Skip to content

ci: build multi-arch images via QEMU (no ARM64 runner needed)#86

Merged
GeiserX merged 1 commit into
mainfrom
ci/multiarch-qemu
Jun 11, 2026
Merged

ci: build multi-arch images via QEMU (no ARM64 runner needed)#86
GeiserX merged 1 commit into
mainfrom
ci/multiarch-qemu

Conversation

@GeiserX

@GeiserX GeiserX commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Problem

The release Docker build never publishes a multi-arch image. The build-ui-arm64 / build-worker-arm64 jobs require runs-on: [self-hosted, Linux, ARM64], but the only registered runner is watchtower-cashpilot (X64). Those jobs queue forever, and the manifest job (which needs all 4 arch jobs) never runs. v0.6.12's arm64 jobs are still stuck weeks later for the same reason — so the published :latest/:x.y.z tags were only ever the per-arch -amd64/-arm64 suffixed images, never a merged manifest.

Fix

Replace the 4 per-arch jobs + manifest-merge with one QEMU-emulated buildx job per image that builds linux/amd64,linux/arm64 together and pushes the multi-platform manifest directly under all tags (:latest, :x.y.z, :x.y). Adds docker/setup-qemu-action@v3.

  • No ARM64 runner required — runs entirely on the existing X64 runner.
  • runs-on: [self-hosted, Linux, X64] so GitHub schedules whichever X64 runner (watchtower / geiserback) is free.
  • build-push-action produces the manifest natively when pushing multiple platforms, so the separate manifest job is removed.

Notes

  • Base image python:3.14-alpine is multi-arch; Dockerfiles have no hardcoded-arch downloads, so arm64 builds cleanly under emulation.
  • arm64 via QEMU is slower (emulated), but correct and unblocked.

Test plan

  • Merge → next release builds and pushes a true multi-arch manifest for both cashpilot and cashpilot-worker
  • docker manifest inspect drumsergio/cashpilot:latest shows both amd64 + arm64

Summary by CodeRabbit

Release Notes

  • Chores
    • Optimized CI/CD workflow by consolidating multi-architecture Docker image builds into unified jobs, reducing build pipeline complexity and improving deployment efficiency.

The arm64 build jobs required a [self-hosted, Linux, ARM64] runner that
does not exist (only watchtower-cashpilot, an X64 runner, is registered),
so build-ui-arm64 / build-worker-arm64 queued forever and the manifest
job never published a multi-arch image (v0.6.12's arm64 jobs are still
stuck for the same reason).

Replace the 4 per-arch jobs + manifest-merge with one QEMU-emulated
buildx job per image that builds linux/amd64,linux/arm64 together and
pushes the multi-platform manifest directly under all tags. runs-on
stays [self-hosted, Linux, X64] so GitHub schedules whichever X64 runner
(watchtower / geiserback) is free.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflow consolidates multi-architecture Docker image builds into single jobs using Docker Buildx. Previous separate amd64 and arm64 jobs for UI and worker services, plus a manifest aggregation job, are replaced with unified build-ui and build-worker jobs that build and push both architectures simultaneously with QEMU cross-compilation support.

Changes

Multi-architecture Build Jobs

Layer / File(s) Summary
Consolidated multi-arch build jobs with Buildx
.github/workflows/build.yml
New build-ui and build-worker jobs use Docker Buildx and QEMU to build both linux/amd64 and linux/arm64 in a single step per job, pushing directly to multi-tag outputs from resolve-tags with architecture-scoped caching, eliminating per-arch job separation and manifest creation.

🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: replacing per-arch Docker build jobs with a QEMU-based multi-arch approach that eliminates the need for separate ARM64 runners.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/multiarch-qemu

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/build.yml (1)

91-92: 💤 Low value

Consider hardening action references (optional).

Static analysis flags two issues on the new/changed checkout and QEMU steps:

  1. persist-credentials: false: Prevents Git credentials from persisting in subsequent steps. Defensive measure when credentials aren't needed post-checkout.
  2. Pinning to SHA: Version tags can be force-pushed; pinning to commit hash mitigates supply-chain risk.

Same pattern exists in the lint job, so this is pre-existing—flagging for awareness, not as a blocker.

Example hardening
       - uses: actions/checkout@v6
+        with:
+          persist-credentials: false
       - uses: docker/setup-qemu-action@v3

For SHA pinning, you'd replace @v6 / @v3 with the full commit hash (e.g., @<sha>). This adds maintenance overhead for updates.

🤖 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/build.yml around lines 91 - 92, Update the two action
steps that use actions/checkout@v6 and docker/setup-qemu-action@v3: add
persist-credentials: false to the checkout step to avoid leaking Git creds, and
replace the loose tags (`@v6`, `@v3`) with the corresponding commit SHA pins for
both actions (i.e., pin actions/checkout and docker/setup-qemu-action to their
specific commit hashes) so the workflow references immutable commits rather than
mutable tags.

Source: Linters/SAST tools

🤖 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.

Nitpick comments:
In @.github/workflows/build.yml:
- Around line 91-92: Update the two action steps that use actions/checkout@v6
and docker/setup-qemu-action@v3: add persist-credentials: false to the checkout
step to avoid leaking Git creds, and replace the loose tags (`@v6`, `@v3`) with the
corresponding commit SHA pins for both actions (i.e., pin actions/checkout and
docker/setup-qemu-action to their specific commit hashes) so the workflow
references immutable commits rather than mutable tags.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 235a92cb-953d-4510-b83a-f017159cd8ed

📥 Commits

Reviewing files that changed from the base of the PR and between bc23621 and 43cd1a3.

📒 Files selected for processing (1)
  • .github/workflows/build.yml

@GeiserX GeiserX merged commit c66560b into main Jun 11, 2026
8 checks passed
@GeiserX GeiserX deleted the ci/multiarch-qemu branch June 11, 2026 15:52
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