Align all release version declarations
Dependency Audit / dependency-audit (push) Failing after 1m44s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 10m42s

This commit is contained in:
2026-08-04 15:06:36 +02:00
parent 8e890b37ed
commit 492449a4e2
3 changed files with 60 additions and 10 deletions
+5
View File
@@ -66,6 +66,11 @@ tags. The default preflight intentionally does not require those heads to exist
in the previous release baseline. A failed candidate-baseline check therefore in the previous release baseline. A failed candidate-baseline check therefore
cannot produce a protected package release. cannot produce a protected package release.
The source gate validates `pyproject.toml`, module `MODULE_VERSION`, public
package `__version__`, and WebUI metadata before creating tags. Release-tag
artifact checks run only after the candidate tags and immutable WebUI lock have
been created locally.
It builds one wheel and, where applicable, one npm tarball. The workflow records It builds one wheel and, where applicable, one npm tarball. The workflow records
the source tag, source commit, filename, size, and SHA-256 in the source tag, source commit, filename, size, and SHA-256 in
`package-artifacts.json` before publishing. Gitea rejects a second upload of the `package-artifacts.json` before publishing. Gitea rejects a second upload of the
+17
View File
@@ -61,6 +61,23 @@ class ReleaseEntrypointGateTests(unittest.TestCase):
self.assertNotIn("--strict-if-baseline", audit_function) self.assertNotIn("--strict-if-baseline", audit_function)
self.assertIn('command+=("--strict")', audit_function) self.assertIn('command+=("--strict")', audit_function)
def test_source_gate_does_not_require_tags_before_they_are_created(self) -> None:
script = (META_ROOT / "tools" / "release" / "push-release-tag.sh").read_text()
gate = script[
script.index("run_version_alignment_gate()") :
script.index("run_manifest_shape_gate()")
]
self.assertIn('command+=(--source-metadata-only)', gate)
self.assertIn('else\n command+=(--release-composition)', gate)
def test_version_updater_targets_canonical_runtime_declarations(self) -> None:
script = (META_ROOT / "tools" / "release" / "push-release-tag.sh").read_text()
self.assertIn("could not update MODULE_VERSION", script)
self.assertIn("update_package_init_versions", script)
self.assertNotIn("could not update ModuleManifest.version", script)
def test_source_catalog_generator_enforces_explicit_repo_versions(self) -> None: def test_source_catalog_generator_enforces_explicit_repo_versions(self) -> None:
script = (META_ROOT / "tools" / "release" / "generate-release-catalog.py").read_text() script = (META_ROOT / "tools" / "release" / "generate-release-catalog.py").read_text()
+38 -10
View File
@@ -333,20 +333,46 @@ path = pathlib.Path(sys.argv[1])
new_version = sys.argv[2] new_version = sys.argv[2]
text = path.read_text() text = path.read_text()
text, count = re.subn( text, count = re.subn(
r'(?m)^(\s*version=)["\'][^"\']+["\'](,?\s*)$', r'(?m)^(MODULE_VERSION\s*=\s*)["\'][^"\']+["\'](\s*)$',
rf'\1"{new_version}"\2', rf'\1"{new_version}"\2',
text, text,
count=1, count=1,
) )
if count == 0:
text, count = re.subn(
r'(?m)^(MODULE_VERSION\s*=\s*)["\'][^"\']+["\'](\s*)$',
rf'\1"{new_version}"\2',
text,
count=1,
)
if count != 1: if count != 1:
raise SystemExit(f"could not update ModuleManifest.version in {path}") raise SystemExit(f"could not update MODULE_VERSION in {path}")
path.write_text(text)
PYCODE
done
}
update_package_init_versions() {
local repo="$1"
local version="$2"
local package_init=""
for package_init in "$repo"/src/*/__init__.py; do
[[ -f "$package_init" ]] || continue
if ! grep -q '^__version__\s*=' "$package_init"; then
continue
fi
"$PYTHON" - "$package_init" "$version" <<'PYCODE'
from __future__ import annotations
import pathlib
import re
import sys
path = pathlib.Path(sys.argv[1])
new_version = sys.argv[2]
text = path.read_text()
text, count = re.subn(
r'(?m)^(__version__\s*=\s*)["\'][^"\']+["\'](\s*)$',
rf'\1"{new_version}"\2',
text,
count=1,
)
if count != 1:
raise SystemExit(f"could not update __version__ in {path}")
path.write_text(text) path.write_text(text)
PYCODE PYCODE
done done
@@ -470,6 +496,7 @@ update_version_files() {
update_pyproject "$repo" "$version" update_pyproject "$repo" "$version"
update_manifest_version "$repo" "$project_name" "$version" update_manifest_version "$repo" "$project_name" "$version"
update_package_init_versions "$repo" "$version"
update_webui_package "$repo" "$project_name" "$version" update_webui_package "$repo" "$project_name" "$version"
} }
@@ -500,10 +527,11 @@ run_version_alignment_gate() {
"$PYTHON" "$PYTHON"
"$META_ROOT/tools/checks/check-version-alignment.py" "$META_ROOT/tools/checks/check-version-alignment.py"
--workspace-root "$PARENT" --workspace-root "$PARENT"
--release-composition
) )
if [[ "$mode" == "source" ]]; then if [[ "$mode" == "source" ]]; then
command+=(--source-metadata-only) command+=(--source-metadata-only)
else
command+=(--release-composition)
fi fi
local repo local repo
for repo in "${PACKAGE_REPOS[@]}"; do for repo in "${PACKAGE_REPOS[@]}"; do