Enhance Docker release workflow for multi-arch support#75
Enhance Docker release workflow for multi-arch support#75JaredHatfield merged 3 commits intomainfrom
Conversation
Updated the GitHub Actions workflow to support multi-architecture builds and added concurrency management.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #75 +/- ##
=====================================
Coverage 0.00% 0.00%
=====================================
Files 1 1
Lines 17 17
=====================================
Misses 17 17 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Updates the Docker release workflow to build and publish per-architecture images and then assemble/push a multi-arch manifest, adding repo-level concurrency control to manage overlapping Docker publish runs.
Changes:
- Convert the release Docker job to a matrix build (amd64/arm64) and publish arch-specific tags.
- Add a follow-up job to create/push a multi-arch manifest from the arch images.
- Move concurrency control to the workflow level.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| types: [published] | ||
|
|
||
| concurrency: | ||
| group: docker |
There was a problem hiding this comment.
concurrency.group is set to a constant (docker). Concurrency groups are global across the repo, so this will also serialize/queue runs from other workflows that use the same group (e.g., the dev Docker workflow), potentially delaying releases. Consider scoping the group to this workflow (and optionally the ref), e.g. ${{ github.workflow }}-${{ github.ref }} (and decide explicitly whether to set cancel-in-progress).
| group: docker | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true |
| TAGS: ${{ steps.meta.outputs.tags }} | ||
| run: | | ||
| IMAGE="ghcr.io/${REPO_LC}" | ||
| VERSION="${GITHUB_REF_NAME}" | ||
|
|
||
| TAG_ARGS="" | ||
| while IFS= read -r tag; do | ||
| [ -n "${tag}" ] && TAG_ARGS="${TAG_ARGS} -t ${tag}" | ||
| done <<< "${TAGS}" | ||
|
|
||
| docker buildx imagetools create \ | ||
| ${TAG_ARGS} \ |
There was a problem hiding this comment.
The build job’s tags are generated with pattern=v{{version}} (forcing a v prefix), but the manifest job later assumes the arch images are tagged as ${GITHUB_REF_NAME}-<arch>. If a release tag is 1.2.3 (no v), the build will push v1.2.3-amd64/arm64 while the manifest job will try to reference 1.2.3-amd64/arm64 and fail. Consider deriving the base version/tag consistently (e.g., from docker/metadata-action outputs) or removing the hard-coded v prefix from the patterns.
| "${IMAGE}:${VERSION}-amd64" \ | ||
| "${IMAGE}:${VERSION}-arm64" | ||
|
|
||
| docker buildx imagetools inspect "${IMAGE}:${VERSION}" |
There was a problem hiding this comment.
Digest extraction for the manifest is done by grepping/awking the human-readable output of docker buildx imagetools inspect, and grep -m1 can pick up the wrong digest if multiple Digest: lines are present (per-platform entries) or if the CLI output format changes. Prefer a machine-readable output/format flag (if available) and avoid parsing with grep|awk for correctness and long-term stability.
| docker buildx imagetools inspect "${IMAGE}:${VERSION}" | |
| DIGEST=$(docker buildx imagetools inspect "${IMAGE}:${VERSION}" --format '{{json .}}' | jq -r '.Digest') |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| DIGEST=$(docker buildx imagetools inspect "${IMAGE}:${META_VERSION}" --format '{{json .}}' | jq -r '.Digest') | ||
| echo "digest=${DIGEST}" >> $GITHUB_OUTPUT |
There was a problem hiding this comment.
The manifest job extracts the digest by piping JSON into jq, which introduces an extra tool dependency and can silently produce an empty/"null" digest if the format ever changes. Prefer using docker buildx imagetools inspect --format '{{.Digest}}' (or another Buildx-native format) and failing the step if the digest is empty before writing to $GITHUB_OUTPUT.
| DIGEST=$(docker buildx imagetools inspect "${IMAGE}:${META_VERSION}" --format '{{json .}}' | jq -r '.Digest') | |
| echo "digest=${DIGEST}" >> $GITHUB_OUTPUT | |
| DIGEST=$(docker buildx imagetools inspect "${IMAGE}:${META_VERSION}" --format '{{.Digest}}') | |
| if [ -z "${DIGEST}" ] || [ "${DIGEST}" = "null" ]; then | |
| echo "Failed to determine image digest for ${IMAGE}:${META_VERSION}" >&2 | |
| exit 1 | |
| fi | |
| echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" |
Updated the GitHub Actions workflow to support multi-architecture builds and added concurrency management.