Skip to content

fix(ci): rsync gh-pages publishes by checksum, not size+mtime - #372

Merged
crs48 merged 1 commit into
mainfrom
claude/fix-publish-rsync-checksum
Jul 4, 2026
Merged

fix(ci): rsync gh-pages publishes by checksum, not size+mtime#372
crs48 merged 1 commit into
mainfrom
claude/fix-publish-rsync-checksum

Conversation

@crs48

@crs48 crs48 commented Jul 4, 2026

Copy link
Copy Markdown
Owner

The second deploy-pipeline bug (stacked on #370)

After #370 unblocked Deploy Site, run 28709576907 went green — but the live app still served pre-#366 code. The publish commit (e99fa1de) tells the story: all the chunk renames landed (index-DppD45_e.js → index-BuveDUTb.js, web-worker-BIYC6Nw7.js → web-worker-BFqMZy2X.js, …) but app/index.html, app/404.html, and app/sw.js are absent from the diffstat — gh-pages ended up with a stale index.html pointing at a deleted entry chunk.

Root cause

publish-gh-pages syncs with rsync -a, whose quick check skips files whose size and mtime both match:

  • Size never changes for these files. A rebuild substitutes 8-char content hashes for 8-char content hashes, so index.html/404.html/sw.js are byte-for-byte the same length across builds.
  • mtime carries no signal. Both sides are freshly generated — cp -R build output (prepare step) vs a just-git worktree add-ed checkout (publish step) — every mtime is "now". This run's prepare-copy and checkout landed in the same second, so the quick check called them identical.

Every prior deploy dodged this by a one-second timing margin; it's a latent race in every publish (production, PR previews, branch previews — all use this action).

Fix

rsync -a --checksum — decide by content, deterministically. git add -A already ignores genuinely unchanged files, so the only cost is reading both trees.

After merge

.github/** isn't in Deploy Site's path filters, so I'll workflow_dispatch a production deploy, then verify gh-pages:app/index.html references the live entry chunk and the deployed bundle carries the #366/#369 markers.

🤖 Generated with Claude Code

Deploy e99fa1d published NEW app chunk hashes with a STALE
app/index.html (and 404.html + sw.js) still referencing the deleted
old entry chunk — the live app kept loading pre-#366 code even after
the deploy went green.

Root cause: rsync's default quick check skips files whose size and
mtime match. Both sides of this sync are freshly generated (cp'd build
output vs a just-checked-out gh-pages worktree), so every mtime is
"now" and carries no signal — and a rebuild substitutes 8-char content
hashes for 8-char content hashes, so index.html/404.html/sw.js keep
the exact same byte size across builds. When the prepare-copy and the
worktree checkout landed in the same second, the quick check silently
skipped precisely the three files whose size never changes. Every
earlier deploy dodged this by a one-second timing margin.

--checksum makes the decision by content, deterministically. git
add -A already dedupes genuinely unchanged files, so the only cost is
reading both trees.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48 crs48 added the skip-changelog Exclude this PR from the changelog label Jul 4, 2026
@crs48
crs48 temporarily deployed to pr-372 July 4, 2026 15:06 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #372.

github-actions Bot added a commit that referenced this pull request Jul 4, 2026
@crs48
crs48 merged commit a3f6bd7 into main Jul 4, 2026
15 of 16 checks passed
@crs48
crs48 deleted the claude/fix-publish-rsync-checksum branch July 4, 2026 15:11
github-actions Bot added a commit that referenced this pull request Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Exclude this PR from the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant