Skip to content

Commit 9235087

Browse files
authored
feat(ci): use multiple runners for build (#508)
1 parent 7c066e9 commit 9235087

File tree

1 file changed

+204
-33
lines changed

1 file changed

+204
-33
lines changed

.github/workflows/build.yml

Lines changed: 204 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ name: build
33
on:
44
push:
55
branches:
6-
- "main"
7-
- "feature-*"
8-
- "bug-*"
6+
- main
97
paths:
108
- "src/**"
119
- "Dockerfile"
@@ -16,16 +14,31 @@ on:
1614
workflow_dispatch:
1715

1816
permissions:
17+
attestations: write
1918
contents: read
2019
id-token: write
2120
packages: write
2221

2322
jobs:
2423
build:
25-
runs-on: ubuntu-latest
26-
outputs:
27-
docker_build_digest: ${{ steps.docker_build.outputs.digest }}
28-
docker_meta_version: ${{ steps.docker_meta.outputs.version }}
24+
name: build (${{ matrix.platform }})
25+
runs-on: ${{ matrix.runner }}
26+
if: github.event_name != 'pull_request'
27+
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
include:
32+
- runner: ubuntu-24.04
33+
platform: linux/amd64
34+
arch: x86_64
35+
- runner: ubuntu-24.04-arm
36+
platform: linux/arm64
37+
arch: aarch64
38+
- runner: ubuntu-24.04-arm
39+
platform: linux/arm/v7
40+
arch: armv7
41+
2942
steps:
3043
- name: Checkout
3144
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
@@ -35,73 +48,220 @@ jobs:
3548
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f #v5.8.0
3649
with:
3750
images: |
38-
tibiadata/tibiadata-api-go
39-
ghcr.io/tibiadata/tibiadata-api-go
51+
${{ github.repository }}
52+
ghcr.io/${{ github.repository }}
4053
tags: |
4154
type=edge
42-
type=ref,event=branch,enable=${{ (github.ref != 'refs/heads/main') }}
55+
type=ref,event=branch,enable={{is_not_default_branch}}
4356
type=semver,pattern={{version}}
4457
type=semver,pattern={{major}}
4558
type=semver,pattern={{major}}.{{minor}}
4659
env:
4760
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
4861

49-
- name: Install Cosign
50-
if: github.event_name != 'pull_request'
51-
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 #v3.10.0
52-
53-
- name: Set up QEMU
62+
- name: Set up QEMU (${{ matrix.platform }})
63+
if: matrix.platform == 'linux/arm/v7'
5464
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 #v3.6.0
65+
with:
66+
platforms: ${{ matrix.platform }}
5567

5668
- name: Set up Docker Buildx
5769
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
5870

5971
- name: Login to DockerHub
60-
if: github.event_name != 'pull_request'
6172
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
6273
with:
6374
username: ${{ secrets.DOCKERHUB_USERNAME }}
6475
password: ${{ secrets.DOCKERHUB_TOKEN }}
6576

6677
- name: Login to GitHub Container Registry
67-
if: github.event_name != 'pull_request'
6878
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
6979
with:
7080
registry: ghcr.io
7181
username: ${{ github.actor }}
7282
password: ${{ secrets.GITHUB_TOKEN }}
7383

74-
- name: Build and push
84+
- name: Build and push (${{ matrix.platform }})
7585
id: docker_build
7686
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
7787
with:
7888
context: .
79-
platforms: linux/amd64,linux/arm/v7,linux/arm64
80-
push: ${{ github.event_name != 'pull_request' }}
89+
platforms: ${{ matrix.platform }}
90+
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
8191
annotations: ${{ steps.docker_meta.outputs.annotations }}
8292
labels: ${{ steps.docker_meta.outputs.labels }}
83-
tags: ${{ steps.docker_meta.outputs.tags }}
84-
cache-from: type=gha
85-
cache-to: type=gha,mode=max
93+
tags: |
94+
${{ github.repository }}
95+
ghcr.io/${{ github.repository }}
96+
cache-from: type=gha,scope=${{ matrix.platform }}
97+
cache-to: type=gha,scope=${{ matrix.platform }},mode=max
8698
sbom: true
8799
build-args: |
88100
TibiaDataBuildBuilder=github
89101
TibiaDataBuildRelease=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.version'] }}
90102
TibiaDataBuildCommit=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }}
91103
92-
- name: Sign the images (with GitHub OIDC Token)
93-
if: github.event_name != 'pull_request'
104+
- name: Export digest
105+
run: |
106+
mkdir -p ${{ runner.temp }}/digests
107+
digest="${{ steps.docker_build.outputs.digest }}"
108+
touch "${{ runner.temp }}/digests/${digest#sha256:}"
109+
110+
- name: Upload digest
111+
id: upload_digests
112+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2
113+
with:
114+
name: digests-${{ matrix.arch }}
115+
path: ${{ runner.temp }}/digests/*
116+
if-no-files-found: error
117+
retention-days: 1
118+
119+
- name: Attest digest (per-arch)
120+
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a #v3.0.0
121+
with:
122+
subject-name: digests-${{ matrix.arch }}
123+
subject-digest: sha256:${{ steps.upload_digests.outputs.artifact-digest }}
124+
125+
manifest:
126+
name: build (multi-arch)
127+
runs-on: ubuntu-latest
128+
needs:
129+
- build
130+
131+
outputs:
132+
docker_build_digest: ${{ steps.docker_build.outputs.digest }}
133+
docker_meta_version: ${{ steps.docker_meta.outputs.version }}
134+
135+
steps:
136+
- name: Checkout
137+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
138+
139+
- name: Docker meta
140+
id: docker_meta
141+
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f #v5.8.0
142+
with:
143+
images: |
144+
${{ github.repository }}
145+
ghcr.io/${{ github.repository }}
146+
tags: |
147+
type=edge
148+
type=ref,event=branch,enable={{is_not_default_branch}}
149+
type=semver,pattern={{version}}
150+
type=semver,pattern={{major}}
151+
type=semver,pattern={{major}}.{{minor}}
152+
env:
153+
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
154+
155+
- name: Download digests
156+
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0
157+
with:
158+
path: ${{ runner.temp }}/digests
159+
pattern: digests-*
160+
merge-multiple: true
161+
162+
- name: Install Cosign
163+
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 #v3.10.0
164+
165+
- name: Set up Docker Buildx
166+
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
167+
168+
- name: Login to DockerHub
169+
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
170+
with:
171+
username: ${{ secrets.DOCKERHUB_USERNAME }}
172+
password: ${{ secrets.DOCKERHUB_TOKEN }}
173+
174+
- name: Login to GitHub Container Registry
175+
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
176+
with:
177+
registry: ghcr.io
178+
username: ${{ github.actor }}
179+
password: ${{ secrets.GITHUB_TOKEN }}
180+
181+
- name: Create manifest list and push
182+
id: docker_build
183+
working-directory: ${{ runner.temp }}/digests
184+
run: |
185+
# Create the manifest list and push to both registries
186+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
187+
--annotation "index:org.opencontainers.image.created=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.created'] }}" \
188+
--annotation "index:org.opencontainers.image.description=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.description'] }}" \
189+
--annotation "index:org.opencontainers.image.licenses=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.licenses'] }}" \
190+
--annotation "index:org.opencontainers.image.revision=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }}" \
191+
--annotation "index:org.opencontainers.image.source=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.source'] }}" \
192+
--annotation "index:org.opencontainers.image.version=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.version'] }}" \
193+
$(printf '${{ github.repository }}@sha256:%s ' *) \
194+
$(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *)
195+
196+
# Get the digest of the created manifest list
197+
DIGEST=$(docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json .Manifest.Digest }}' | jq -r .)
198+
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
199+
200+
- name: Attest docker build (DockerHub)
201+
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a #v3.0.0
202+
with:
203+
subject-name: index.docker.io/${{ github.repository }}
204+
subject-digest: ${{ steps.docker_build.outputs.digest }}
205+
push-to-registry: true
206+
207+
- name: Attest docker build (GitHub Container Registry)
208+
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a #v3.0.0
209+
with:
210+
subject-name: ghcr.io/${{ github.repository }}
211+
subject-digest: ${{ steps.docker_build.outputs.digest }}
212+
push-to-registry: true
213+
214+
- name: Cosign sign images (GitHub OIDC)
215+
run: |
216+
cosign sign --yes \
217+
${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
218+
219+
cosign sign --yes \
220+
ghcr.io/${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
221+
222+
- name: Inspect images (GitHub Container Registry)
223+
run: |
224+
docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }}
225+
226+
echo "::group::Manifest"
227+
docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json .Manifest }}'
228+
echo "::endgroup::"
229+
230+
echo "::group::Image (linux/amd64)"
231+
docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .Image "linux/amd64") }}'
232+
echo "::endgroup::"
233+
234+
echo "::group::Provenance (linux/amd64)"
235+
docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .Provenance "linux/amd64") }}'
236+
echo "::endgroup::"
237+
238+
echo "::group::SBOM (linux/amd64)"
239+
docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .SBOM "linux/amd64") }}'
240+
echo "::endgroup::"
241+
242+
- name: Verify cosign signatures
94243
run: |
95-
cosign sign --yes --recursive \
96-
tibiadata/tibiadata-api-go@${{ steps.docker_build.outputs.digest }}
244+
echo "::group::Verify signature (DockerHub)"
245+
cosign verify --rekor-url https://rekor.sigstore.dev \
246+
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
247+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
248+
${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
249+
echo "::endgroup::"
97250
98-
cosign sign --yes --recursive \
99-
ghcr.io/tibiadata/tibiadata-api-go@${{ steps.docker_build.outputs.digest }}
251+
echo "::group::Verify signature (GitHub Container Registry)"
252+
cosign verify --rekor-url https://rekor.sigstore.dev \
253+
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
254+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
255+
ghcr.io/${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
256+
echo "::endgroup::"
100257
101258
argocd:
102259
if: github.event_name == 'release' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
103260
runs-on: ubuntu-latest
104-
needs: build
261+
needs:
262+
- build
263+
- manifest
264+
105265
steps:
106266
- name: Determine the deployment subdomain
107267
id: determine_deployment
@@ -118,19 +278,30 @@ jobs:
118278
token: ${{ secrets.REPO_ACCESS_TOKEN }}
119279
repository: tibiadata/tibiadata-argocd-app-of-apps
120280
event-type: bump-tibiadata-api-go-image-sha
121-
client-payload: '{"docker_digest": "${{ needs.build.outputs.docker_build_digest }}", "subdomain": "${{ steps.determine_deployment.outputs.subdomain }}"}'
281+
client-payload: |-
282+
{
283+
"docker_digest": "${{ needs.manifest.outputs.docker_build_digest }}",
284+
"subdomain": "${{ steps.determine_deployment.outputs.subdomain }}"
285+
}
122286
123287
helm-chart:
124288
if: github.event_name == 'release'
125289
permissions:
126290
contents: write
127291
runs-on: ubuntu-latest
128-
needs: build
292+
needs:
293+
- build
294+
- manifest
295+
129296
steps:
130297
- name: Trigger workflow in tibiadata-helm-charts repo
131298
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 #v3.0.0
132299
with:
133300
token: ${{ secrets.REPO_ACCESS_TOKEN }}
134301
repository: tibiadata/tibiadata-helm-charts
135302
event-type: bump-helm-chart-release
136-
client-payload: '{"chart_name": "${{ github.event.repository.name }}", "release_version": "${{ needs.build.outputs.docker_meta_version }}"}'
303+
client-payload: |-
304+
{
305+
"chart_name": "${{ github.event.repository.name }}",
306+
"release_version": "${{ needs.manifest.outputs.docker_meta_version }}"
307+
}

0 commit comments

Comments
 (0)