@@ -3,9 +3,7 @@ name: build
33on :
44 push :
55 branches :
6- - " main"
7- - " feature-*"
8- - " bug-*"
6+ - main
97 paths :
108 - " src/**"
119 - " Dockerfile"
1614 workflow_dispatch :
1715
1816permissions :
17+ attestations : write
1918 contents : read
2019 id-token : write
2120 packages : write
2221
2322jobs :
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+
27+ strategy :
28+ fail-fast : false
29+ matrix :
30+ include :
31+ - runner : ubuntu-24.04
32+ platform : linux/amd64
33+ arch : x86_64
34+ - runner : ubuntu-24.04-arm
35+ platform : linux/arm64
36+ arch : aarch64
37+ - runner : ubuntu-24.04-arm
38+ platform : linux/arm/v7
39+ arch : armv7
40+
2941 steps :
3042 - name : Checkout
3143 uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -35,73 +47,220 @@ jobs:
3547 uses : docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
3648 with :
3749 images : |
38- tibiadata/tibiadata-api-go
39- ghcr.io/tibiadata/tibiadata-api-go
50+ ${{ github.repository }}
51+ ghcr.io/${{ github.repository }}
4052 tags : |
4153 type=edge
42- type=ref,event=branch,enable=${{ (github.ref != 'refs/heads/main') }}
54+ type=ref,event=branch,enable={{is_not_default_branch }}
4355 type=semver,pattern={{version}}
4456 type=semver,pattern={{major}}
4557 type=semver,pattern={{major}}.{{minor}}
4658 env :
4759 DOCKER_METADATA_ANNOTATIONS_LEVELS : manifest,index
4860
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
61+ - name : Set up QEMU (${{ matrix.platform }})
62+ if : matrix.platform == 'linux/arm/v7'
5463 uses : docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
64+ with :
65+ platforms : ${{ matrix.platform }}
5566
5667 - name : Set up Docker Buildx
5768 uses : docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
5869
5970 - name : Login to DockerHub
60- if : github.event_name != 'pull_request'
6171 uses : docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
6272 with :
6373 username : ${{ secrets.DOCKERHUB_USERNAME }}
6474 password : ${{ secrets.DOCKERHUB_TOKEN }}
6575
6676 - name : Login to GitHub Container Registry
67- if : github.event_name != 'pull_request'
6877 uses : docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
6978 with :
7079 registry : ghcr.io
7180 username : ${{ github.actor }}
7281 password : ${{ secrets.GITHUB_TOKEN }}
7382
74- - name : Build and push
83+ - name : Build and push (${{ matrix.platform }})
7584 id : docker_build
7685 uses : docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
7786 with :
7887 context : .
79- platforms : linux/amd64,linux/arm/v7,linux/arm64
80- push : ${{ github.event_name != 'pull_request' }}
88+ platforms : ${{ matrix.platform }}
89+ outputs : type=image,push-by-digest=true,name-canonical=true,push=true
8190 annotations : ${{ steps.docker_meta.outputs.annotations }}
8291 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
92+ tags : |
93+ ${{ github.repository }}
94+ ghcr.io/${{ github.repository }}
95+ cache-from : type=gha,scope=${{ matrix.platform }}
96+ cache-to : type=gha,scope=${{ matrix.platform }},mode=max
8697 sbom : true
8798 build-args : |
8899 TibiaDataBuildBuilder=github
89100 TibiaDataBuildRelease=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.version'] }}
90101 TibiaDataBuildCommit=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }}
91102
92- - name : Sign the images (with GitHub OIDC Token)
93- if : github.event_name != 'pull_request'
103+ - name : Export digest
104+ run : |
105+ mkdir -p ${{ runner.temp }}/digests
106+ digest="${{ steps.docker_build.outputs.digest }}"
107+ touch "${{ runner.temp }}/digests/${digest#sha256:}"
108+
109+ - name : Upload digest
110+ id : upload_digests
111+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
112+ with :
113+ name : digests-${{ matrix.arch }}
114+ path : ${{ runner.temp }}/digests/*
115+ if-no-files-found : error
116+ retention-days : 1
117+
118+ - name : Attest digest (per-arch)
119+ uses : actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
120+ with :
121+ subject-name : digests-${{ matrix.arch }}
122+ subject-digest : sha256:${{ steps.upload_digests.outputs.artifact-digest }}
123+
124+ manifest :
125+ name : build (multi-arch)
126+ runs-on : ubuntu-latest
127+ needs :
128+ - build
129+
130+ outputs :
131+ docker_build_digest : ${{ steps.docker_build.outputs.digest }}
132+ docker_meta_version : ${{ steps.docker_meta.outputs.version }}
133+
134+ steps :
135+ - name : Checkout
136+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
137+
138+ - name : Docker meta
139+ id : docker_meta
140+ uses : docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
141+ with :
142+ images : |
143+ ${{ github.repository }}
144+ ghcr.io/${{ github.repository }}
145+ tags : |
146+ type=edge
147+ type=ref,event=branch,enable={{is_not_default_branch}}
148+ type=semver,pattern={{version}}
149+ type=semver,pattern={{major}}
150+ type=semver,pattern={{major}}.{{minor}}
151+ env :
152+ DOCKER_METADATA_ANNOTATIONS_LEVELS : manifest,index
153+
154+ - name : Download digests
155+ uses : actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
156+ with :
157+ path : ${{ runner.temp }}/digests
158+ pattern : digests-*
159+ merge-multiple : true
160+
161+ - name : Install Cosign
162+ uses : sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
163+
164+ - name : Set up Docker Buildx
165+ uses : docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
166+
167+ - name : Login to DockerHub
168+ uses : docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
169+ with :
170+ username : ${{ secrets.DOCKERHUB_USERNAME }}
171+ password : ${{ secrets.DOCKERHUB_TOKEN }}
172+
173+ - name : Login to GitHub Container Registry
174+ uses : docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
175+ with :
176+ registry : ghcr.io
177+ username : ${{ github.actor }}
178+ password : ${{ secrets.GITHUB_TOKEN }}
179+
180+ - name : Create manifest list and push
181+ id : docker_build
182+ working-directory : ${{ runner.temp }}/digests
183+ run : |
184+ # Create the manifest list and push to both registries
185+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
186+ --annotation "index:org.opencontainers.image.created=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.created'] }}" \
187+ --annotation "index:org.opencontainers.image.description=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.description'] }}" \
188+ --annotation "index:org.opencontainers.image.licenses=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.licenses'] }}" \
189+ --annotation "index:org.opencontainers.image.revision=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }}" \
190+ --annotation "index:org.opencontainers.image.source=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.source'] }}" \
191+ --annotation "index:org.opencontainers.image.version=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.version'] }}" \
192+ $(printf '${{ github.repository }}@sha256:%s ' *) \
193+ $(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *)
194+
195+ # Get the digest of the created manifest list
196+ DIGEST=$(docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{json .Manifest.Digest}}' | jq -r .)
197+ echo "digest=$DIGEST" >> $GITHUB_OUTPUT
198+
199+ - name : Attest docker build (DockerHub)
200+ uses : actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
201+ with :
202+ subject-name : index.docker.io/${{ github.repository }}
203+ subject-digest : ${{ steps.docker_build.outputs.digest }}
204+ push-to-registry : true
205+
206+ - name : Attest docker build (GitHub Container Registry)
207+ uses : actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
208+ with :
209+ subject-name : ghcr.io/${{ github.repository }}
210+ subject-digest : ${{ steps.docker_build.outputs.digest }}
211+ push-to-registry : true
212+
213+ - name : Cosign sign images (GitHub OIDC)
214+ run : |
215+ cosign sign --yes \
216+ ${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
217+
218+ cosign sign --yes \
219+ ghcr.io/${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
220+
221+ - name : Inspect images (GitHub Container Registry)
222+ run : |
223+ docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }}
224+
225+ echo "::group::Manifest"
226+ docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json .Manifest }}'
227+ echo "::endgroup::"
228+
229+ echo "::group::Image (linux/amd64)"
230+ docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .Image "linux/amd64") }}'
231+ echo "::endgroup::"
232+
233+ echo "::group::Provenance (linux/amd64)"
234+ docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .Provenance "linux/amd64") }}'
235+ echo "::endgroup::"
236+
237+ echo "::group::SBOM (linux/amd64)"
238+ docker buildx imagetools inspect ghcr.io/${{ github.repository }}:${{ steps.docker_meta.outputs.version }} --format '{{ json (index .SBOM "linux/amd64") }}'
239+ echo "::endgroup::"
240+
241+ - name : Verify cosign signatures
94242 run : |
95- cosign sign --yes --recursive \
96- tibiadata/tibiadata-api-go@${{ steps.docker_build.outputs.digest }}
243+ echo "::group::Verify signature (DockerHub)"
244+ cosign verify --rekor-url https://rekor.sigstore.dev \
245+ --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
246+ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
247+ ${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
248+ echo "::endgroup::"
97249
98- cosign sign --yes --recursive \
99- ghcr.io/tibiadata/tibiadata-api-go@${{ steps.docker_build.outputs.digest }}
250+ echo "::group::Verify signature (GitHub Container Registry)"
251+ cosign verify --rekor-url https://rekor.sigstore.dev \
252+ --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
253+ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
254+ ghcr.io/${{ github.repository }}@${{ steps.docker_build.outputs.digest }}
255+ echo "::endgroup::"
100256
101257 argocd :
102258 if : github.event_name == 'release' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
103259 runs-on : ubuntu-latest
104- needs : build
260+ needs :
261+ - build
262+ - manifest
263+
105264 steps :
106265 - name : Determine the deployment subdomain
107266 id : determine_deployment
@@ -118,19 +277,30 @@ jobs:
118277 token : ${{ secrets.REPO_ACCESS_TOKEN }}
119278 repository : tibiadata/tibiadata-argocd-app-of-apps
120279 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 }}"}'
280+ client-payload : |-
281+ {
282+ "docker_digest": "${{ needs.manifest.outputs.docker_build_digest }}",
283+ "subdomain": "${{ steps.determine_deployment.outputs.subdomain }}"
284+ }
122285
123286 helm-chart :
124287 if : github.event_name == 'release'
125288 permissions :
126289 contents : write
127290 runs-on : ubuntu-latest
128- needs : build
291+ needs :
292+ - build
293+ - manifest
294+
129295 steps :
130296 - name : Trigger workflow in tibiadata-helm-charts repo
131297 uses : peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
132298 with :
133299 token : ${{ secrets.REPO_ACCESS_TOKEN }}
134300 repository : tibiadata/tibiadata-helm-charts
135301 event-type : bump-helm-chart-release
136- client-payload : ' {"chart_name": "${{ github.event.repository.name }}", "release_version": "${{ needs.build.outputs.docker_meta_version }}"}'
302+ client-payload : |-
303+ {
304+ "chart_name": "${{ github.event.repository.name }}",
305+ "release_version": "${{ needs.manifest.outputs.docker_meta_version }}"
306+ }
0 commit comments