Skip to content

Deploy the site twice rather than waiting to be asked - #84

Merged
marcosqlbi merged 1 commit into
mainfrom
fix/publish-site-retry
Sep 2, 2026
Merged

Deploy the site twice rather than waiting to be asked#84
marcosqlbi merged 1 commit into
mainfrom
fix/publish-site-retry

Conversation

@marcosqlbi

Copy link
Copy Markdown
Collaborator

Publish site has failed on almost every release: 7 of 23 release-triggered runs passed, while pushes passed 9 of 9 and manual runs 8 of 8. Running it by hand afterwards always fixed it.

It is not flaky. A Pages deployment is identified by commit SHA — deploy-pages sends the SHA as pages_build_version and then polls a deployment status keyed on that same SHA — and a release redeploys a commit Pages already holds, because the release tag, the pre-release tag and main are all one commit. The second deployment of that commit reads the first one's status, reports success in six seconds, and is then never served. In the 1.2.2 run the stalled deployment sat at in_progress for five minutes, where a healthy one reaches success in about ten seconds, and the site went on serving stable.json 1.2.1 until the workflow was run by hand.

The verify step added for 1.0.0 is the only reason any of this was ever visible rather than a download page quietly a version behind.

Deploying the same files again clears it, so the workflow now does that itself: a short first check (90s — a deployment that is going to appear is serving within about ten seconds, so a long wait only delayed the fix), a second deploy-pages if the site is still stale, then the full check. A run that fails now has failed twice, and the collision is not the explanation — the failure message and docs/release-management.md say so, and point at the github-pages environment for a deployment stuck in progress.

Verified as far as it can be before a release: the YAML parses and the step graph is right, and scripts/verify-published-site.ps1 was run against the live domain in both its outcomes. The retry path itself can only be proved by a colliding deployment, so I would like to exercise it after merge by running Publish site twice in a row on main — the second run redeploys the same commit, which is the collision, and it publishes identical files either way.

🤖 Generated with Claude Code

Publish site failed on all but 7 of 23 release-triggered runs, while
pushes passed 9 of 9 and manual runs 8 of 8, and a re-run by hand always
fixed it.

The cause is that a release redeploys a commit Pages already holds. A
Pages deployment is identified by commit SHA - deploy-pages sends the SHA
as pages_build_version and polls a status keyed on the same SHA - and the
release tag, the pre-release tag and main are all one commit. The second
deployment of that commit reads the first one's status, reports success
in six seconds, and is then never served: the stalled deployment sat at
in_progress for five minutes where a healthy one reaches success in ten
seconds. The verify step, added for 1.0.0, is the only reason any of this
was visible rather than a download page quietly a version behind.

Deploying the same files again clears it, so the workflow now does that
itself: a short first check, a second deploy if the site is still stale,
then the full check. A run that fails now has failed twice, and the
collision is not the explanation - which is what the failure message and
docs/release-management.md now say.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@marcosqlbi
marcosqlbi merged commit bdc0db9 into main Sep 2, 2026
4 checks passed
@marcosqlbi
marcosqlbi deleted the fix/publish-site-retry branch September 2, 2026 13:08
marcosqlbi added a commit that referenced this pull request Sep 2, 2026
**The retry from #84 does not work.** Dev 3286 was its first real test:
it deployed, the site was stale, it deployed again, and the site was
still stale. That run is also what finally identified the cause.

**A Pages deployment made from a tag is not served unless it is the
first deployment of that commit.** One made from a branch supersedes
whatever is live, first or not. Commit `f169379` settles it:

| time | ref | outcome |
|---|---|---|
| 13:59 | `main` | went live |
| 14:20 | tag `v1.2.2-dev.3286` | stalled, and stalled again on the
retry |

By the time a release is published, its commit has usually been deployed
from `main` already — the release tag, the pre-release tag and `main`
are all one commit — so the release's own deployment is created,
reported as succeeded by `deploy-pages`, and never served. Across the
runs since the verify step existed: pushes 9 of 9, manual runs 8 of 8,
release-triggered runs 7 of 23.

So **a release no longer deploys the site**. The new `redeploy` job asks
this same workflow to run on `main`, passing the release tag as an input
so `-ExpectTag` still stops the manifests being written before the
release is listed. `workflow_dispatch` is one of the two events GitHub
exempts from the rule that `GITHUB_TOKEN` cannot start another workflow
run, so no personal access token is needed. A release now produces two
runs: a three-line dispatcher on the tag, and the deployment on `main`.

The retry is **removed** rather than left beside the real fix. It is
known not to work for the only failure it ever targeted, and leaving
both in would make it unclear which one was doing the work. The verify
step stays — that is what catches the problem.

Also clears the Node 20 deprecation warnings, which the runners already
force to Node 24: `configure-pages` v5→v6, `deploy-pages` v4→v5,
`upload-pages-artifact` v3→v5. The last is what drops the transitive
`upload-artifact@v4`. Note `upload-pages-artifact` v4 stopped including
dotfiles in the artifact — `site/` has none, so nothing is silently
dropped, and there is a comment saying what to do if one is ever added.

Because the release path no longer sees the release event, the changelog
check now reads the tag from the input and decides from its shape:
`v1.2.2` is checked, `v1.2.2-dev.3286` is skipped as a pre-release,
empty means this is not a release deployment. All four branches were
exercised locally, including that an unwritten version exits 1.

**This cannot be fully proved until the next release** — the dispatcher
only runs on a `release` event. What a merge does prove is the deploy
path itself: the same steps on `main`, on the new action versions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 <noreply@anthropic.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