teleo-infrastructure/.github/workflows/gcp-readiness.yml
twentyOne2x c9a2573e86
Some checks are pending
CI / lint-and-test (push) Waiting to run
Harden GCP artifact and readiness receipts
Retains immutable Artifact Registry image digests and makes GCP readiness workflows fail after uploading evidence when readiness checks fail.
2026-07-07 13:24:14 +02:00

116 lines
4.5 KiB
YAML

name: gcp-readiness
on:
workflow_dispatch:
inputs:
service_account:
description: GCP service account to impersonate for the read-only readiness probe
required: false
default: sa-artifact-builder@teleo-501523.iam.gserviceaccount.com
permissions:
contents: read
id-token: write
concurrency:
group: gcp-readiness-${{ github.ref }}
cancel-in-progress: true
env:
PROJECT_ID: teleo-501523
WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/living-ip-github
READINESS_SERVICE_ACCOUNT: ${{ inputs.service_account || 'sa-artifact-builder@teleo-501523.iam.gserviceaccount.com' }}
READINESS_ARTIFACT_DIR: gcp-readiness-artifacts
jobs:
readiness:
name: Read-only GCP readiness probe
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- id: auth
uses: google-github-actions/auth@v2
with:
workload_identity_provider: ${{ env.WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.READINESS_SERVICE_ACCOUNT }}
- uses: google-github-actions/setup-gcloud@v2
- name: Capture gcloud identity
shell: bash
run: |
set +e
mkdir -p "${READINESS_ARTIFACT_DIR}"
{
echo "project=${PROJECT_ID}"
echo "service_account=${READINESS_SERVICE_ACCOUNT}"
echo "workflow_ref=${GITHUB_REF}"
echo "revision=${GITHUB_SHA}"
} > "${READINESS_ARTIFACT_DIR}/context.txt"
gcloud auth list --format=json > "${READINESS_ARTIFACT_DIR}/gcloud-auth-list.json" 2> "${READINESS_ARTIFACT_DIR}/gcloud-auth-list.stderr"
echo "$?" > "${READINESS_ARTIFACT_DIR}/gcloud-auth-list.exitcode"
gcloud config list --format=json > "${READINESS_ARTIFACT_DIR}/gcloud-config-list.json" 2> "${READINESS_ARTIFACT_DIR}/gcloud-config-list.stderr"
echo "$?" > "${READINESS_ARTIFACT_DIR}/gcloud-config-list.exitcode"
- name: Run readiness checker
shell: bash
run: |
set +e
mkdir -p "${READINESS_ARTIFACT_DIR}"
python3 ops/check_gcp_infra_readiness.py \
> "${READINESS_ARTIFACT_DIR}/gcp-infra-readiness.json" \
2> "${READINESS_ARTIFACT_DIR}/gcp-infra-readiness.stderr"
echo "$?" > "${READINESS_ARTIFACT_DIR}/gcp-infra-readiness.exitcode"
python3 - <<'PY'
import os
import json
from pathlib import Path
base = Path(os.environ["READINESS_ARTIFACT_DIR"])
report = {
"artifact": "github_wif_gcp_readiness_probe",
"checker_exitcode": (base / "gcp-infra-readiness.exitcode").read_text().strip(),
"stderr_tail": (base / "gcp-infra-readiness.stderr").read_text()[-2000:],
}
try:
payload = json.loads((base / "gcp-infra-readiness.json").read_text() or "{}")
except json.JSONDecodeError as exc:
report["json_parse_error"] = str(exc)
payload = {}
if payload:
report["pass_count"] = payload.get("pass_count")
report["blocked_count"] = payload.get("blocked_count")
report["fail_count"] = payload.get("fail_count")
report["checks"] = [
{
"name": check.get("name"),
"status": check.get("status"),
"required_tier": check.get("required_tier"),
"current_tier": check.get("current_tier"),
"detail": (check.get("detail") or "")[:500],
}
for check in payload.get("checks", [])
]
(base / "gcp-readiness-summary.json").write_text(json.dumps(report, indent=2, sort_keys=True) + "\n")
print(json.dumps(report, indent=2, sort_keys=True))
PY
- name: Upload readiness artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: gcp-readiness
path: ${{ env.READINESS_ARTIFACT_DIR }}/
if-no-files-found: error
- name: Enforce readiness result
if: always()
shell: bash
run: |
code="$(cat "${READINESS_ARTIFACT_DIR}/gcp-infra-readiness.exitcode" 2>/dev/null || echo 1)"
if [ "${code}" != "0" ]; then
echo "GCP readiness checker failed with exit code ${code}. See the uploaded gcp-readiness artifact for exact failed checks."
exit "${code}"
fi