We have an ongoing issue with concurrent publishing to the
grails-website repository. This has affected multiple releases over the
past several months in addition to grails-website publishing. Any time
two publishing actions are running at the same time.
I previously opened
https://github.com/apache/grails-github-actions/pull/98 to make
concurrent documentation pushes safe. It was closed in favor of a
job-level concurrency group (`grails-docs-publish`) added in
grails-core#15988 and then closed again, after re-opening, when it
became clear that did not work. That approach serializes independent
documentation jobs within Grails Core. Because GitHub Actions
concurrency groups are scoped to a single repository, it cannot
coordinate publishers from other repositories (grails-static-website,
and eventually Grails Forge) that also target the same destination branch.
In practice making this serial has introduced measurable delays during
release sequences (for example, an 18-minute wait observed on the each
release documentation job, plus manual synchronization, plus manual
re-run on grail-website action which failed, plus waiting on github
runner availability). This burned 3 hours this morning.
The current pair of pull requests restores the ability to publish in
parallel while remaining conservative:
- https://github.com/apache/grails-github-actions/pull/110 – Safely
retry concurrent documentation pushes
When another publisher advances the destination branch first, the
action recognizes a genuine non-fast-forward rejection, fetches the new
tip into the existing shallow checkout, confirms the fetched tip
descends from the originally observed tip, rebases the unpublished local
deployment commit, and retries a normal push (maximum five attempts).
There is no force-push. Conflicts, non-descendant history, and unrelated
failures fail closed without modifying the remote.
- https://github.com/apache/grails-core/pull/16110 – Allow concurrent
documentation publishing
Removes the repository-local `grails-docs-publish` queue so
independent documentation jobs can proceed once the action-level retry
is available. Git’s normal fast-forward rules then coordinate updates to
the shared branch.
This is a deliberately narrow solution. It covers the cross-repository
case, avoids serializing unrelated release work, and fails safely. I am
open to any alternative that fully addresses the same constraints
(multiple independent publishers, no force-push, safe handling of true
content conflicts, and no artificial serialization of independent jobs).
Until a better complete solution is available and verified, these
changes allow the project to move forward without further release delays.
An alternate solution has also been proposed of uploading artifacts and
then having a separate workflow process them:
That approach would introduce additional moving parts (artifact storage,
a new coordinating workflow, hand-off between producers and a consumer,
extra latency, and new failure modes) for what is fundamentally a
concurrent commit problem on a shared branch. Multiple independent
publishers are simply generating documentation and pushing it to the
same destination. When another push lands first, the required response
is the standard Git sequence: fetch the new tip, rebase the unpublished
local commit, and push again. That is exactly what the retry logic in
apache/grails-github-actions#110 does, using ordinary fast-forward rules
and failing closed on true conflicts.
Let's debate this and get it fixed before the next release cycle, so we
can get back to faster releases.
James
- Allowing concurrent publishes to grails-website James Fredley
-