You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build production images on main and request release only after all image builds and the existing repository CI succeed for the same commit. GitHub authenticates with a scoped, short-lived publisher identity after building; the infrastructure-owned release pipeline handles production rollout. PR validation builds never publish.
This requires the matching infrastructure setup and repository variables before merging. Releases are disabled unless PRODUCTION_RELEASES_ENABLED is true.
Validation: actionlint, embedded shell/Python syntax, and applicable repository pre-commit checks passed. The frontend TypeScript check also passed.
Review: Automatic production releases (production-release.yml)
Overall this is a well-structured pipeline (short-lived WIF auth, build-before-auth ordering, digest pinning + asserted schema before publishing, size budget gate, and PRODUCTION_RELEASES_ENABLED kill switch are all good calls). Two issues look worth fixing before this goes live, plus a few smaller notes.
1. pull_request.paths filter references a Dockerfile that doesn't exist, so PR validation builds never trigger for real Dockerfile changes
There is no Dockerfile at the repo root — the actual files the build job's matrix compiles are compose/production/django/Dockerfile and frontend/Dockerfile. Neither is listed in this path filter. That means the stated purpose of the PR trigger ("PR validation builds never publish" / PRODUCTION_RELEASES.md: "PR builds validate images without authenticating") never actually fires when someone edits either production Dockerfile — the one case this validation exists for. A broken production Dockerfile would only be discovered after merging to main, when the release pipeline itself fails.
2. Release is gated on backend.yml only, but the pipeline also publishes/releases the frontend image
wait-for-production-ci.py is invoked with:
REQUIRED_WORKFLOWS: '["backend.yml"]'
frontend.yml (lint + component tests) is a separate workflow that also runs on push to main, but it's not in REQUIRED_WORKFLOWS. As written, the checks job can pass — and release can fire — while frontend CI for the same commit is still running or has failed, even though the build/release jobs build and ship a frontend image as part of the same release payload. This seems to contradict the PR description ("request release only after all image builds and the existing repository CI succeed") and the changelog fragment ("gated on successful CI"). Worth adding "frontend.yml" to REQUIRED_WORKFLOWS (and confirming whether any of the frontend-e2e*.yml workflows should also gate, if they're considered required signal for a release).
Minor notes
.github/scripts/wait-for-production-ci.py has clean, testable logic (check_runs) but no unit test. Since it's pure Python with no side effects beyond the HTTP call, a couple of quick tests (matched/success, matched/failure raises, no-match-yet) would cheaply lock in the "reruns supersede prior failures" behavior called out in the comment.
The inline Python in the release job's "Request production release" step uses bare assert for release-gating checks (commit match, digest format, expected image set). These execute correctly today (no -O/PYTHONOPTIMIZE in play), but since this is the last checkpoint before a real production rollout is requested, raising explicit exceptions (as wait-for-production-ci.py already does with RuntimeError/TimeoutError) would be more robust against a future environment change silently stripping assertions.
The release job declares permissions: actions: read, which doesn't appear to be used anywhere in that job's steps (no Actions API calls) — could probably be dropped for tighter least-privilege.
Nice touch pinning third-party actions to full commit SHAs here (a step up from the @v7-style tags used in docker-build-release.yml); .github/dependabot.yml already covers the github-actions ecosystem so these will still get automatic update PRs.
No concerns with the GraphQL/Python/React layers here since this PR is CI-only; didn't find security issues in the auth/permission flow itself (build-before-auth ordering, contents: read everywhere, no secrets logged, id-token only requested where OIDC federation is actually used).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Build production images on main and request release only after all image builds and the existing repository CI succeed for the same commit. GitHub authenticates with a scoped, short-lived publisher identity after building; the infrastructure-owned release pipeline handles production rollout. PR validation builds never publish.
This requires the matching infrastructure setup and repository variables before merging. Releases are disabled unless PRODUCTION_RELEASES_ENABLED is true.
Validation: actionlint, embedded shell/Python syntax, and applicable repository pre-commit checks passed. The frontend TypeScript check also passed.