"""Check the dependency graph that ties tested digests to deployable images.""" from pathlib import Path import yaml ROOT = Path(__file__).resolve().parents[3] def test_staging_verifies_identity_before_and_after_journeys(): workflow = yaml.safe_load((ROOT / '.gitea/workflows/deploy.yml').read_text()) assert workflow['concurrency'] == {'group': 'staging-release', 'cancel-in-progress': False} jobs = workflow['jobs'] for component in ('backend', 'frontend', 'pipeline'): job = jobs['build-' + component] assert 'prepare' in job['needs'] assert job['outputs']['digest'] == '${{ steps.build.outputs.digest }}' build = next(step for step in job['steps'] if step.get('id') == 'build') assert 'BUILD_ID=${{ needs.prepare.outputs.build_id }}' in build['with']['build-args'] steps = jobs['e2e-staging']['steps'] runs = [step.get('run', '') for step in steps] test = runs.index('npx playwright test') assert 'release.py wait' in runs[test - 1] assert 'release.py wait' in runs[test + 1] assert 'release.py verify' in runs[-1] for component in ('backend', 'frontend', 'pipeline'): assert 'build-' + component in jobs['e2e-staging']['needs'] assert component.upper() + '_DIGEST' in steps[-1]['env'] def test_promotion_uses_verified_digest_resolver_and_build_identity_poll(): workflow = yaml.safe_load((ROOT / '.gitea/workflows/promote.yml').read_text()) steps = workflow['jobs']['promote-prod']['steps'] runs = [step.get('run', '') for step in steps] assert 'python3 scripts/ci/release.py promote --output release.json' in runs assert runs[-1] == 'python3 scripts/ci/release.py wait --release release.json'