Build Docker images on native arm64 runners to fix release hang#296
Conversation
The v0.4.2 release Docker build exceeded GitHub's 6-hour job limit and was cancelled, while normal main-push builds finished in ~3 minutes. The workflow built linux/amd64,linux/arm64 in one job on an amd64 runner, so arm64 was produced under QEMU emulation. The Dockerfile builder stage is pinned to $BUILDPLATFORM (native), but the runtime stage is not, so the arm64 'pnpm install --prod' and 'npx prisma generate' ran emulated. These were normally inline-cache hits; the preceding dependency bump (#294/#295) rewrote pnpm-lock.yaml and package.json, invalidating the cache and forcing the emulated steps to execute for the first time -> 6h timeout. Build each platform on its own native runner (ubuntu-24.04 / ubuntu-24.04-arm, free on this public repo), push by digest, and merge a multi-arch manifest. Replace the broken type=inline cache with type=gha,mode=max scoped per arch, and add timeout-minutes so a hang fails fast instead of burning 6h. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
📝 WalkthroughWalkthroughDocker publish workflow reworked from single multi-arch image build to two-stage architecture-native builds with per-digest artifacts, followed by manifest-list merge. Task documentation explains the arm64 hang root cause and provides implementation checklist. ChangesDocker Workflow Multi-Arch Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/docker-publish.yml:
- Line 50: Replace tag-pinned GitHub Action refs with immutable commit SHAs for
all uses entries mentioned (actions/checkout, docker/login-action,
docker/setup-buildx-action, docker/build-push-action, actions/upload-artifact,
actions/download-artifact, docker/metadata-action). For each occurrence (e.g.,
the existing uses: entries like actions/checkout@v4 and
docker/build-push-action@v6), look up the corresponding repository's recommended
commit SHA for the desired tag/release and update the uses value to the full SHA
ref (e.g., actions/checkout@<sha>) to ensure immutable pinning; do this
consistently for the instances at the workflow locations that reference those
action names so the workflow uses specific commit SHAs instead of version tags.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6be85f52-8eee-4962-a784-44cc53ebe31f
📒 Files selected for processing (3)
.github/workflows/docker-publish.ymldocs/tasks/README.mddocs/tasks/active/20260525-docker-publish-arm64-native-todo.md
| # and push by digest only; the merge job assembles the tagged manifest. | ||
| - name: Build and push image by digest | ||
| id: build | ||
| uses: docker/build-push-action@v6 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find non-SHA-pinned `uses:` references in this workflow.
rg -nP '^\s*uses:\s*[^@]+@(?!(?:[0-9a-fA-F]{40})$).+$' .github/workflows/docker-publish.ymlRepository: wafflebase/wafflebase
Length of output: 454
Pin GitHub Actions to immutable commit SHAs (including checkout).
In .github/workflows/docker-publish.yml, these uses: refs are tag-pinned (@v*) rather than SHA-pinned, weakening supply-chain integrity: actions/checkout@v4 (35), docker/login-action@v3 (38, 88), docker/setup-buildx-action@v3 (44, 94), docker/build-push-action@v6 (50), actions/upload-artifact@v4 (65), actions/download-artifact@v4 (81), and docker/metadata-action@v5 (99).
[NO DIFF NEEDED—SUGGESTED PATCH SHAPE ALREADY PROVIDED IN ORIGINAL COMMENT]
🧰 Tools
🪛 zizmor (1.25.2)
[error] 50-50: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/docker-publish.yml at line 50, Replace tag-pinned GitHub
Action refs with immutable commit SHAs for all uses entries mentioned
(actions/checkout, docker/login-action, docker/setup-buildx-action,
docker/build-push-action, actions/upload-artifact, actions/download-artifact,
docker/metadata-action). For each occurrence (e.g., the existing uses: entries
like actions/checkout@v4 and docker/build-push-action@v6), look up the
corresponding repository's recommended commit SHA for the desired tag/release
and update the uses value to the full SHA ref (e.g., actions/checkout@<sha>) to
ensure immutable pinning; do this consistently for the instances at the workflow
locations that reference those action names so the workflow uses specific commit
SHAs instead of version tags.
Verification: verify:selfResult: ✅ PASS in 219.8s
Verification: verify:integrationResult: ✅ PASS |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
These tasks landed on main per recent commit log: docker-publish-arm64 (#296), import-progress-toast (#299), pptx-blipfill-fillrect-crop (#297), release-v0.4.2 (#295), slides-textbox-autogrow (cf83a49), and slides-textbox-edit-theme-color (#300). Move their docs to archive/2026/05 and regenerate the task indexes. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
These tasks landed on main per recent commit log: docker-publish-arm64 (#296), import-progress-toast (#299), pptx-blipfill-fillrect-crop (#297), release-v0.4.2 (#295), slides-textbox-autogrow (cf83a49), and slides-textbox-edit-theme-color (#300). Move their docs to archive/2026/05 and regenerate the task indexes. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Summary
The v0.4.2 release Docker build hangs and fails (run 26367212237). Attempt 1 ran for exactly 6h (16:54:50 → 22:55:08) and was cancelled by GitHub's hard 6-hour job limit; attempt 2 was grinding toward the same fate. Previous releases (v0.4.1 / v0.4.0 / v0.3.x) all finished in ~2–3 min.
Root cause
docker-publish.ymlbuiltlinux/amd64,linux/arm64in a single job on an amd64 runner, so arm64 was produced under QEMU emulation. TheDockerfilepins the builder stage to--platform=$BUILDPLATFORM(native, fast), but the runtime stage is not pinned, so for the arm64 target these ran emulated:pnpm install --frozen-lockfile --prodnpx [email protected] generate← notoriously slow / hangs under QEMU arm64These were normally inline-cache hits (
cache-from: type=registry,ref=:latest), so the emulatedRUNs never executed → ~3 min. The release was immediately preceded by #294 ("Bump deps", rewrotepnpm-lock.yaml687 lines + 6package.json) and #295 (version bump, touched lockfile + allpackage.json), which invalidated those cached layers. The release then executed the arm64 runtime stage emulated for the first time → past the 6h limit.type=inlinecache also can't recover (no multi-arch / intermediate-stage caching).Fix
Build each platform on its own native runner — no QEMU anywhere:
buildmatrix:linux/amd64→ubuntu-24.04,linux/arm64→ubuntu-24.04-arm(free on this public repo), each pushed by digest.mergejob downloads the digests and assembles the multi-arch manifest viadocker buildx imagetools create, applying tags fromdocker/metadata-action.type=inlinecache withtype=gha,mode=maxscoped per arch.timeout-minutes(30 build / 15 merge) so a hang fails fast instead of burning 6h.Tag semantics are unchanged: push to
main→:latest; release →:<tag_name>+:latest. Pattern follows the official Docker "distribute build across multiple runners" reference.Tradeoff:
type=ghakeeps Docker Hub clean (vstype=registrycache tags). GHA cache is ref-scoped, so release (tag-ref) builds get a cold cache and rebuild natively (~minutes, acceptable);mainpushes reuse their scope and stay fast.Test plan
pnpm verify:fastgreen (lint + 792 unit tests).build+merge.Docker Publish(push tomainpath) — confirm both arch builds finish in minutes and the manifest merges.docker buildx imagetools inspect yorkieteam/wafflebase:v0.4.2shows amd64 + arm64).🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Chores