Skip to content

Fix older publishes overwriting newer deploys - #2294

Merged
cderv merged 4 commits into
mainfrom
ci/publish-per-site
Oct 16, 2026
Merged

cderv merged 4 commits into
mainfrom
ci/publish-per-site

Conversation

@cderv

@cderv cderv commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Deploys of the same site from different workflows do not wait for each other. publish.yml grouped its concurrency by calling workflow and ref, so a publish from a push to main, from update-downloads.yml and from the axe report each ran in their own group, and an older build finishing last could overwrite a newer deploy.

This becomes more frequent with #2293, where sync PRs are merged right away and publish prerelease themselves.

Fix

There is now one concurrency group per deployed site, quarto.org and prerelease.quarto.org, whichever workflow calls publish.yml. The site is picked the same way the deploy steps pick it, so a caller passing prerelease: false from the prerelease branch (the axe report dispatched there) still lands in the quarto.org group. A dispatch of publish.yml from any other branch deploys neither site, so it gets its own group and never cancels a deploy.

In a shared group, the run that queues last cancels the one in progress. Every publish now checks out the branch tip when the job starts instead of a fixed commit, so the run that wins includes every earlier change. update-downloads.yml and axe-scan.yml pass the branch name instead of the commit they just pushed, and push-triggered runs check out github.ref instead of github.sha.

The render profile had the same problem, already on main. A called workflow inherits the caller's ref, so the axe report dispatched from prerelease rendered its quarto.org publish with the prerelease-docs profile, and quarto.org was deployed with prerelease branding and site URLs. The profile is now picked with the same guard as the prerelease deploy step, so prerelease: false always renders the release profile.

Test Plan

  • zizmor and actionlint on the workflows: no new findings
  • After merge, the next push to main publishes quarto.org from the branch tip
  • After merge, the next Update Downloads run with changes publishes both sites

cderv added 4 commits October 16, 2026 15:17
publish.yml grouped its concurrency by the calling workflow and ref, so deploys of the same site from different workflows (a push, update-downloads, the axe report, the prerelease sync) ran in separate groups and an older build finishing last could overwrite a newer deploy.
The group is now keyed on the deployed site, whichever workflow calls publish.yml.

The site is picked the way the deploy steps pick it: an explicit prerelease input wins over github.ref.
A called workflow inherits the caller's ref, so falling back to the ref whenever the input was false would put the quarto.org publish of an Axe Report dispatched from prerelease in the prerelease group, cancelling its sibling.
With one concurrency group per site, the run that queues last cancels
the one in progress. update-downloads and axe-scan passed the SHA they
had just pushed, so a publish queued a few seconds late could cancel a
run for a newer commit and deploy the older SHA. Push-triggered runs
had the same exposure through the default checkout of github.sha.

Every caller now passes a branch name, and the checkout falls back to
github.ref instead of github.sha, so each run builds the branch tip as
it stands when the job starts. The commit-hash job outputs that only
fed the pinned refs are removed.
Dispatching Quarto Publish from a branch other than main or prerelease
deploys neither site, but its run fell into the main group and
cancelled any quarto.org publish in progress, leaving those changes
unpublished. The previous group included the ref, so such a run was
isolated. It now gets a group named after its ref.
A called workflow inherits the caller's ref and event. Dispatching Axe
Report from prerelease called publish.yml for quarto.org with
prerelease: false, but github.ref was refs/heads/prerelease, so the
render used the prerelease-docs profile and quarto.org was deployed
with prerelease branding and site URLs.

The profile condition now carries the same guard as the prerelease
deploy step, so an explicit prerelease: false always renders the
release profile.
@cderv
cderv merged commit 6965812 into main Oct 16, 2026
1 check passed
@cderv
cderv deleted the ci/publish-per-site branch October 16, 2026 14:12
@github-actions

Copy link
Copy Markdown
Contributor

Successfully created backport PR for prerelease:

github-actions Bot added a commit that referenced this pull request Oct 16, 2026
* Serialize publishes per deployed site

publish.yml grouped its concurrency by the calling workflow and ref, so deploys of the same site from different workflows (a push, update-downloads, the axe report, the prerelease sync) ran in separate groups and an older build finishing last could overwrite a newer deploy.
The group is now keyed on the deployed site, whichever workflow calls publish.yml.

The site is picked the way the deploy steps pick it: an explicit prerelease input wins over github.ref.
A called workflow inherits the caller's ref, so falling back to the ref whenever the input was false would put the quarto.org publish of an Axe Report dispatched from prerelease in the prerelease group, cancelling its sibling.

* Publish the branch tip so a cancelling run never deploys older content

With one concurrency group per site, the run that queues last cancels
the one in progress. update-downloads and axe-scan passed the SHA they
had just pushed, so a publish queued a few seconds late could cancel a
run for a newer commit and deploy the older SHA. Push-triggered runs
had the same exposure through the default checkout of github.sha.

Every caller now passes a branch name, and the checkout falls back to
github.ref instead of github.sha, so each run builds the branch tip as
it stands when the job starts. The commit-hash job outputs that only
fed the pinned refs are removed.

* Keep publishes that deploy nothing out of the main group

Dispatching Quarto Publish from a branch other than main or prerelease
deploys neither site, but its run fell into the main group and
cancelled any quarto.org publish in progress, leaving those changes
unpublished. The previous group included the ref, so such a run was
isolated. It now gets a group named after its ref.

* Render with the profile of the site being deployed

A called workflow inherits the caller's ref and event. Dispatching Axe
Report from prerelease called publish.yml for quarto.org with
prerelease: false, but github.ref was refs/heads/prerelease, so the
render used the prerelease-docs profile and quarto.org was deployed
with prerelease branding and site URLs.

The profile condition now carries the same guard as the prerelease
deploy step, so an explicit prerelease: false always renders the
release profile.

(cherry picked from commit 6965812)

Co-authored-by: Christophe Dervieux <christophe.dervieux@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant