Skip to content

ci: build release Docker images natively per-arch, merge with a manifest#235

Merged
kevincodex1 merged 2 commits into
mainfrom
ci/docker-native-arm
Jul 22, 2026
Merged

ci: build release Docker images natively per-arch, merge with a manifest#235
kevincodex1 merged 2 commits into
mainfrom
ci/docker-native-arm

Conversation

@kevincodex1

@kevincodex1 kevincodex1 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

The v0.6.0 release run's multi-arch Docker build wedged for 3+ hours emulating the arm64 Rust release build under QEMU, and — because the workflow concurrency group is cancel-in-progress:false — every queued release run sat blocked behind it.

  • docker is now a matrix: amd64 on ubuntu-latest, arm64 on ubuntu-24.04-arm — both native, mirroring release-binaries. Each leg smoke-tests the image (--version must report the released version) and pushes by digest only.
  • docker-manifest stitches the digests into the :X.Y.Z, :X.Y and :latest tags with buildx imagetools, so a half-finished matrix can never publish a partially-tagged image.
  • workflow_dispatch grows docker_backfill_tag (and npm_backfill_tag becomes optional): each channel backfills independently for an already-cut release — needed to publish the missing v0.6.0 image.

Summary by CodeRabbit

  • New Features
    • Added safer manual release backfill options for npm and Docker tags (with optional Docker backfill tagging).
    • Docker releases now build natively for AMD64 and ARM64.
    • Added architecture-specific smoke testing before publishing images.
    • Multi-architecture Docker manifests are assembled only after validating both platform images.
  • Chores
    • Reworked the Docker publishing flow to remove prior emulation-based steps and improve manual dispatch gating.

The v0.6.0 release run's multi-arch Docker build wedged for 3+ hours
emulating the arm64 Rust release build under QEMU, and — because the
workflow concurrency group is cancel-in-progress:false — every queued
release run sat blocked behind it.

- docker is now a matrix: amd64 on ubuntu-latest, arm64 on
  ubuntu-24.04-arm — both native, mirroring release-binaries. Each leg
  smoke-tests the image (--version must report the released version)
  and pushes by digest only.
- docker-manifest stitches the digests into the :X.Y.Z, :X.Y and
  :latest tags with buildx imagetools, so a half-finished matrix can
  never publish a partially-tagged image.
- workflow_dispatch grows docker_backfill_tag (and npm_backfill_tag
  becomes optional): each channel backfills independently for an
  already-cut release — needed to publish the missing v0.6.0 image.
