@@ -100,16 +100,28 @@ jobs:
100100 draft : false
101101 prerelease : false
102102
103- publish -docker :
104- name : 🐳 Publish Docker Image
103+ build -docker :
104+ name : 🐳 Build Docker Image
105105 needs : prepare-release
106106 runs-on : ubuntu-latest
107107 permissions :
108108 packages : write
109+ strategy :
110+ fail-fast : false
111+ matrix :
112+ platform :
113+ - linux/amd64
114+ - linux/arm64
115+ - linux/arm/v7
109116 steps :
110117 - name : 📥 Checkout code
111118 uses : actions/checkout@v4
112119
120+ - name : 🔧 Prepare platform name
121+ run : |
122+ platform=${{ matrix.platform }}
123+ echo "PLATFORM_PAIR=${platform////-}" >> $GITHUB_ENV
124+
113125 - name : 🛠️ Set up QEMU
114126 uses : docker/setup-qemu-action@v3
115127
@@ -122,17 +134,66 @@ jobs:
122134 username : ${{ secrets.DOCKERHUB_USERNAME }}
123135 password : ${{ secrets.DOCKERHUB_TOKEN }}
124136
125- - name : 🚢 Build and push Docker image
137+ - name : 🚢 Build and push by digest
138+ id : build
126139 uses : docker/build-push-action@v5
127140 with :
128141 context : .
129- platforms : linux/amd64,linux/arm64,linux/arm/v7
130- push : true
131- cache-from : type=gha
132- cache-to : type=gha,mode=max
133- tags : |
134- laffin/cloudproxy:latest
135- laffin/cloudproxy:${{ needs.prepare-release.outputs.new_version }}
142+ platforms : ${{ matrix.platform }}
143+ labels : |
144+ org.opencontainers.image.revision=${{ github.sha }}
145+ org.opencontainers.image.version=${{ needs.prepare-release.outputs.new_version }}
146+ outputs : type=image,name=laffin/cloudproxy,push-by-digest=true,name-canonical=true,push=true
147+ cache-from : type=gha,scope=buildkit-${{ env.PLATFORM_PAIR }}
148+ cache-to : type=gha,mode=max,scope=buildkit-${{ env.PLATFORM_PAIR }}
149+
150+ - name : 📤 Export digest
151+ run : |
152+ mkdir -p /tmp/digests
153+ digest="${{ steps.build.outputs.digest }}"
154+ touch "/tmp/digests/${digest#sha256:}"
155+
156+ - name : 📦 Upload digest
157+ uses : actions/upload-artifact@v4
158+ with :
159+ name : digests-${{ env.PLATFORM_PAIR }}
160+ path : /tmp/digests/*
161+ if-no-files-found : error
162+ retention-days : 1
163+
164+ publish-docker :
165+ name : 🚀 Create and Push Docker Manifest
166+ needs : [prepare-release, build-docker]
167+ runs-on : ubuntu-latest
168+ permissions :
169+ packages : write
170+ steps :
171+ - name : 📥 Download digests
172+ uses : actions/download-artifact@v4
173+ with :
174+ path : /tmp/digests
175+ pattern : digests-*
176+ merge-multiple : true
177+
178+ - name : 🏗️ Set up Docker Buildx
179+ uses : docker/setup-buildx-action@v3
180+
181+ - name : 🔑 Login to Docker Hub
182+ uses : docker/login-action@v3
183+ with :
184+ username : ${{ secrets.DOCKERHUB_USERNAME }}
185+ password : ${{ secrets.DOCKERHUB_TOKEN }}
186+
187+ - name : 🏷️ Create manifest list and push
188+ working-directory : /tmp/digests
189+ run : |
190+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< '{"tags":["laffin/cloudproxy:latest","laffin/cloudproxy:${{ needs.prepare-release.outputs.new_version }}"]}') \
191+ $(printf 'laffin/cloudproxy@sha256:%s ' *)
192+
193+ - name : 🔍 Inspect image
194+ run : |
195+ docker buildx imagetools inspect laffin/cloudproxy:latest
196+ docker buildx imagetools inspect laffin/cloudproxy:${{ needs.prepare-release.outputs.new_version }}
136197
137198 publish-pypi :
138199 name : 📦 Publish PyPI Package
0 commit comments