feat(release): publish verified source tags
Some checks failed
Dependency Audit / dependency-audit (push) Failing after 14s
Security Audit / security-audit (push) Failing after 12s

This commit is contained in:
2026-07-22 01:17:07 +02:00
parent eca75cbc93
commit 30f9ed152a
12 changed files with 1735 additions and 40 deletions

View File

@@ -19,6 +19,11 @@ from .contracts import collect_contracts
from .git_state import collect_repository_snapshot
from .model import CatalogEntryChange, SelectiveCatalogCandidate
from .module_directory import write_module_directory
from .source_provenance import (
catalog_source_selection,
selected_source_provenance,
source_tag_provenance_issues,
)
from .version_alignment import selected_repository_version_issues
from .workspace import load_repository_specs, resolve_workspace_root, website_root
@@ -35,6 +40,7 @@ def build_selective_catalog_candidate(
signing_keys: tuple[str, ...] = (),
public_base_url: str = DEFAULT_PUBLIC_BASE_URL,
repository_base: str = GITEA_BASE,
source_remote: str = "origin",
expires_days: int = 90,
sequence: int | None = None,
check_public: bool = True,
@@ -48,6 +54,15 @@ def build_selective_catalog_candidate(
workspace = resolve_workspace_root(workspace_root)
enforce_selected_version_alignment(repo_versions=repo_versions, workspace=workspace)
enforce_selected_source_provenance(
repo_versions=repo_versions,
workspace=workspace,
remote=source_remote,
)
selected_provenance = selected_source_provenance(
repo_versions=repo_versions,
workspace=workspace,
)
web_root = website_root(workspace)
source_catalog = resolve_base_catalog(base_catalog=base_catalog, web_root=web_root, channel=channel)
payload = read_catalog(source_catalog)
@@ -66,7 +81,15 @@ def build_selective_catalog_candidate(
release = {}
release["catalog_url"] = f"{public_base_url.rstrip('/')}/catalogs/v1/channels/{channel}.json"
release["keyring_url"] = f"{public_base_url.rstrip('/')}/catalogs/v1/keyring.json"
release["selected_units"] = [{"repo": repo, "version": version, "tag": f"v{version.removeprefix('v')}"} for repo, version in sorted(repo_versions.items())]
release["selected_units"] = [
{
"repo": repo,
"version": version,
"tag": f"v{version.removeprefix('v')}",
**selected_provenance[repo],
}
for repo, version in sorted(repo_versions.items())
]
candidate["release"] = release
repo_contracts = contracts_by_repo(workspace)
@@ -76,6 +99,11 @@ def build_selective_catalog_candidate(
repo_contracts=repo_contracts,
repository_base=repository_base.rstrip("/"),
)
enforce_complete_catalog_source_provenance(
payload=candidate,
workspace=workspace,
remote=source_remote,
)
output_root = resolve_output_dir(output_dir=output_dir, channel=channel, generated_at=generated_at)
catalog_path = output_root / "channels" / f"{channel}.json"
@@ -175,6 +203,50 @@ def enforce_selected_version_alignment(*, repo_versions: dict[str, str], workspa
raise ValueError("Version alignment gate failed: " + "; ".join(failures))
def enforce_selected_source_provenance(
*,
repo_versions: dict[str, str],
workspace: Path,
remote: str = "origin",
) -> None:
failures = source_tag_provenance_issues(
repo_versions=repo_versions,
workspace=workspace,
remote=remote,
require_head_repos=repo_versions,
)
if failures:
raise ValueError(
"Source tag provenance gate failed: "
+ "; ".join(issue.describe() for issue in failures)
)
def enforce_complete_catalog_source_provenance(
*,
payload: object,
workspace: Path,
remote: str = "origin",
) -> None:
selection = catalog_source_selection(payload)
failures = [*selection.issues]
failures.extend(
source_tag_provenance_issues(
repo_versions=selection.all_versions,
workspace=workspace,
remote=remote,
require_head_repos=selection.selected_versions,
expected_commits=selection.selected_commits,
expected_tag_objects=selection.selected_tag_objects,
)
)
if failures:
raise ValueError(
"Complete catalog source provenance gate failed: "
+ "; ".join(issue.describe() for issue in failures)
)
def resolve_base_catalog(*, base_catalog: Path | str | None, web_root: Path, channel: str) -> Path | str:
if base_catalog is not None:
value = str(base_catalog)