Skip to content

Commit 40fc5dc

Browse files
Build images as multi-arch (amd64 + arm64) manifest lists. (#163)
Build images as multi-arch (amd64 + arm64) manifest lists. --------- Co-authored-by: Brice Dutheil <brice.dutheil@gmail.com>
1 parent 1e7ea0d commit 40fc5dc

8 files changed

Lines changed: 389 additions & 63 deletions

File tree

.github/workflows/ci.yml

Lines changed: 130 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,28 @@ on:
77
branches:
88
- master
99
schedule:
10-
- cron: '0 0 * * 0'
10+
- cron: '0 0 * * 0'
1111
workflow_dispatch:
1212

13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
16+
1317
jobs:
14-
build_push_check:
15-
name: Build docker image, publish it and run vuln scanner against it
18+
build_amd64:
19+
name: Build amd64 images (push by digest)
1620
permissions:
17-
contents: read # for actions/checkout to fetch code
18-
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
19-
packages: write # for image publication to GitHub Packages
20-
runs-on: ubuntu-latest
21+
contents: read
22+
packages: write
23+
runs-on: ubuntu-24.04
2124
environment:
2225
name: ci-build
26+
outputs:
27+
latest_image_tag: ${{ steps.build.outputs.LATEST_IMAGE_TAG }}
2328
steps:
2429
- name: Checkout repository
2530
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
2631
- name: Set up Docker Buildx
27-
id: buildx
2832
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # 4.0.0
2933
- name: Login to ghcr.io
3034
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # 4.1.0
@@ -45,20 +49,132 @@ jobs:
4549
run: ./build --test
4650
- name: Describe images
4751
run: ./build --describe >> $GITHUB_STEP_SUMMARY
48-
- name: Push images
52+
- name: Push images by digest
53+
env:
54+
ORACLE_JAVA8_TOKEN: ${{ secrets.ORACLE_JAVA8_TOKEN }}
55+
run: ./build --push
56+
- name: Upload digest metadata
57+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
58+
with:
59+
name: digests-amd64
60+
path: digests/amd64-*.json
61+
if-no-files-found: error
62+
retention-days: 1
63+
64+
build_arm64:
65+
name: Build arm64 images (push by digest)
66+
permissions:
67+
contents: read
68+
packages: write
69+
runs-on: ubuntu-24.04-arm
70+
environment:
71+
name: ci-build
72+
outputs:
73+
latest_image_tag: ${{ steps.build.outputs.LATEST_IMAGE_TAG }}
74+
steps:
75+
- name: Checkout repository
76+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
77+
- name: Set up Docker Buildx
78+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # 4.0.0
79+
- name: Login to ghcr.io
80+
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # 4.1.0
81+
with:
82+
registry: ghcr.io
83+
username: ${{ github.actor }}
84+
password: ${{ secrets.GITHUB_TOKEN }}
85+
- name: Free Disk Space (Ubuntu)
86+
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
87+
with:
88+
docker-images: false
89+
- name: Build arm64 images
90+
id: build
91+
env:
92+
ORACLE_JAVA8_TOKEN: ${{ secrets.ORACLE_JAVA8_TOKEN }}
93+
PLATFORM: linux/arm64
94+
run: ./build
95+
- name: Test arm64 images
96+
env:
97+
PLATFORM: linux/arm64
98+
run: ./build --test
99+
- name: Describe arm64 images
100+
env:
101+
PLATFORM: linux/arm64
102+
run: ./build --describe >> $GITHUB_STEP_SUMMARY
103+
- name: Push arm64 images by digest
104+
env:
105+
ORACLE_JAVA8_TOKEN: ${{ secrets.ORACLE_JAVA8_TOKEN }}
106+
PLATFORM: linux/arm64
49107
run: ./build --push
50-
- name: Run Trivy vulnerability scanner
108+
- name: Upload digest metadata
109+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
110+
with:
111+
name: digests-arm64
112+
path: digests/arm64-*.json
113+
if-no-files-found: error
114+
retention-days: 1
115+
116+
merge_manifests:
117+
name: Merge per-arch digests into multi-arch manifests
118+
needs: [build_amd64, build_arm64]
119+
permissions:
120+
contents: read
121+
security-events: write
122+
packages: write
123+
runs-on: ubuntu-24.04
124+
steps:
125+
- name: Checkout repository
126+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
127+
- name: Set up Docker Buildx
128+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # 4.0.0
129+
- name: Login to ghcr.io
130+
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # 4.1.0
131+
with:
132+
registry: ghcr.io
133+
username: ${{ github.actor }}
134+
password: ${{ secrets.GITHUB_TOKEN }}
135+
- name: Download amd64 digests
136+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
137+
with:
138+
name: digests-amd64
139+
path: digests
140+
- name: Download arm64 digests
141+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
142+
with:
143+
name: digests-arm64
144+
path: digests
145+
- name: Create multi-arch manifests
146+
run: ./build --merge
147+
- name: Run Trivy vulnerability scanner (amd64)
148+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
149+
with:
150+
image-ref: '${{ needs.build_amd64.outputs.latest_image_tag }}'
151+
format: 'sarif'
152+
output: 'trivy-results-amd64.sarif'
153+
severity: 'CRITICAL,HIGH'
154+
limit-severities-for-sarif: true
155+
env:
156+
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db
157+
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
158+
TRIVY_PLATFORM: linux/amd64
159+
- name: Upload amd64 Trivy results
160+
uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
161+
with:
162+
sarif_file: 'trivy-results-amd64.sarif'
163+
category: trivy-amd64
164+
- name: Run Trivy vulnerability scanner (arm64)
51165
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
52166
with:
53-
image-ref: '${{ steps.build.outputs.LATEST_IMAGE_TAG }}'
167+
image-ref: '${{ needs.build_arm64.outputs.latest_image_tag }}'
54168
format: 'sarif'
55-
output: 'trivy-results.sarif'
169+
output: 'trivy-results-arm64.sarif'
56170
severity: 'CRITICAL,HIGH'
57171
limit-severities-for-sarif: true
58172
env:
59173
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db
60174
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
61-
- name: Upload Trivy scan results to GitHub Security tab
175+
TRIVY_PLATFORM: linux/arm64
176+
- name: Upload arm64 Trivy results
62177
uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
63178
with:
64-
sarif_file: 'trivy-results.sarif'
179+
sarif_file: 'trivy-results-arm64.sarif'
180+
category: trivy-arm64

.github/workflows/docker-tag.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
jobs:
1515
tag-images:
1616
name: Tag new images version
17-
runs-on: ubuntu-latest
17+
runs-on: ubuntu-24.04
1818
permissions:
1919
contents: read
2020
packages: write
@@ -28,6 +28,8 @@ jobs:
2828
tar -xzf crane.tar.gz crane
2929
sudo mv crane /usr/local/bin/crane
3030
rm crane.tar.gz
31+
- name: Set up Docker Buildx
32+
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # 4.0.0
3133
- name: Login to ghcr.io
3234
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # 4.1.0
3335
with:
@@ -47,7 +49,12 @@ jobs:
4749
# Collect all image references from COPY --from= and FROM directives
4850
mapfile -t ALL_REFS < <({
4951
sed -n 's/.*--from=\([^ ]*\).*/\1/p' Dockerfile
50-
awk '/^FROM/{print $2}' Dockerfile
52+
# Skip FROM options like `--platform` to capture the image reference
53+
awk '/^FROM/ {
54+
for (i = 2; i <= NF; i++) {
55+
if ($i !~ /^--/) { print $i; break }
56+
}
57+
}' Dockerfile
5158
})
5259
5360
# Filter to only external images

