build each image platform on its own runner, natively where possible - #228
Conversation
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.
📝 WalkthroughWalkthroughThe release workflow now builds amd64, arm64, and arm/v7 images separately. It pushes each image by digest, then creates and verifies ChangesMulti-architecture release workflow
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
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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/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
📒 Files selected for processing (2)
.github/workflows/release.ymlAGENTS.md
| - name: Checkout code | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔒 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'
doneRepository: 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.ymlRepository: 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.
|
Not applying the SHA pinning here, though I agree with it in principle. Eight of the ten flagged references already exist on Pinning only 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 |
|
Tested end to end against a throwaway image before merging. A scratch branch off this one pointed Measured
Against the v9.11.1 release run on The merged manifest matches what the previous single-job path produced, three platforms plus the provenance attestations buildx attaches by default: So The honest readThe gain is real but modest, because That makes dropping |
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.linux/amd64ubuntu-24.04linux/arm64ubuntu-24.04-armlinux/arm/v7ubuntu-24.04linux/arm/v7is 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-digesttoimagetools createpath 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
latestand versioned multi-architecture tags.Documentation