Skip to content

build each image platform on its own runner, natively where possible - #228

Merged
phanan merged 1 commit into
masterfrom
native-arm64-runner-for-image-builds
Aug 10, 2026
Merged

build each image platform on its own runner, natively where possible#228
phanan merged 1 commit into
masterfrom
native-arm64-runner-for-image-builds

Conversation

@phanan

@phanan phanan commented Aug 10, 2026

Copy link
Copy Markdown
Member

The arm64 image was built under QEMU on an x86 runner, emulating every instruction of the build. GitHub's arm64 runners are free and unlimited on public repositories, so amd64 and arm64 now each build on their own architecture.

The single job that built all three platforms becomes a matrix of three, each pushing an untagged image identified only by its digest, followed by a merge job that assembles the digests into the tagged manifest with docker buildx imagetools create.

Platform Runner Native
linux/amd64 ubuntu-24.04 yes
linux/arm64 ubuntu-24.04-arm yes, was emulated
linux/arm/v7 ubuntu-24.04 no, stays under QEMU

linux/arm/v7 is 32-bit ARM, which the 64-bit Arm runners cannot execute, so it is the one leg that still needs emulation and it will dominate the wall clock. Dropping it would make the release fast outright, at the cost of older Raspberry Pi support — a separate decision.

Worth knowing before merging

This cannot be exercised without pushing a tag; there is no dry run for a tag-triggered workflow. The YAML and shell are verified with actionlint, but the push-by-digest to imagetools create path only runs for real on the next release. A throwaway tag on a fork would prove it first if that is worth the detour.

A partial failure now leaves untagged digests on Docker Hub rather than failing the whole build at once. Nothing can pull them by accident, but it is a change from the previous all-or-nothing behaviour, and it is noted in AGENTS.md.

Summary by CodeRabbit

  • New Features

    • Docker releases now support multiple CPU architectures, including AMD64, ARM64, and ARM/v7.
    • Published images include consolidated latest and versioned multi-architecture tags.
    • Added Raspberry Pi support through ARM/v7 images.
  • Documentation

    • Updated release documentation with build details and Raspberry Pi support considerations.

arm64 was emulated under QEMU on an x86 runner, which is where most of the
release time went. GitHub's arm64 runners are free for public repos, so amd64 and
arm64 now each build on their own architecture.

Platforms build in parallel and push untagged by digest; a merge job assembles them
into the tagged manifest. arm/v7 is 32-bit ARM that the 64-bit runners cannot
execute, so it stays emulated.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The release workflow now builds amd64, arm64, and arm/v7 images separately. It pushes each image by digest, then creates and verifies latest and versioned multi-architecture manifests.

Changes

Multi-architecture release workflow

Layer / File(s) Summary
Platform build matrix
.github/workflows/release.yml
Defines the global image name. Assigns native amd64 and arm64 runners. Uses QEMU for arm/v7 builds.
Digest-based platform builds
.github/workflows/release.yml
Builds one platform image per matrix job. Pushes each image by digest and uploads the digest as a short-lived artifact.
Manifest merge and release documentation
.github/workflows/release.yml, AGENTS.md
Downloads platform digests, creates latest and versioned manifests, verifies the versioned manifest, and documents the runner and QEMU assignments.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BuildMatrix
  participant DockerHub
  participant DigestArtifacts
  participant MergeJob
  BuildMatrix->>DockerHub: Build and push platform image by digest
  BuildMatrix->>DigestArtifacts: Upload platform digest
  MergeJob->>DigestArtifacts: Download platform digests
  MergeJob->>DockerHub: Create and verify multi-architecture manifests
Loading

Possibly related PRs

  • koel/docker#226: Both changes modify the release workflow, but this PR focuses on multi-architecture builds and manifest merging.
🚥 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 clearly summarizes the main workflow change: separate platform builds on native runners where possible.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch native-arm64-runner-for-image-builds

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.

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

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/release.yml:
- Around line 42-43: Update every third-party action reference in the release
workflow, including the checkout action named in the diff and the actions at the
listed workflow steps, from mutable version tags to verified full 40-character
commit SHAs. Preserve each action’s current version and behavior while ensuring
all release, registry, artifact, and manifest steps use immutable pinned
references.
🪄 Autofix

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 Plus

Run ID: aa1accd1-62e4-4b78-911e-15ffde99fd7e

📥 Commits

Reviewing files that changed from the base of the PR and between 6e58cfc and 6e801f1.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • AGENTS.md

