Harden source release preparation and record verified security follow-up
Dependency Audit / dependency-audit (push) Successful in 1m51s
Deployment Installer / deployment-installer (push) Successful in 8s
Security Audit / security-audit (push) Successful in 12m32s

This commit is contained in:
2026-09-08 08:04:12 +02:00
parent 9554657bb5
commit 58d320d9b3
26 changed files with 3833 additions and 163 deletions
@@ -6,12 +6,13 @@ from dataclasses import dataclass
import json
from pathlib import Path
import re
import runpy
import subprocess
import tomllib
from .git_state import collect_versions, sanitized_git_environment
from .git_state import collect_versions, registered_developer_meta_path, sanitized_git_environment
from .registry_reference import registry_artifact_conflicts, registry_entry_source
from .workspace import load_repository_specs, resolve_repo_path
from .workspace import META_ROOT, load_repository_specs, resolve_repo_path
_PYTHON_RELEASE_REF = re.compile(
@@ -43,6 +44,7 @@ def repository_version_issues(
versions = collect_versions(repo_path)
declared = {
"pyproject.toml": versions.pyproject,
"packages/govoplan-meta/pyproject.toml": versions.developer_meta,
"package.json": versions.package,
"webui/package.json": versions.webui_package,
"webui/package.release.json": _json_version(repo_path / "webui" / "package.release.json")
@@ -83,6 +85,8 @@ def repository_version_issues(
for source, version in declared.items()
if version is not None and version != canonical_version
]
if registered_developer_meta_path(repo_path) is not None:
issues.extend(developer_meta_composition_issues(repo_path))
if expected_version is not None and canonical_version.removeprefix("v") != expected_version.removeprefix("v"):
issues.append(
@@ -120,6 +124,34 @@ def repository_version_issues(
return tuple(issues)
def developer_meta_composition_issues(repo_path: Path) -> tuple[VersionAlignmentIssue, ...]:
"""Compare the real nested package with the trusted generator's exact output.
Never execute a generator from a selected checkout. Only the installed
operator tooling provides code; selected TOML/requirements are data inputs.
"""
package_path = registered_developer_meta_path(repo_path)
if package_path is None:
return (VersionAlignmentIssue(repo_path.name, "repository", "registered Meta support repository", "", "nested developer-package identity is not registered"),)
source = "packages/govoplan-meta/pyproject.toml"
try:
current = package_path.read_text(encoding="utf-8")
project = tomllib.loads(current).get("project")
if not isinstance(project, dict) or project.get("name") != "govoplan":
return (VersionAlignmentIssue("govoplan", source + ":project.name", "govoplan", str(project.get("name") if isinstance(project, dict) else ""), "developer meta-package identity must be exact"),)
# META_ROOT belongs to the running operator tools, not repo_path.
generator = runpy.run_path(str(META_ROOT / "tools/release/generate-developer-meta-package.py"))
expected = generator["render"](
workspace=repo_path.parent,
requirements=repo_path / "requirements-release.txt",
)
except (OSError, UnicodeError, KeyError, ValueError, TypeError) as exc:
return (VersionAlignmentIssue("govoplan", source, "readable exact developer composition and Core version", type(exc).__name__, "developer meta-package composition could not be validated"),)
if current != expected:
return (VersionAlignmentIssue("govoplan", source, "trusted generator output matching Core and release requirements", "stale composition", "developer meta-package must exactly match the generator --check contract"),)
return ()
def selected_repository_version_issues(
*,
repo_versions: dict[str, str],
@@ -165,6 +197,11 @@ def selected_repository_version_issues(
return tuple(issues)
def selected_webui_repository_names(*, repo_versions: dict[str, str], workspace: Path) -> tuple[str, ...]:
"""Identify the exact selections for which Core's WebUI inputs are relevant."""
return tuple(repo for repo in sorted(repo_versions) if repo != "govoplan-core" and (workspace / repo / "webui/package.json").exists())
def selected_release_webui_bundle_issues(
*,
repo_versions: dict[str, str],
@@ -177,6 +214,8 @@ def selected_release_webui_bundle_issues(
immutable release package input and lockfile will actually install.
"""
if not selected_webui_repository_names(repo_versions=repo_versions, workspace=workspace):
return ()
core_webui = workspace / "govoplan-core" / "webui"
release_package_path = core_webui / "package.release.json"
release_lock_path = core_webui / "package-lock.release.json"