QVAC-23049 infra: pin docs promotion to an explicit, pre-validated commit - #3587
Open
BrunoCampana wants to merge 1 commit into
Open
QVAC-23049 infra: pin docs promotion to an explicit, pre-validated commit#3587BrunoCampana wants to merge 1 commit into
BrunoCampana wants to merge 1 commit into
Conversation
- The commit to promote is now a required `workflow_dispatch` input. The job used to resolve `origin/main` at run time, which is *after* the environment approval, so anything merged during the (unbounded) approval wait was promoted to production without ever having been verified on staging. Naming the commit pins the promotion to the state the operator actually inspected. - Validation moved into a separate ungated `preflight` job. An environment gate pauses a job before its first step runs, so a single-job workflow can only discover a bad request *after* a reviewer has already been paged. Preflight rejects an unknown commit, a commit not contained in `main`, a commit behind `docs-production`, and divergence that makes the fast-forward impossible — all while the run is still unattended. It also publishes the resolved SHA and the exact list of commits being promoted to the run summary, which is what the approver reads before deciding. - Requiring containment in `main` is a security boundary, not a convenience: without it the dispatch input would be a path to deploy unreviewed code straight to the production site. - The gated job re-asserts containment and fast-forwardability against the branch as it stands after the wait, and explicitly refuses a target already contained in `docs-production`. `git merge --ff-only <ancestor>` reports "Already up to date" and exits 0, so without that check a branch that advanced past the target would produce a green run that pushed nothing while logging a successful promotion. - Promoting the commit `docs-production` already points at is a no-op: preflight skips the gated job entirely, so no reviewer is paged. - `run-name` now carries the target commit, making it visible in the run title before the approval decision. - Least privilege: top-level permissions dropped to `contents: read`, with `contents: write` only on the job that pushes; preflight checks out with `persist-credentials: false` so it cannot push at all. Both jobs declare `timeout-minutes`. - `docs/website/docs-workflow.md` updated to describe the input, the two jobs, and the full set of failure conditions.
Contributor
Review StatusCurrent Status: ❌ PENDING Pending reviews: Needs 1 Management or Team Lead, and 1 more from Management, Team Lead, or Member. |
Contributor
License compliance — cleanNo new dependency license findings in this PR. Warn-only (shadow) mode — this check does not block merges yet. Updated automatically by the canonical license compliance workflow. NOTICE presence (advisory)Missing NOTICE (advisory, does not block):
|
Contributor
Workflow security (shadow mode)zizmor found 1185 finding(s) in Findings are annotated inline on the changed files and listed in the job summary. Reproduce locally: pipx run zizmor==1.27.0 --offline .github/ |
BrunoCampana
marked this pull request as draft
August 1, 2026 01:19
BrunoCampana
marked this pull request as ready for review
August 1, 2026 01:28
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What problem does this PR solve?
Promoting docs to production was all-or-nothing: the workflow resolved
origin/maininside the job and advanceddocs-productionto whatever the tip ofmainhappened to be.mainaccumulates commits continuously, from everyone. The state that has been verified and is ready to publish is rarely its current tip — the operator needs to promote up to a chosen commit and leave the work that landed after it on staging. The workflow could not express that.docs-productionapproval, which can hold for hours — the promoted set could keep growing between dispatch and push, sweeping in commits nobody had verified.How does it solve it?
workflow_dispatchinput. The operator decides how fardocs-productionadvances, instead of always taking the tip ofmain, and the promotion stays pinned to that commit however long the approval takes.preflightjob. It rejects an unknown commit, a commit not contained inmain, a commit behinddocs-production, and divergence that makes the fast-forward impossible — all while the run is still unattended. The gated job is reached only by a promotion already known to be valid.mainis a security boundary, not a convenience. Without it the dispatch input would be a path to deploy unreviewed code straight to the production site.run-namecarries the target commit, so the approver can see what they are approving before clicking.docs-productionalready points at the requested commit, preflight skips the gated job entirely and the run ends green.mainand refuses a target already contained indocs-production—git merge --ff-only <ancestor>reports "Already up to date" and exits 0, so without that check a branch that advanced past the target would produce a green run that pushed nothing while logging a successful promotion.contents: read, withcontents: writeonly on the job that pushes; preflight checks out withpersist-credentials: falseso it cannot push at all. Both jobs declaretimeout-minutes.docs/website/docs-workflow.mdis updated to describe the input, the two jobs, and the full set of failure conditions.