Skip to content

Commit 4c88a6c

Browse files
committed
ci: use native runners matrix to eliminate QEMU overhead
Thanks to https://github.com/sredevopsorg/multi-arch-docker-github-workflow Signed-off-by: rizlas <rizlas@users.noreply.github.com>
1 parent 8d9a98d commit 4c88a6c

1 file changed

Lines changed: 105 additions & 11 deletions

File tree

.github/workflows/docker-image.yml

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Inspired by https://github.com/sredevopsorg/multi-arch-docker-github-workflow
12
name: Docker Image CI
23

34
on:
@@ -11,13 +12,22 @@ on:
1112
required: false
1213

1314
jobs:
14-
build-and-push:
15-
runs-on: ubuntu-latest
15+
build:
16+
runs-on: ${{ matrix.runner }}
1617

1718
permissions:
1819
contents: read
1920
packages: write
2021

22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
include:
26+
- platform: linux/amd64
27+
runner: ubuntu-latest
28+
- platform: linux/arm64
29+
runner: ubuntu-24.04-arm
30+
2131
steps:
2232
- name: Checkout code
2333
uses: actions/checkout@v6
@@ -32,9 +42,6 @@ jobs:
3242
username: ${{ github.actor }}
3343
password: ${{ secrets.GITHUB_TOKEN }}
3444

35-
- name: Set up QEMU
36-
uses: docker/setup-qemu-action@v4
37-
3845
- name: Set up Docker Buildx
3946
uses: docker/setup-buildx-action@v4
4047

@@ -55,13 +62,100 @@ jobs:
5562
type=raw,value=latest
5663
type=raw,value=${{ steps.tag.outputs.value }},enable=${{ inputs.upstream_tag != '' }}
5764
58-
- name: Build and push
65+
- name: Build and push by digest
66+
id: build
5967
uses: docker/build-push-action@v7
6068
with:
6169
context: .
62-
push: true
63-
platforms: linux/amd64,linux/arm64
64-
tags: ${{ steps.meta.outputs.tags }}
70+
platforms: ${{ matrix.platform }}
6571
labels: ${{ steps.meta.outputs.labels }}
66-
cache-from: type=gha
67-
cache-to: type=gha,mode=max
72+
outputs: type=image,name=ghcr.io/${{ github.repository }},push-by-digest=true,name-canonical=true,push=true
73+
cache-from: type=gha,scope=${{ matrix.platform }}
74+
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
75+
76+
- name: Export digest
77+
run: |
78+
mkdir -p /tmp/digests
79+
touch "/tmp/digests/${DIGEST#sha256:}"
80+
env:
81+
DIGEST: ${{ steps.build.outputs.digest }}
82+
83+
- name: Upload digest
84+
uses: actions/upload-artifact@v4
85+
with:
86+
name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
87+
path: /tmp/digests/*
88+
if-no-files-found: error
89+
retention-days: 1
90+
91+
merge:
92+
runs-on: ubuntu-latest
93+
needs: build
94+
95+
permissions:
96+
contents: read
97+
packages: write
98+
99+
steps:
100+
- name: Download digests
101+
uses: actions/download-artifact@v4
102+
with:
103+
path: /tmp/digests
104+
pattern: digests-*
105+
merge-multiple: true
106+
107+
- name: Log in to GitHub Packages
108+
uses: docker/login-action@v4
109+
with:
110+
registry: ghcr.io
111+
username: ${{ github.actor }}
112+
password: ${{ secrets.GITHUB_TOKEN }}
113+
114+
- name: Set up Docker Buildx
115+
uses: docker/setup-buildx-action@v4
116+
117+
- name: Sanitize upstream tag
118+
if: inputs.upstream_tag != ''
119+
id: tag
120+
run: echo "value=${INPUT_TAG#v}" >> $GITHUB_OUTPUT
121+
env:
122+
INPUT_TAG: ${{ inputs.upstream_tag }}
123+
124+
- name: Extract metadata
125+
id: meta
126+
uses: docker/metadata-action@v6
127+
with:
128+
images: ghcr.io/${{ github.repository }}
129+
tags: |
130+
type=ref,event=tag
131+
type=raw,value=latest
132+
type=raw,value=${{ steps.tag.outputs.value }},enable=${{ inputs.upstream_tag != '' }}
133+
134+
- name: Get timestamp
135+
id: timestamp
136+
run: echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
137+
138+
- name: Create and push manifest
139+
id: manifest
140+
working-directory: /tmp/digests
141+
continue-on-error: true
142+
run: |
143+
docker buildx imagetools create \
144+
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
145+
--annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \
146+
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \
147+
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \
148+
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \
149+
$(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *)
150+
151+
- name: Create and push manifest (without annotations)
152+
if: steps.manifest.outcome == 'failure'
153+
working-directory: /tmp/digests
154+
run: |
155+
docker buildx imagetools create \
156+
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
157+
$(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *)
158+
159+
- name: Inspect manifest
160+
run: |
161+
docker buildx imagetools inspect 'ghcr.io/${{ github.repository }}:${{ steps.meta.outputs.version }}'

0 commit comments

Comments
 (0)