fix(release): harden review gate diagnostics
This commit is contained in:
@@ -16,11 +16,14 @@ import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
from typing import Any, Iterable
|
||||
from unittest import mock
|
||||
|
||||
from jsonschema import Draft202012Validator, FormatChecker
|
||||
from jsonschema.exceptions import SchemaError
|
||||
|
||||
from govoplan_core.core.module_package_catalog import validate_module_package_catalog
|
||||
import govoplan_core.core.module_package_catalog as module_package_catalog
|
||||
from govoplan_release.source_provenance import catalog_source_selection
|
||||
from govoplan_release.version_alignment import candidate_catalog_version_issues
|
||||
|
||||
|
||||
RELEASE_REF_PATTERN = re.compile(
|
||||
@@ -74,6 +77,28 @@ def review_capability_fit(
|
||||
("assessment.release",),
|
||||
)
|
||||
)
|
||||
findings.extend(
|
||||
Finding(
|
||||
"blocker",
|
||||
"catalog_release_metadata",
|
||||
(
|
||||
f"{issue.source}: {issue.message}; expected {issue.expected!r}, "
|
||||
f"found {issue.actual!r}."
|
||||
),
|
||||
("assessment.release",),
|
||||
)
|
||||
for issue in candidate_catalog_version_issues(catalog)
|
||||
)
|
||||
source_selection = catalog_source_selection(catalog)
|
||||
findings.extend(
|
||||
Finding(
|
||||
"blocker",
|
||||
"catalog_source_provenance",
|
||||
issue.message,
|
||||
("assessment.release",),
|
||||
)
|
||||
for issue in source_selection.issues
|
||||
)
|
||||
expected_keyring_hash = _catalog_keyring_hash(catalog)
|
||||
actual_keyring_hash = canonical_hash(keyring)
|
||||
if expected_keyring_hash is None:
|
||||
@@ -208,6 +233,37 @@ def review_capability_fit(
|
||||
)
|
||||
)
|
||||
|
||||
selected_version = source_selection.selected_versions.get(repository)
|
||||
selected_commit = source_selection.selected_commits.get(repository)
|
||||
assessed_commit = str(module["commit"]).lower()
|
||||
if (
|
||||
selected_version == assessed_version
|
||||
and selected_commit is not None
|
||||
and not selected_commit.lower().startswith(assessed_commit)
|
||||
):
|
||||
changes.append(
|
||||
{
|
||||
"module_id": module_id,
|
||||
"repository": repository,
|
||||
"kind": "commit_changed",
|
||||
"assessed_commit": module["commit"],
|
||||
"catalog_commit": selected_commit,
|
||||
}
|
||||
)
|
||||
changed_repositories.add(repository)
|
||||
findings.append(
|
||||
Finding(
|
||||
"review",
|
||||
"composition_commit_changed",
|
||||
(
|
||||
f"Signed selected-unit provenance for {repository!r} at "
|
||||
f"{assessed_version!r} points to commit {selected_commit[:12]}, "
|
||||
f"not assessed commit {module['commit']}."
|
||||
),
|
||||
(f"composition.{module_id}",),
|
||||
)
|
||||
)
|
||||
|
||||
expected_tag = f"v{catalog_version}" if catalog_version else None
|
||||
catalog_tags = entry["tags"]
|
||||
if (
|
||||
@@ -310,12 +366,27 @@ def validate_catalog(
|
||||
) as handle:
|
||||
json.dump(catalog, handle)
|
||||
handle.flush()
|
||||
return validate_module_package_catalog(
|
||||
Path(handle.name),
|
||||
require_trusted=True,
|
||||
approved_channels=(channel,) if channel else (),
|
||||
trusted_keys=trusted_keys,
|
||||
)
|
||||
# Installer replay state answers whether a catalog may be accepted again
|
||||
# by one runtime. This read-only assessment instead compares explicit
|
||||
# inputs, so ambient installer state must not affect its result.
|
||||
with (
|
||||
mock.patch.object(
|
||||
module_package_catalog,
|
||||
"_configured_sequence_state_path",
|
||||
return_value=None,
|
||||
),
|
||||
mock.patch.object(
|
||||
module_package_catalog,
|
||||
"_configured_enforce_sequence",
|
||||
return_value=False,
|
||||
),
|
||||
):
|
||||
return module_package_catalog.validate_module_package_catalog(
|
||||
Path(handle.name),
|
||||
require_trusted=True,
|
||||
approved_channels=(channel,) if channel else (),
|
||||
trusted_keys=trusted_keys,
|
||||
)
|
||||
|
||||
|
||||
def trusted_keys_from_keyring(payload: dict[str, Any]) -> dict[str, str]:
|
||||
|
||||
Reference in New Issue
Block a user