[SCM] PostGIS branch master updated. 3.7.0beta1-251-gfe534c85f4
git at osgeo.org
git at osgeo.org
Sun Aug 9 02:53:24 PDT 2026
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".
The branch, master has been updated
via fe534c85f4b5e8089fbd3a03767f4e16f51c8a59 (commit)
via 287f5e084a98ea5346b3e60d8bbe0560ccc22826 (commit)
from 780515fbe4f1aab7e95cd1d261b8b0cfde423419 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit fe534c85f4b5e8089fbd3a03767f4e16f51c8a59
Merge: 780515fbe4 287f5e084a
Author: Darafei Praliaskouski <komzpa at gmail.com>
Date: Sun Aug 9 02:53:11 2026 -0700
Merge pull request 'Accept NEWS placeholders and attribution companies' (!672) from Komzpa/postgis:codex/news-x-placeholder-validator into master
Update the NEWS validation helpers so release preparation placeholders and company affiliations are handled by maintained data instead of one-off parser exceptions.
This includes:
- treating dates such as `2026/08/0x` as unreleased placeholders in `utils/docs/check_news.sh`
- testing that a NEWS entry can be added while the target release still uses an `x` placeholder date
- reading non-person NEWS attribution names from the `Corporate Sponsors` section of `doc/credits.xml`
- rejecting organization-looking NEWS attributions unless the organization is registered in `doc/credits.xml`
- adding the corporate sponsor entries needed by current unreleased NEWS attributions
- documenting the `Name, Organization` attribution convention in `doc/development/`
This is split out from `GT-671` so the security hardening PR can stay focused on the backpatchable code change. Merge this tooling PR first, then re-check `GT-671` on top of it.
Reviewed-on: https://gitea.osgeo.org/postgis/postgis/pulls/672
commit 287f5e084a98ea5346b3e60d8bbe0560ccc22826
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Sun Aug 9 12:40:48 2026 +0400
Allow x placeholders in NEWS dates
diff --git a/doc/credits.xml b/doc/credits.xml
index cdb0e7be25..b5ca5bbf2e 100644
--- a/doc/credits.xml
+++ b/doc/credits.xml
@@ -481,15 +481,17 @@
<listitem><simpara><link xlink:href="http://www.elecnor-deimos.com">Deimos Space</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.faunalia.eu">Faunalia</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://gov.bc.ca">Geographic Data BC</link></simpara></listitem>
+ <listitem><simpara><link xlink:href="https://www.google.com">Google</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.highgo.com">HighGo</link></simpara></listitem>
<listitem><simpara>Hunter Systems Group</simpara></listitem>
<listitem><simpara><link xlink:href="https://pti-agriambio.csic.es">INIA-CSIC</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.isciences.com">ISciences, LLC</link></simpara></listitem>
+ <listitem><simpara><link xlink:href="https://www.jirotech.com">Jirotech (formerly LISAsoft)</link></simpara></listitem>
+ <listitem><simpara><link xlink:href="https://koordinates.com">Koordinates</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.kontur.io">Kontur</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.lidwala.com">Lidwala Consulting Engineers</link></simpara></listitem>
- <listitem><simpara><link xlink:href="https://www.jirotech.com">LISAsoft</link></simpara></listitem>
- <listitem><simpara>Logical Tracking & Tracing International AG</simpara></listitem>
- <listitem><simpara>Maponics</simpara></listitem>
+ <listitem><simpara><link xlink:href="http://www.logicaltracking.com">Logical Tracking & Tracing International AG</link></simpara></listitem>
+ <listitem><simpara><link xlink:href="https://www.maponics.com/">Maponics</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://maumap.com/">Maumap</link></simpara></listitem>
<listitem><simpara><link xlink:href="http://www.mtri.org">Michigan Tech Research Institute</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.nrcan.gc.ca">Natural Resources Canada</link></simpara></listitem>
@@ -499,12 +501,13 @@
<listitem><simpara><link xlink:href="https://oslandia.com">Oslandia</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.palantir.com">Palantir Technologies</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.paragoncorporation.com">Paragon Corporation</link></simpara></listitem>
+ <listitem><simpara><link xlink:href="https://planetscale.com">PlanetScale</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://postgrespro.com">Postgres Pro</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.r3-gis.com">R3 GIS</link></simpara></listitem>
<listitem><simpara><link xlink:href="http://www.refractions.net">Refractions Research</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.regione.toscana.it">Regione Toscana - SITA</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.safe.com">Safe Software</link></simpara></listitem>
- <listitem><simpara>Sirius Corporation plc</simpara></listitem>
+ <listitem><simpara><link xlink:href="https://www.siriusopensource.com/en-us">Sirius Corporation plc</link></simpara></listitem>
<listitem><simpara><link xlink:href="http://www.uster.ch">Stadt Uster</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.ucdavis.edu">UC Davis Center for Vectorborne Diseases</link></simpara></listitem>
<listitem><simpara><link xlink:href="https://www.ulaval.ca">Université Laval</link></simpara></listitem>
diff --git a/doc/development/maintenance/_index.md b/doc/development/maintenance/_index.md
index a61e12c679..312010bb3f 100644
--- a/doc/development/maintenance/_index.md
+++ b/doc/development/maintenance/_index.md
@@ -128,10 +128,11 @@ missing person, either add that person's canonical display name to
Keep `.mailmap` canonical names to person names only. In `NEWS` attribution
parentheses, comma-separated affiliations such as `Name, Organization` are
-allowed when the organization is recognized by the checker. If the checker
-reports the organization as a missing contributor, teach the checker that the
-organization is not a person instead of adding the organization to
-`doc/credits.xml`.
+allowed when the organization is listed under the `Corporate Sponsors` section
+of `doc/credits.xml`. If the checker reports the organization as a missing
+contributor, add the organization to that corporate list rather than adding it
+to the individual contributor list. Human reporters and patch authors still
+belong in the individual contributor credits.
## Commit Messages
diff --git a/doc/development/testing/_index.md b/doc/development/testing/_index.md
index 105e89e37a..72354c41c9 100644
--- a/doc/development/testing/_index.md
+++ b/doc/development/testing/_index.md
@@ -156,10 +156,12 @@ Other useful targets:
keep all handle-first entries together at the start of the list. Keep
`.mailmap` canonical names to person names only. In `NEWS` attribution
parentheses, comma-separated affiliations such as `Name, Organization` are
- allowed when the organization is recognized by the checker. If the checker
- reports the organization as a missing contributor, teach the checker that the
- organization is not a person instead of adding the organization to
- `doc/credits.xml`. Do not infer a person's name from an email address.
+ allowed when the organization is listed under the `Corporate Sponsors`
+ section of `doc/credits.xml`. If the checker reports the organization as a
+ missing contributor, add the organization to that corporate list rather than
+ adding it to the individual contributor list. Human reporters and patch
+ authors still belong in the individual contributor credits. Do not infer a
+ person's name from an email address.
* [CI inventory standards](ci.md) describe how to keep build-bot and badge
inventories checkable instead of copying stale dashboard markup into
maintained prose.
diff --git a/utils/docs/check_contributor_credits.py b/utils/docs/check_contributor_credits.py
index 0fe6061e36..59b34ec895 100644
--- a/utils/docs/check_contributor_credits.py
+++ b/utils/docs/check_contributor_credits.py
@@ -41,8 +41,8 @@ NON_HUMAN_NAMES = {
("claude", "fable", "5"),
}
NON_PERSON_NEWS_RE = re.compile(
- r"\b(?:bureau|city|company|corporation|foundation|highgo|inc\.?|"
- r"google|koordinates|llc|osgeo|team|university)\b",
+ r"\b(?:bureau|city|company|corporation|foundation|inc\.?|llc|team|"
+ r"university)\b",
re.I,
)
TECHNICAL_NEWS_RE = re.compile(
@@ -116,6 +116,40 @@ def credit_keys(name):
return {key for key in keys if key}
+def node_text(node):
+ return " ".join("".join(node.itertext()).split())
+
+
+def news_non_person_attribution_names(credits_path):
+ credits_path = Path(credits_path)
+ if not credits_path.exists():
+ return set()
+
+ try:
+ root = ET.parse(credits_path).getroot()
+ except ET.ParseError as exc:
+ raise CreditValidationError(f"cannot parse {credits_path}: {exc}") from exc
+
+ names = set()
+ for entry in root.findall(".//db:varlistentry", DOCBOOK):
+ term = entry.find("db:term", DOCBOOK)
+ if term is None or node_text(term) != "Corporate Sponsors":
+ continue
+ for simpara in entry.findall(".//db:simpara", DOCBOOK):
+ text = node_text(simpara)
+ suffix_match = re.search(
+ r"\s*\((?:formerly|now)\s+([^()]*)\)\s*$", text, re.I
+ )
+ candidate_names = [text, re.sub(r"\s*\([^()]*\)\s*$", "", text).strip()]
+ if suffix_match:
+ candidate_names.append(suffix_match.group(1).strip())
+ for name in candidate_names:
+ key = normalized_name(name)
+ if key:
+ names.add(key)
+ return names
+
+
def person_is_credited(name, credits):
return normalized_name(name) in credits
@@ -256,16 +290,37 @@ def unreleased_news_lines(news_path):
return lines
-def split_news_people(value):
+def split_news_people(value, non_person_names=None):
+ if non_person_names is None:
+ default_credits = Path(__file__).resolve().parents[2] / "doc" / "credits.xml"
+ non_person_names = news_non_person_attribution_names(default_credits)
people = []
for candidate in NEWS_PERSON_SEPARATOR_RE.split(value):
- candidate = re.sub(r"\s+(?:from|of)\s+.*$", "", candidate, flags=re.I).strip()
- if (
- not candidate
- or NON_PERSON_NEWS_RE.search(candidate)
- or TECHNICAL_NEWS_RE.search(candidate)
- ):
+ candidate = re.sub(
+ r"^\s*(?:reported|fixed|patched|implemented)\s+by\s+",
+ "",
+ candidate,
+ flags=re.I,
+ ).strip()
+ if not candidate or normalized_name(candidate) in non_person_names:
continue
+ if TECHNICAL_NEWS_RE.search(candidate):
+ continue
+ if NON_PERSON_NEWS_RE.search(candidate):
+ raise CreditValidationError(
+ f"NEWS attribution {candidate!r} looks like an organization; "
+ "add it to the Corporate Sponsors section in doc/credits.xml"
+ )
+ candidate = re.sub(r"\s+(?:from|of)\s+.*$", "", candidate, flags=re.I).strip()
+ if not candidate or normalized_name(candidate) in non_person_names:
+ continue
+ if TECHNICAL_NEWS_RE.search(candidate):
+ continue
+ if NON_PERSON_NEWS_RE.search(candidate):
+ raise CreditValidationError(
+ f"NEWS attribution {candidate!r} looks like an organization; "
+ "add it to the Corporate Sponsors section in doc/credits.xml"
+ )
if normalized_name(candidate) and re.search(
r"[^\W\d_]", candidate, re.UNICODE
):
@@ -274,6 +329,10 @@ def split_news_people(value):
def news_contributors(news_path):
+ news_path = Path(news_path)
+ non_person_names = news_non_person_attribution_names(
+ news_path.parent / "doc" / "credits.xml"
+ )
lines = unreleased_news_lines(news_path)
contributors = []
current = []
@@ -286,7 +345,8 @@ def news_contributors(news_path):
match = NEWS_ATTRIBUTION_RE.search(text)
if match:
contributors.extend(
- (name, current_line) for name in split_news_people(match.group(1))
+ (name, current_line)
+ for name in split_news_people(match.group(1), non_person_names)
)
current = []
current_line = None
@@ -305,7 +365,8 @@ def news_contributors(news_path):
match = NEWS_TEAM_RE.match(line)
if match:
contributors.extend(
- (name, line_number) for name in split_news_people(match.group(1))
+ (name, line_number)
+ for name in split_news_people(match.group(1), non_person_names)
)
finish_entry()
return contributors
diff --git a/utils/docs/check_news.sh b/utils/docs/check_news.sh
index b0ebaf0fde..1606a62d93 100755
--- a/utils/docs/check_news.sh
+++ b/utils/docs/check_news.sh
@@ -98,7 +98,8 @@ if test -n "${NEWS_BASE_REF}"; then
if ! awk '
function is_unreleased(date) {
- return date ~ /^[0-9][0-9][0-9][0-9]\/xx\/xx$/
+ return date ~ /^[0-9][0-9][0-9][0-9]\/([0-9x][0-9x])\/([0-9x][0-9x])$/ &&
+ date ~ /x/
}
function section_accepts_new_entries() {
target_section_is_open = release == target_first &&
@@ -133,7 +134,7 @@ if test -n "${NEWS_BASE_REF}"; then
next
}
release != "" && release_date == "" &&
- /^[0-9][0-9][0-9][0-9]\/([0-9][0-9]|xx)\/([0-9][0-9]|xx)$/ {
+ /^[0-9][0-9][0-9][0-9]\/([0-9][0-9]|[0-9x][0-9x])\/([0-9][0-9]|[0-9x][0-9x])$/ {
release_date = $0
next
}
diff --git a/utils/docs/tests/test_check_contributor_credits.py b/utils/docs/tests/test_check_contributor_credits.py
index 07dc26010c..6b75f65f2a 100644
--- a/utils/docs/tests/test_check_contributor_credits.py
+++ b/utils/docs/tests/test_check_contributor_credits.py
@@ -13,6 +13,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from check_contributor_credits import (
CreditValidationError,
+ news_non_person_attribution_names,
normalized_name,
split_news_people,
validate,
@@ -280,6 +281,15 @@ class ContributorCreditValidationTest(unittest.TestCase):
self.assertEqual(0, result.git_coauthors)
def test_news_slashes_separate_people_from_people_and_affiliations(self):
+ corporate_sponsors = news_non_person_attribution_names(
+ Path(__file__).resolve().parents[3] / "doc" / "credits.xml"
+ )
+ self.assertIn(
+ normalized_name("PlanetScale"),
+ corporate_sponsors,
+ )
+ self.assertIn(normalized_name("Jirotech"), corporate_sponsors)
+ self.assertIn(normalized_name("LISAsoft"), corporate_sponsors)
self.assertEqual(
["Regina Obe", "Sandro Santilli"],
split_news_people("Regina Obe / Sandro Santilli"),
@@ -300,6 +310,26 @@ class ContributorCreditValidationTest(unittest.TestCase):
["Jan Katins", "Regina Obe"],
split_news_people("Jan Katins of Aiven, Regina Obe"),
)
+ self.assertEqual(
+ ["Eric Ridge", "Darafei Praliaskouski"],
+ split_news_people(
+ "reported by Eric Ridge, PlanetScale; "
+ "fixed by Darafei Praliaskouski"
+ ),
+ )
+
+ def test_news_organization_attribution_must_be_registered(self):
+ self.fixture.initial_commit(
+ "Alice Example",
+ "Bob News",
+ news_credit="Alice Example, Example Company",
+ )
+
+ with self.assertRaisesRegex(
+ CreditValidationError,
+ "Example Company.*Corporate Sponsors",
+ ):
+ validate(self.fixture.repo)
def test_released_news_parentheses_are_not_attributions(self):
self.fixture.initial_commit("Alice Example", "Bob News")
diff --git a/utils/docs/tests/test_check_news.py b/utils/docs/tests/test_check_news.py
index c171c93c47..f38984c6a7 100644
--- a/utils/docs/tests/test_check_news.py
+++ b/utils/docs/tests/test_check_news.py
@@ -115,6 +115,22 @@ class NewsValidationTest(unittest.TestCase):
result = self.fixture.check_news(self.fixture.base_commit)
self.assertEqual(0, result.returncode, result.stdout + result.stderr)
+ def test_x_placeholder_date_section_accepts_new_entries(self):
+ base_news = BASE_NEWS.replace("2026/xx/xx", "2026/08/0x")
+ self.fixture.write_news(base_news)
+ self.fixture.git("add", "NEWS")
+ self.fixture.git("commit", "-m", "x placeholder NEWS")
+ target_commit = self.fixture.git("rev-parse", "HEAD").stdout.strip()
+ self.fixture.write_news(
+ base_news.replace(
+ " - Existing unreleased fix",
+ " - New unreleased fix\n - Existing unreleased fix",
+ )
+ )
+
+ result = self.fixture.check_news(target_commit)
+ self.assertEqual(0, result.returncode, result.stdout + result.stderr)
+
def test_new_entry_in_released_section_fails(self):
self.fixture.write_news(
BASE_NEWS.replace(
-----------------------------------------------------------------------
Summary of changes:
doc/credits.xml | 11 +--
doc/development/maintenance/_index.md | 9 +--
doc/development/testing/_index.md | 10 +--
utils/docs/check_contributor_credits.py | 81 +++++++++++++++++++---
utils/docs/check_news.sh | 5 +-
utils/docs/tests/test_check_contributor_credits.py | 30 ++++++++
utils/docs/tests/test_check_news.py | 16 +++++
7 files changed, 138 insertions(+), 24 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list