Comment on lines 42 to 43
- name: Checkout code
uses: actions/checkout@v6

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

for action in \
  actions/checkout@v6 \
  docker/setup-qemu-action@v4 \
  docker/build-push-action@v7 \
  actions/upload-artifact@v4 \
  actions/download-artifact@v4 \
  docker/setup-buildx-action@v4 \
  docker/login-action@v4
do
  repo="${action%@*}"
  ref="${action#*@}"
  printf '%s@' "$repo"
  gh api "repos/$repo/commits/$ref" --jq '.sha'
done

Repository: koel/docker

Length of output: 600


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Release workflow action refs:\n'
rg -n 'uses:\s*[^#]+' .github/workflows/release.yml

printf '\nRelevant credential/job context:\n'
sed -n '1,150p' .github/workflows/release.yml

Repository: koel/docker

Length of output: 4696


Pin release workflow actions to full commit SHAs.

The release workflow runs Docker Hub login and publish steps from third-party actions tagged with mutable @vN refs. These action refs appear at .github/workflows/release.yml:18, 43, 52, 57, 60, 73, 88, 101, 108, 111; pin each one to a verified 40-character commit SHA so upstream tags cannot redirect build, registry login, artifact upload, or manifest merge code.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 42-43: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/release.yml around lines 42 - 43, Update every third-party
action reference in the release workflow, including the checkout action named in
the diff and the actions at the listed workflow steps, from mutable version tags
to verified full 40-character commit SHAs. Preserve each action’s current
version and behavior while ensuring all release, registry, artifact, and
manifest steps use immutable pinned references.

@phanan

phanan commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Not applying the SHA pinning here, though I agree with it in principle.

Eight of the ten flagged references already exist on mastercheckout, setup-qemu-action, setup-buildx-action, login-action and build-push-action are all unchanged by this PR, which only adds upload-artifact and download-artifact. Mutable tags are the convention across every workflow in this repo, including ci.yml and the composite action in .github/actions/test, which also builds and runs image code.

Pinning only release.yml would be the worst of both worlds: it would read as though the supply chain were locked down while ci.yml — which runs on every pull request, including from forks — still resolves mutable tags. And pinned SHAs go stale silently unless Dependabot is configured to bump them, which is a repo-level setup step rather than a line in this diff.

So this is a repo-wide policy change with its own decisions to make (all workflows, the composite action, Dependabot config for action SHAs), not a defect introduced here. Happy to do it as a follow-up PR if wanted.

On the artipacked sub-finding: persist-credentials: false would be harmless, but the warning does not apply here. It flags credentials leaking through uploaded artifacts, and the only artifacts this workflow uploads are empty marker files under /tmp/digests, named after image digests — the checkout workspace is never uploaded.

@phanan

phanan commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

Tested end to end against a throwaway image before merging. A scratch branch off this one pointed IMAGE_NAME at phanan/koel-ci-test and hardcoded the build arg to v9.11.1, then a v9.11.1-armtest tag triggered the workflow. The run succeeded and the tag, branch and Docker Hub repo have been cleaned up.

Measured

Job Runner Duration
Run tests ubuntu-24.04 2m31s
Build linux/arm64 ubuntu-24.04-arm 2m01s
Build linux/amd64 ubuntu-24.04 2m21s
Build linux/arm/v7 ubuntu-24.04 + QEMU 21m53s
Push the multi-arch manifest ubuntu-24.04 21s

Against the v9.11.1 release run on master for comparison: tests 2m29s, then a single Deploy to Docker Hub job of 28m39s. Whole workflow 31m12s before, 24m57s after — roughly 20% off the wall clock.

The merged manifest matches what the previous single-job path produced, three platforms plus the provenance attestations buildx attaches by default:

linux/arm64, linux/amd64, linux/arm/v7, and 3 unknown/unknown (attestations)

So push-by-digest into imagetools create is verified to produce an equivalent manifest, attestations included.

The honest read

The gain is real but modest, because linux/arm/v7 is now the entire release. amd64 and arm64 finish in about two minutes each; everything after that is 32-bit ARM emulation. Without v7 this workflow would complete in under three minutes rather than twenty-five.

That makes dropping linux/arm/v7 the change that would actually matter. It is a user-facing support decision rather than a CI one, so it belongs in its own PR — noted here because this run is what makes the case measurable.

@phanan
phanan merged commit 9bb9360 into master Aug 10, 2026
3 checks passed
@phanan
phanan deleted the native-arm64-runner-for-image-builds branch August 10, 2026 20:03
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