.github/workflows/registry-cleanup.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
contents: read
1313
packages: write
1414
steps:
15-
- name: Prune untagged images
15+
- name: Prune stale PR test image tags
1616
uses: vlaurin/action-ghcr-prune@0cf7d39f88546edd31965acba78cdcb0be14d641 #v0.6.0
1717
with:
1818
token: ${{ secrets.GITHUB_TOKEN }}
@@ -21,4 +21,8 @@ jobs:
2121
keep-younger-than: 30 # days
2222
prune-tags-regexes: |
2323
^[a-z0-9]+_merge-
24-
prune-untagged: true
24+
# IMPORTANT: do NOT enable prune-untagged. With multi-arch manifest
25+
# lists, each per-arch child manifest appears "untagged" in GHCR even
26+
# though it is referenced by a tagged manifest list. Pruning untagged
27+
# images would dereference the manifest lists and break pulls.
28+
prune-untagged: false

.github/workflows/vuln-check.yml

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,42 @@ jobs:
2929
with:
3030
docker-images: false # Do not remove locally built images (including trivy scanner)
3131

32-
- name: Run Trivy vulnerability scanner
32+
- name: Run Trivy vulnerability scanner (amd64)
3333
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
3434
with:
3535
image-ref: 'ghcr.io/datadog/dd-trace-java-docker-build:latest'
3636
format: 'sarif'
37-
output: 'trivy-results.sarif'
37+
output: 'trivy-results-amd64.sarif'
3838
severity: 'CRITICAL,HIGH'
3939
limit-severities-for-sarif: true
4040
env:
4141
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db
4242
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
43+
TRIVY_PLATFORM: linux/amd64
4344

44-
- name: Upload Trivy scan results to GitHub Security tab
45+
- name: Upload amd64 Trivy scan results to GitHub Security tab
4546
uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
4647
if: always()
4748
with:
48-
sarif_file: 'trivy-results.sarif'
49+
sarif_file: 'trivy-results-amd64.sarif'
50+
category: trivy-amd64
51+
52+
- name: Run Trivy vulnerability scanner (arm64)
53+
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
54+
with:
55+
image-ref: 'ghcr.io/datadog/dd-trace-java-docker-build:latest'
56+
format: 'sarif'
57+
output: 'trivy-results-arm64.sarif'
58+
severity: 'CRITICAL,HIGH'
59+
limit-severities-for-sarif: true
60+
env:
61+
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db
62+
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
63+
TRIVY_PLATFORM: linux/arm64
64+
65+
- name: Upload arm64 Trivy scan results to GitHub Security tab
66+
uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
67+
if: always()
68+
with:
69+
sarif_file: 'trivy-results-arm64.sarif'
70+
category: trivy-arm64

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
.idea
2+
.DS_Store
3+
digests/

0 commit comments

Comments
 (0)