@github-actions github-actions Bot added the needs-issue PR has no linked issue label Jul 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the contribution. A couple of things will help us review this faster:

  • Link the issue this addresses (Closes #123). For protocol changes, open an issue first.

See CONTRIBUTING.md. Update the PR and these notes will clear automatically.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3e31f065-0171-48e8-9e4e-b16fdc1e0661

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The release workflow now supports independent npm and Docker backfill tags. Docker images build natively for amd64 and arm64, undergo smoke tests, publish by digest, and are combined into multi-architecture manifests.

Changes

Docker release backfill

Layer / File(s) Summary
Backfill inputs and tag resolution
.github/workflows/release.yml
Manual dispatch accepts optional npm and Docker backfill tags; Docker jobs validate and resolve the selected release tag.
Native architecture builds and digest exports
.github/workflows/release.yml
A native amd64/arm64 matrix builds and smoke-tests images, then publishes architecture-specific digests as artifacts.
Multi-architecture manifest assembly
.github/workflows/release.yml
A dedicated job downloads both digests and publishes VERSION, MAJOR.MINOR, and latest multi-architecture tags.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ManualDispatch
  participant NativeDockerRunners
  participant DigestArtifacts
  participant ContainerRegistry
  ManualDispatch->>NativeDockerRunners: resolve release or Docker backfill tag
  NativeDockerRunners->>NativeDockerRunners: build and smoke-test amd64 and arm64 images
  NativeDockerRunners->>ContainerRegistry: push architecture-specific images by digest
  NativeDockerRunners->>DigestArtifacts: upload architecture digests
  DigestArtifacts->>ContainerRegistry: provide digests to docker-manifest
  ContainerRegistry->>ContainerRegistry: publish multi-architecture release tags
Loading

Possibly related PRs

  • Gitlawb/node#233: Updates the same release workflow for manual backfill publishing and npm backfill handling.

Suggested reviewers: beardthelion

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: native per-arch Docker release builds and manifest merging.
Description check ✅ Passed The description covers the summary, motivation, and concrete changes, though it omits some template sections like verification steps.
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 ci/docker-native-arm

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

81-101: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated tag-resolution/validation script across docker and docker-manifest. Both jobs independently parse and validate docker_backfill_tag/tag_name with the exact same bash. This duplication likely exists because matrix-job outputs are unreliable in GitHub Actions (needs.docker.outputs.* from a matrix job is nondeterministic), but the logic itself doesn't need to live in a matrix leg — hoisting it to a small upstream job removes the duplication risk entirely.

  • .github/workflows/release.yml#L81-L101: replace this inline resolution with a needs: resolve-tag dependency and consume needs.resolve-tag.outputs.tag for the checkout ref.
  • .github/workflows/release.yml#L174-L188: replace this inline resolution with the same needs.resolve-tag.outputs.tag/.version consumption instead of re-running the parsing script.

Introduce a single upstream job, e.g.:

  resolve-tag:
    name: Resolve release tag
    needs: release-please
    if: ${{ !cancelled() && (needs.release-please.outputs.release_created == 'true' || (github.event_name == 'workflow_dispatch' && (inputs.docker_backfill_tag != '' ))) }}
    runs-on: ubuntu-latest
    outputs:
      tag: ${{ steps.rel.outputs.tag }}
      version: ${{ steps.rel.outputs.version }}
    steps:
      - name: Resolve release tag
        id: rel
        env:
          DISPATCH_TAG: ${{ inputs.docker_backfill_tag }}
          RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }}
        run: |
          set -euo pipefail
          TAG="${DISPATCH_TAG:-$RELEASE_TAG}"
          case "$TAG" in
            v[0-9]*) ;;
            *) echo "::error::'$TAG' does not look like a release tag (vX.Y.Z)"; exit 1 ;;
          esac
          echo "tag=$TAG" >> "$GITHUB_OUTPUT"
          echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
🤖 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 81 - 101, Hoist the shared tag
resolution and validation into a single upstream resolve-tag job dependent on
release-please, exposing tag and version outputs while preserving the existing
execution condition. In .github/workflows/release.yml lines 81-101, add the
resolve-tag dependency and consume needs.resolve-tag.outputs.tag for checkout;
apply the same dependency and consume needs.resolve-tag.outputs.tag/version in
lines 174-188, removing both duplicated inline scripts.
🤖 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 139-148: The image output configured in the “Build and push by
digest” step uses a mixed-case repository path. Update its GHCR image reference
to use the lowercased repository value via ${GITHUB_REPOSITORY,,} (or the
existing lowercase prep-step output), matching the manifest job’s target while
preserving the current digest and push options.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 81-101: Hoist the shared tag resolution and validation into a
single upstream resolve-tag job dependent on release-please, exposing tag and
version outputs while preserving the existing execution condition. In
.github/workflows/release.yml lines 81-101, add the resolve-tag dependency and
consume needs.resolve-tag.outputs.tag for checkout; apply the same dependency
and consume needs.resolve-tag.outputs.tag/version in lines 174-188, removing
both duplicated inline scripts.
🪄 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: e66652a9-7fce-4c5c-a39f-d12bd88a50bf

📥 Commits

Reviewing files that changed from the base of the PR and between ccc2cf4 and 7593540.

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

Comment thread .github/workflows/release.yml
@beardthelion beardthelion added the kind:ci CI, release, or packaging pipeline label Jul 22, 2026
buildx's --output name= does no lowercasing (unlike metadata-action),
so ghcr.io/Gitlawb/node is an invalid reference and the per-arch digest
push would fail outright. Compute the lowercase image once in the
resolve step and reuse it, matching the manifest job.
@kevincodex1

Copy link
Copy Markdown
Contributor Author

hey @coderabbitai please review and approve if its all good!

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@kevincodex1 I’ll review #235, including the native amd64/arm64 build and manifest-publishing flow, and approve it if no issues are found.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind:ci CI, release, or packaging pipeline needs-issue PR has no linked issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants