Skip to content

Commit c2a99c1

Browse files
Use native runners to build Docker images (#451)
Instead of relying on QEMU emulation to build multi-arch images, use native arm64 and amd64 build runners to build architecture-specific images, then publish multi-arch metadata with each of the image manifests. Signed-off-by: Mark S. Lewis <[email protected]>
1 parent da27c6a commit c2a99c1

File tree

1 file changed

+83
-39
lines changed

1 file changed

+83
-39
lines changed

.github/workflows/release.yaml

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ name: Release
66
on:
77
push:
88
tags:
9-
- "v2.*"
10-
workflow_dispatch:
9+
- "v[0-9]+.[0-9]+.[0-9]+"
10+
- "v[0-9]+.[0-9]+.[0-9]+-*"
11+
12+
env:
13+
IMAGE_NAME: ${{ github.repository_owner }}/fabric-nodeenv
1114

1215
jobs:
1316
test:
@@ -33,60 +36,101 @@ jobs:
3336
env:
3437
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
3538
36-
publishdocker:
37-
runs-on: ubuntu-latest
39+
docker-build-push:
40+
name: Push Docker image
3841
needs: test
42+
runs-on: ${{ matrix.arch.runner }}
3943
permissions:
4044
contents: read
4145
packages: write
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
arch:
50+
- platform: linux-amd64
51+
runner: ubuntu-24.04
52+
- platform: linux-arm64
53+
runner: ubuntu-24.04-arm
4254
steps:
43-
- name: Set up QEMU
44-
uses: docker/setup-qemu-action@v3
45-
- name: Set up Docker Buildx
46-
uses: docker/setup-buildx-action@v3
55+
- uses: actions/checkout@v4
56+
- name: Get commit timestamp
57+
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}"
58+
- name: Login to GitHub Container Registry
59+
uses: docker/login-action@v3
4760
with:
48-
buildkitd-flags: --debug
49-
buildkitd-config-inline: |
50-
[worker.oci]
51-
max-parallelism = 1
52-
- name: Checkout
53-
uses: actions/checkout@v4
61+
registry: ghcr.io
62+
username: ${{ github.actor }}
63+
password: ${{ secrets.GITHUB_TOKEN }}
5464
- name: Login to Docker Hub
55-
# If testing on a fork, login error may occur and can be ignored
56-
continue-on-error: true
65+
if: ${{ github.repository_owner == 'hyperledger' }}
5766
uses: docker/login-action@v3
5867
with:
68+
registry: docker.io
5969
username: ${{ secrets.DOCKERHUB_USERNAME }}
6070
password: ${{ secrets.DOCKERHUB_TOKEN }}
61-
- name: Login to GitHub Container Registry
71+
- name: Set up Docker Buildx
72+
uses: docker/setup-buildx-action@v3
73+
- name: Build image
74+
id: build
75+
uses: docker/build-push-action@v6
76+
with:
77+
file: docker/fabric-nodeenv/Dockerfile
78+
context: docker/fabric-nodeenv
79+
outputs: type=registry,name=${{ env.OUTPUT_NAME }},push-by-digest=true,name-canonical=true
80+
env:
81+
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
82+
OUTPUT_NAME: ${{ github.repository_owner == 'hyperledger' && format('ghcr.io/{0},docker.io/{0}', env.IMAGE_NAME) || format('ghcr.io/{0}', env.IMAGE_NAME) }}
83+
- name: Export digest
84+
run: |
85+
mkdir -p ${{ runner.temp }}/digests
86+
digest="${{ steps.build.outputs.digest }}"
87+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
88+
- name: Upload digest
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: digest-${{ matrix.arch.platform }}
92+
path: ${{ runner.temp }}/digests/*
93+
if-no-files-found: error
94+
95+
docker-meta:
96+
needs: docker-build-push
97+
name: Publish Docker metadata
98+
runs-on: ubuntu-latest
99+
permissions:
100+
contents: read
101+
packages: write
102+
strategy:
103+
fail-fast: false
104+
matrix:
105+
registry: ${{ fromJSON(github.repository_owner == 'hyperledger' && '["docker.io", "ghcr.io"]' || '["ghcr.io"]') }}
106+
steps:
107+
- name: Download digests
108+
uses: actions/download-artifact@v4
109+
with:
110+
path: ${{ runner.temp }}/digests
111+
pattern: digest-*
112+
merge-multiple: true
113+
- name: Login to ${{ matrix.registry }}
62114
uses: docker/login-action@v3
63115
with:
64-
registry: ghcr.io
65-
username: ${{ github.repository_owner }}
66-
password: ${{ secrets.GITHUB_TOKEN }}
67-
- name: Docker meta
116+
registry: ${{ matrix.registry }}
117+
username: ${{ matrix.registry == 'docker.io' && secrets.DOCKERHUB_USERNAME || github.actor }}
118+
password: ${{ matrix.registry == 'docker.io' && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }}
119+
- name: Docker metadata
68120
id: meta
69121
uses: docker/metadata-action@v5
70122
with:
71-
# If testing on a fork, Docker Hub publish might fail so place it last
72-
images: |
73-
ghcr.io/${{ github.repository_owner }}/fabric-nodeenv
74-
docker.io/${{ github.repository_owner }}/fabric-nodeenv
123+
images: ${{ matrix.registry }}/${{ env.IMAGE_NAME }}
75124
tags: |
76125
type=semver,pattern={{version}}
77126
type=semver,pattern={{major}}.{{minor}}
78127
type=semver,pattern={{major}}.{{minor}}.{{patch}}
79-
- name: Get Git commit timestamps
80-
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
81-
- name: Build and push image
82-
id: push
83-
uses: docker/build-push-action@v6
84-
with:
85-
platforms: linux/amd64,linux/arm64
86-
file: docker/fabric-nodeenv/Dockerfile
87-
context: docker/fabric-nodeenv
88-
tags: ${{ steps.meta.outputs.tags }}
89-
push: ${{ github.event_name != 'pull_request' }}
90-
labels: ${{ steps.meta.outputs.labels }}
91-
env:
92-
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
128+
- name: Set up Docker Buildx
129+
uses: docker/setup-buildx-action@v3
130+
- name: Create and push manifest list
131+
working-directory: ${{ runner.temp }}/digests
132+
run: |
133+
docker buildx imagetools create $(jq -cr '.tags | map("--tag " + .) | join(" ")' <<< "${DOCKER_METADATA_OUTPUT_JSON}") \
134+
$(printf '${{ matrix.registry }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
135+
- name: Inspect image
136+
run: docker buildx imagetools inspect '${{ matrix.registry }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}'

0 commit comments

Comments
 (0)