from pathlib import Path import yaml from ops import gcp_leoclean_nosend_package as package WORKFLOW = Path(".github/workflows/gcp-leoclean-nosend-release.yml") def load_workflow() -> dict[str, object]: return yaml.load(WORKFLOW.read_text(encoding="utf-8"), Loader=yaml.BaseLoader) def workflow_step(name: str) -> dict[str, object]: workflow = load_workflow() jobs = workflow["jobs"] assert isinstance(jobs, dict) publish = jobs["publish"] assert isinstance(publish, dict) steps = publish["steps"] assert isinstance(steps, list) return next(step for step in steps if step.get("name") == name) def test_release_workflow_is_manual_main_only_and_serialized() -> None: workflow = load_workflow() assert set(workflow["on"]) == {"workflow_dispatch"} assert workflow["permissions"] == {"contents": "read", "id-token": "write"} assert workflow["concurrency"] == { "group": "gcp-leoclean-nosend-release-main", "cancel-in-progress": "false", } guard = workflow_step("Require manual main dispatch")["run"] assert 'test "${GITHUB_EVENT_NAME}" = "workflow_dispatch"' in guard assert 'test "${GITHUB_REF}" = "refs/heads/main"' in guard assert 'test "${GITHUB_REF_TYPE}" = "branch"' in guard assert 'test "${GITHUB_REPOSITORY}" = "living-ip/teleo-infrastructure"' in guard assert '"living-ip/teleo-infrastructure/.github/workflows/gcp-leoclean-nosend-release.yml@refs/heads/main"' in guard def test_release_workflow_checks_out_exact_clean_revision_without_persisted_token() -> None: step = workflow_step("Check out exact dispatched revision") assert step["uses"] == "actions/checkout@11d5960a326750d5838078e36cf38b85af677262" assert step["with"] == { "fetch-depth": "0", "persist-credentials": "false", "ref": "${{ github.sha }}", } revision_check = workflow_step("Verify exact clean main revision")["run"] assert 'test "$(git rev-parse --verify HEAD)" = "${GITHUB_SHA}"' in revision_check assert 'test "$(git rev-parse --verify refs/remotes/origin/main^{commit})" = "${GITHUB_SHA}"' in revision_check assert "git status --porcelain=v1 --untracked-files=all" in revision_check def test_release_workflow_smokes_before_requesting_cloud_identity() -> None: workflow = WORKFLOW.read_text(encoding="utf-8") smoke = workflow.index("Smoke exact no-send OCI surface") prepare = workflow.index("Prepare exact candidate context") initialize = workflow.index("Initialize pre-mutation publish outcome") auth = workflow.index("Authenticate to Google Cloud through WIF") push = workflow.index("Build and push one immutable candidate") finalize = workflow.index("Finalize and validate release v3 bundle") cleanup = workflow.index("Remove ephemeral Docker authentication") complete = workflow.index("Finalize publish outcome") upload = workflow.index("Upload exact available build and release evidence") assert smoke < prepare < initialize < auth < push < finalize < cleanup < complete < upload assert "scripts/run_leoclean_nosend_runtime_canary.sh" in workflow assert "scripts/run_gcp_leoclean_nosend_oci_smoke.py" in workflow assert 'assert smoke["input_sha256"] == image_input["input_sha256"]' in workflow assert 'assert smoke["cleanup"]["status"] == "pass"' in workflow def test_release_workflow_uses_exact_wif_artifact_builder_without_repository_secrets() -> None: workflow = load_workflow() text = WORKFLOW.read_text(encoding="utf-8") env = workflow["env"] assert env["PROJECT_ID"] == "teleo-501523" assert env["REGION"] == "europe-west6" assert env["ARTIFACT_REPOSITORY"] == "teleo" assert env["IMAGE_REPOSITORY"] == package.IMAGE_REPOSITORY assert env["WORKLOAD_IDENTITY_PROVIDER"] == ( "projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/living-ip-github" ) assert env["ARTIFACT_SERVICE_ACCOUNT"] == "sa-artifact-builder@teleo-501523.iam.gserviceaccount.com" assert "${{ secrets." not in text assert "password" not in text.casefold() auth = workflow_step("Authenticate to Google Cloud through WIF") assert auth["uses"] == "google-github-actions/auth@c200f3691d83b41bf9bbd8638997a462592937ed" assert auth["with"] == { "workload_identity_provider": "${{ env.WORKLOAD_IDENTITY_PROVIDER }}", "service_account": "${{ env.ARTIFACT_SERVICE_ACCOUNT }}", "create_credentials_file": "true", "export_environment_variables": "true", } def test_release_workflow_keeps_runner_temp_out_of_job_environment() -> None: workflow = load_workflow() jobs = workflow["jobs"] assert isinstance(jobs, dict) publish = jobs["publish"] assert isinstance(publish, dict) root_env = workflow["env"] job_env = publish.get("env", {}) assert isinstance(root_env, dict) assert isinstance(job_env, dict) assert all("runner.temp" not in value for value in [*root_env.values(), *job_env.values()]) initialize = workflow_step("Initialize private release paths")["run"] assert 'release_root="${RUNNER_TEMP}/leoclean-nosend-release"' in initialize def test_release_workflow_requires_immutable_repository_and_package_owned_candidate_push() -> None: workflow = WORKFLOW.read_text(encoding="utf-8") immutable = workflow_step("Require immutable fixed Artifact Registry repository")["run"] push = workflow_step("Build and push one immutable candidate")["run"] assert "gcloud artifacts repositories describe" in immutable assert 'repository["dockerConfig"]["immutableTags"] is True' in immutable assert "ops/gcp_leoclean_nosend_package.py build-push" in push assert "--execute-staging-push" in push assert "--docker-binary /usr/bin/docker" in push assert "--docker-host unix:///var/run/docker.sock" in push assert '--gcloud-binary "$(command -v gcloud)"' in push assert '--outcome-journal "${PUBLISH_OUTCOME}"' in push assert "docker push" not in workflow assert "docker tag" not in workflow assert "candidate-" not in workflow def test_release_workflow_always_finalizes_journal_and_uploads_only_allowlisted_evidence() -> None: finalize = workflow_step("Finalize and validate release v3 bundle")["run"] cleanup = workflow_step("Remove ephemeral Docker authentication") complete = workflow_step("Finalize publish outcome") upload = workflow_step("Upload exact available build and release evidence") paths = upload["with"]["path"].splitlines() assert "ops/gcp_leoclean_nosend_package.py finalize" in finalize assert "ops/gcp_leoclean_nosend_package.py validate" in finalize assert 'assert release["schema"] == "livingip.leocleanNoSendRelease.v3"' in finalize assert cleanup["if"] == "always()" assert complete["if"] == "always() && steps.init_outcome.outcome == 'success'" assert "ops/gcp_leoclean_nosend_package.py complete-outcome" in complete["run"] assert '--build-outcome "${{ steps.build_push.outcome }}"' in complete["run"] assert '--finalize-outcome "${{ steps.finalize.outcome }}"' in complete["run"] assert '--cleanup-outcome "${{ steps.cleanup.outcome }}"' in complete["run"] assert upload["if"] == "always()" assert paths == [ "${{ runner.temp }}/leoclean-nosend-release/evidence/runtime-receipt.json", "${{ runner.temp }}/leoclean-nosend-release/evidence/oci-smoke.json", "${{ runner.temp }}/leoclean-nosend-release/evidence/publish-outcome.json", "${{ runner.temp }}/leoclean-nosend-release/receipts/build-push-receipt.json", "${{ runner.temp }}/leoclean-nosend-release/final/release-v3/release.json", "${{ runner.temp }}/leoclean-nosend-release/final/release-v3/leoclean-gcp-nosend.service", ] assert upload["with"]["if-no-files-found"] == "warn" assert upload["with"]["retention-days"] == "30" assert "*" not in upload["with"]["path"] assert "google-github-actions" not in upload["with"]["path"] def test_release_workflow_has_no_deployment_or_runtime_mutation_surface() -> None: workflow = WORKFLOW.read_text(encoding="utf-8").casefold() forbidden = ( "--execute-restart", "install_gcp_leoclean_nosend_release.py", "gcloud compute", "gcloud sql", "gcloud secrets", "kubectl", "systemctl", "terraform apply", ) assert all(marker not in workflow for marker in forbidden)