1+ name : Docker Bake Build and Push
2+ # This is mostly taken from
3+ # here: https://docs.docker.com/build/ci/github-actions/multi-platform/#with-bake
4+ on :
5+ push :
6+ branches : [ main ]
7+ pull_request :
8+ branches : [ main ]
9+ workflow_dispatch :
10+
11+ env :
12+ REGISTRY : ghcr.io/nersc/interactem
13+
14+ jobs :
15+ prepare :
16+ runs-on : ubuntu-latest
17+ permissions :
18+ contents : read
19+ outputs :
20+ tag : ${{ steps.meta.outputs.tag }}
21+ services : ${{ steps.services.outputs.services }}
22+ all-images : ${{ steps.services.outputs.all-images }}
23+ steps :
24+ - name : Checkout
25+ uses : actions/checkout@v4
26+ with :
27+ submodules : false
28+
29+ - name : Set up Docker Buildx
30+ uses : docker/setup-buildx-action@v3
31+
32+ - name : Extract metadata
33+ id : meta
34+ run : |
35+ TAG=$(git rev-parse --short=6 HEAD)
36+ echo "tag=${TAG}" >> $GITHUB_OUTPUT
37+ echo "Generated tag: ${TAG}"
38+
39+ - name : Define services
40+ id : services
41+ run : |
42+ # Extract services from the prod group in docker-bake.hcl
43+ SERVICES=$(docker buildx bake prod --print | jq -cr '[.group.prod.targets[]]')
44+ echo "Services found: ${SERVICES}"
45+ echo "services=${SERVICES}" >> $GITHUB_OUTPUT
46+
47+ # Create combined list including base image for merge-manifests
48+ ALL_IMAGES=$(echo ${SERVICES} | jq -c '. + ["interactem"]')
49+ echo "All images (including base): ${ALL_IMAGES}"
50+ echo "all-images=${ALL_IMAGES}" >> $GITHUB_OUTPUT
51+ working-directory : ./docker
52+
53+ build-base :
54+ needs : prepare
55+ strategy :
56+ matrix :
57+ include :
58+ - platform : amd64
59+ runner : ubuntu-24.04
60+ docker-platform : linux/amd64
61+ - platform : arm64
62+ runner : ubuntu-24.04-arm
63+ docker-platform : linux/arm64
64+ runs-on : ${{ matrix.runner }}
65+ permissions :
66+ contents : read
67+ packages : write
68+ steps :
69+ - name : Checkout
70+ uses : actions/checkout@v4
71+ with :
72+ submodules : false
73+
74+ - name : Set up Docker Buildx
75+ uses : docker/setup-buildx-action@v3
76+
77+ - name : Login to GitHub Container Registry
78+ uses : docker/login-action@v3
79+ with :
80+ registry : ${{ env.REGISTRY }}
81+ username : ${{ github.actor }}
82+ password : ${{ secrets.GHCR_PAT }}
83+
84+ - name : Build and push base image by digest
85+ id : bake
86+ uses : docker/bake-action@v6
87+ with :
88+ source : .
89+ files : ./docker/docker-bake.hcl
90+ targets : base
91+ set : |
92+ *.platform=${{ matrix.docker-platform }}
93+ ${{ github.event_name != 'pull_request' && '*.output=type=image,push-by-digest=true,name-canonical=true,push=true' || '' }}
94+ *.tags=${{ env.REGISTRY }}/interactem
95+ env :
96+ TAG : ${{ needs.prepare.outputs.tag }}
97+ CACHE_PLATFORM : ${{ matrix.platform }}
98+
99+ - name : Export digest
100+ if : github.event_name != 'pull_request'
101+ run : |
102+ mkdir -p /tmp/digests
103+ digest="${{ fromJSON(steps.bake.outputs.metadata).base['containerimage.digest'] }}"
104+ touch "/tmp/digests/${digest#sha256:}"
105+
106+ - name : Upload digest
107+ if : github.event_name != 'pull_request'
108+ uses : actions/upload-artifact@v4
109+ with :
110+ name : interactem-digest-${{ matrix.platform }}
111+ path : /tmp/digests/*
112+ if-no-files-found : error
113+ retention-days : 1
114+
115+ build-services :
116+ needs : [prepare, build-base]
117+ strategy :
118+ matrix :
119+ platform :
120+ - { name: amd64, runner: ubuntu-24.04, docker: linux/amd64 }
121+ - { name: arm64, runner: ubuntu-24.04-arm, docker: linux/arm64 }
122+ service : ${{ fromJson(needs.prepare.outputs.services) }}
123+ runs-on : ${{ matrix.platform.runner }}
124+ permissions :
125+ contents : read
126+ packages : write
127+ steps :
128+ - name : Checkout
129+ uses : actions/checkout@v4
130+ with :
131+ submodules : false
132+
133+ - name : Set up Docker Buildx
134+ uses : docker/setup-buildx-action@v3
135+
136+ - name : Login to GitHub Container Registry
137+ uses : docker/login-action@v3
138+ with :
139+ registry : ${{ env.REGISTRY }}
140+ username : ${{ github.actor }}
141+ password : ${{ secrets.GHCR_PAT }}
142+
143+ - name : Build and push ${{ matrix.service }} by digest
144+ id : bake
145+ uses : docker/bake-action@v6
146+ with :
147+ source : .
148+ files : ./docker/docker-bake.hcl
149+ targets : ${{ matrix.service }}
150+ set : |
151+ *.platform=${{ matrix.platform.docker }}
152+ ${{ github.event_name != 'pull_request' && '*.output=type=image,push-by-digest=true,name-canonical=true,push=true' || '' }}
153+ *.tags=${{ env.REGISTRY }}/${{ matrix.service }}
154+ env :
155+ TAG : ${{ needs.prepare.outputs.tag }}
156+ CACHE_PLATFORM : ${{ matrix.platform.name }}
157+
158+ - name : Export digest
159+ if : github.event_name != 'pull_request'
160+ run : |
161+ mkdir -p /tmp/digests
162+ digest="${{ fromJSON(steps.bake.outputs.metadata)[matrix.service]['containerimage.digest'] }}"
163+ touch "/tmp/digests/${digest#sha256:}"
164+
165+ - name : Upload digest
166+ if : github.event_name != 'pull_request'
167+ uses : actions/upload-artifact@v4
168+ with :
169+ name : ${{ matrix.service }}-digest-${{ matrix.platform.name }}
170+ path : /tmp/digests/*
171+ if-no-files-found : error
172+ retention-days : 1
173+
174+ merge-manifests :
175+ if : github.event_name != 'pull_request'
176+ needs : [prepare, build-base, build-services]
177+ runs-on : ubuntu-latest
178+ permissions :
179+ contents : read
180+ packages : write
181+ strategy :
182+ matrix :
183+ service : ${{ fromJson(needs.prepare.outputs.all-images) }}
184+ steps :
185+ - name : Set up Docker Buildx
186+ uses : docker/setup-buildx-action@v3
187+
188+ - name : Login to GitHub Container Registry
189+ uses : docker/login-action@v3
190+ with :
191+ registry : ${{ env.REGISTRY }}
192+ username : ${{ github.actor }}
193+ password : ${{ secrets.GHCR_PAT }}
194+
195+ - name : Download digests
196+ uses : actions/download-artifact@v4
197+ with :
198+ path : /tmp/digests
199+ pattern : ${{ matrix.service }}-digest-*
200+ merge-multiple : true
201+
202+ - name : Create manifest list and push
203+ working-directory : /tmp/digests
204+ run : |
205+ # Create manifest
206+ docker buildx imagetools create \
207+ -t ${{ env.REGISTRY }}/${{ matrix.service }}:${{ needs.prepare.outputs.tag }} \
208+ -t ${{ env.REGISTRY }}/${{ matrix.service }}:latest \
209+ $(printf '${{ env.REGISTRY }}/${{ matrix.service }}@sha256:%s ' *)
210+
211+ - name : Inspect image
212+ run : |
213+ docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ matrix.service }}:${{ needs.prepare.outputs.tag }}
0 commit comments