Add unit tests for PackRunAttestation and SealedInstallEnforcer
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled
- Implement comprehensive tests for PackRunAttestationService, covering attestation generation, verification, and event emission. - Add tests for SealedInstallEnforcer to validate sealed install requirements and enforcement logic. - Introduce a MonacoLoaderService stub for testing purposes to prevent Monaco workers/styles from loading during Karma runs.
This commit is contained in:
89
ops/devops/release/check_release_manifest.py
Normal file
89
ops/devops/release/check_release_manifest.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Fail-fast validator for release manifests and downloads manifest.
|
||||
Checks presence of required components and expected fields so release pipelines
|
||||
can surface missing artefacts early (instead of blocking deploy tasks later).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
REQUIRED_COMPONENTS = [
|
||||
"orchestrator",
|
||||
"policy-registry",
|
||||
"vex-lens",
|
||||
"issuer-directory",
|
||||
"findings-ledger",
|
||||
"vuln-explorer-api",
|
||||
"packs-registry",
|
||||
"task-runner",
|
||||
"web-ui",
|
||||
]
|
||||
|
||||
|
||||
def load_yaml(path: Path):
|
||||
try:
|
||||
return yaml.safe_load(path.read_text())
|
||||
except Exception as exc:
|
||||
raise SystemExit(f"ERROR: failed to parse {path}: {exc}")
|
||||
|
||||
|
||||
def check_manifest(manifest_path: Path) -> list[str]:
|
||||
data = load_yaml(manifest_path)
|
||||
comps = {c.get("name") for c in data.get("release", {}).get("components", [])}
|
||||
missing = [c for c in REQUIRED_COMPONENTS if c not in comps]
|
||||
return missing
|
||||
|
||||
|
||||
def check_downloads(downloads_path: Path) -> list[str]:
|
||||
missing = []
|
||||
try:
|
||||
data = json.loads(downloads_path.read_text())
|
||||
except Exception as exc:
|
||||
return [f"{downloads_path}: invalid JSON ({exc})"]
|
||||
items = data.get("items", [])
|
||||
if not items:
|
||||
missing.append(f"{downloads_path}: no items found")
|
||||
for idx, item in enumerate(items):
|
||||
for field in ("name", "type"):
|
||||
if field not in item:
|
||||
missing.append(f"{downloads_path}: item {idx} missing '{field}'")
|
||||
if item.get("type") == "container" and "image" not in item:
|
||||
missing.append(f"{downloads_path}: item {idx} missing 'image'")
|
||||
if item.get("type") == "archive" and "sha256" not in item:
|
||||
missing.append(f"{downloads_path}: item {idx} missing 'sha256'")
|
||||
return missing
|
||||
|
||||
|
||||
def main():
|
||||
manifest = Path("deploy/releases/2025.09-stable.yaml")
|
||||
airgap = Path("deploy/releases/2025.09-airgap.yaml")
|
||||
downloads = Path("deploy/downloads/manifest.json")
|
||||
|
||||
errors: list[str] = []
|
||||
for path in (manifest, airgap):
|
||||
if not path.exists():
|
||||
errors.append(f"{path}: file missing")
|
||||
continue
|
||||
missing = check_manifest(path)
|
||||
if missing:
|
||||
errors.append(f"{path}: missing components -> {', '.join(missing)}")
|
||||
if downloads.exists():
|
||||
errors.extend(check_downloads(downloads))
|
||||
else:
|
||||
errors.append(f"{downloads}: file missing")
|
||||
|
||||
if errors:
|
||||
print("FAIL\n" + "\n".join(f"- {e}" for e in errors))
|
||||
sys.exit(1)
|
||||
|
||||
print("OK: required components present and downloads manifest is well-formed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user