Automate policy source freshness and inventory
Some checks failed
Build and publish policy-nexus image / build-and-push (push) Failing after 2s
Some checks failed
Build and publish policy-nexus image / build-and-push (push) Failing after 2s
This commit is contained in:
parent
78d096bdd5
commit
03a4fab9e0
17 changed files with 1647 additions and 42 deletions
|
|
@ -46,8 +46,11 @@ def verify(build: Path) -> dict[str, Any]:
|
|||
|
||||
index = build / "index.html"
|
||||
manifest_path = build / "publication-manifest.json"
|
||||
if not index.is_file() or not manifest_path.is_file():
|
||||
raise ValueError("release requires index.html and publication-manifest.json")
|
||||
inventory_path = build / "source-inventory.json"
|
||||
if not index.is_file() or not manifest_path.is_file() or not inventory_path.is_file():
|
||||
raise ValueError(
|
||||
"release requires index.html, publication-manifest.json and source-inventory.json"
|
||||
)
|
||||
|
||||
manifest_bytes = manifest_path.read_bytes()
|
||||
manifest = json.loads(manifest_bytes)
|
||||
|
|
@ -59,6 +62,19 @@ def verify(build: Path) -> dict[str, Any]:
|
|||
if not isinstance(documents, list) or not documents:
|
||||
raise ValueError("publication manifest must contain at least one document")
|
||||
|
||||
inventory_bytes = inventory_path.read_bytes()
|
||||
inventory = json.loads(inventory_bytes)
|
||||
if inventory.get("schema_version") != "policy-nexus-source-inventory/v1":
|
||||
raise ValueError("source inventory schema_version is invalid")
|
||||
source_set_digest = inventory.get("source_set_digest", "")
|
||||
if not HEX_DIGEST.fullmatch(source_set_digest):
|
||||
raise ValueError("source inventory requires a valid source_set_digest")
|
||||
inventoried_published = {
|
||||
(source.get("source_repo"), source.get("source_path"))
|
||||
for source in inventory.get("sources", [])
|
||||
if source.get("disposition") == "published"
|
||||
}
|
||||
|
||||
verified: list[str] = []
|
||||
for document in documents:
|
||||
document_id = document.get("id", "<unknown>")
|
||||
|
|
@ -72,6 +88,8 @@ def verify(build: Path) -> dict[str, Any]:
|
|||
"review_due",
|
||||
"canonical_path",
|
||||
"revision_path",
|
||||
"source_repo",
|
||||
"source_path",
|
||||
):
|
||||
if not document.get(field) or document.get(field) == "unknown":
|
||||
raise ValueError(f"{document_id}: release metadata field {field} is required")
|
||||
|
|
@ -84,6 +102,9 @@ def verify(build: Path) -> dict[str, Any]:
|
|||
)
|
||||
if not HEX_DIGEST.fullmatch(source_digest):
|
||||
raise ValueError(f"{document_id}: invalid source_digest {source_digest!r}")
|
||||
source_key = (document["source_repo"], document["source_path"])
|
||||
if source_key not in inventoried_published:
|
||||
raise ValueError(f"{document_id}: source is not published in source inventory")
|
||||
|
||||
canonical = build / _safe_relative(document["canonical_path"])
|
||||
revision = build / _safe_relative(document["revision_path"])
|
||||
|
|
@ -105,6 +126,8 @@ def verify(build: Path) -> dict[str, Any]:
|
|||
return {
|
||||
"schema_version": "policy-nexus-release/v1",
|
||||
"publication_manifest_digest": hashlib.sha256(manifest_bytes).hexdigest(),
|
||||
"source_inventory_digest": hashlib.sha256(inventory_bytes).hexdigest(),
|
||||
"source_set_digest": source_set_digest,
|
||||
"generated_as_of": manifest["generated_as_of"],
|
||||
"documents": verified,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue