@@ -10,30 +10,6 @@ branding:
1010 icon : package
1111 color : blue
1212
13- outputs :
14- built-image :
15- description : |
16- Built image data.
17- Example:
18- ```json
19- {
20- "name": "application",
21- "registry": "ghcr.io",
22- "repository": "my-org/my-repo/application",
23- "digest": "sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
24- "image": "ghcr.io/my-org/my-repo/application@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
25- "tags": [
26- "pr-63-5222075",
27- "pr-63"
28- ],
29- "annotations": {
30- "org.opencontainers.image.created": "2021-09-30T14:00:00Z",
31- "org.opencontainers.image.description": "Application image"
32- }
33- }
34- ```
35- value : ${{ steps.get-built-image.outputs.built-image }}
36-
3713inputs :
3814 oci-registry :
3915 description : " OCI registry where to pull and push images"
@@ -70,7 +46,7 @@ inputs:
7046 required : false
7147 platform :
7248 description : |
73- Platform to build for.
49+ Platform to build for. Example: `linux/amd64`.
7450 See https://github.com/docker/build-push-action#inputs.
7551 required : true
7652 context :
@@ -112,6 +88,31 @@ inputs:
11288 default : " gha"
11389 required : false
11490
91+ outputs :
92+ built-image :
93+ description : |
94+ Built image data.
95+ Example:
96+ ```json
97+ {
98+ "name": "application",
99+ "registry": "ghcr.io",
100+ "repository": "my-org/my-repo/application",
101+ "digest": "sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
102+ "image": "ghcr.io/my-org/my-repo/application@sha256:d31aa93410434ac9dcfc9179cac2cb1fd4d7c27f11527addc40299c7c675f49d",
103+ "tags": [
104+ "pr-63-5222075",
105+ "pr-63"
106+ ],
107+ "annotations": {
108+ "org.opencontainers.image.created": "2021-09-30T14:00:00Z",
109+ "org.opencontainers.image.description": "Application image"
110+ },
111+ "platform": "linux/amd64"
112+ }
113+ ```
114+ value : ${{ steps.get-built-image.outputs.built-image }}
115+
115116runs :
116117 using : " composite"
117118 steps :
@@ -142,6 +143,14 @@ runs:
142143 - id : get-docker-config
143144 shell : bash
144145 run : |
146+ DOCKERFILE_PATH="${{ github.workspace }}/${{ inputs.context }}/${{ inputs.dockerfile }}"
147+ if [ ! -f "$DOCKERFILE_PATH" ]; then
148+ echo "::error::Dockerfile not found at path: $DOCKERFILE_PATH"
149+ exit 1
150+ fi
151+ DOCKERFILE_PATH=$(realpath "$DOCKERFILE_PATH")
152+ echo "dockerfile-path=$DOCKERFILE_PATH" >> "$GITHUB_OUTPUT"
153+
145154 TAG_SUFFIX="-${{ steps.slugify-platform.outputs.result }}"
146155
147156 # Add tag suffix flavor
@@ -201,7 +210,24 @@ runs:
201210 fi
202211 fi
203212
204- - id : cache
213+ - if : steps.get-docker-config.outputs.docker-exists != 'true'
214+ uses : docker/setup-docker-action@3fb92d6d9c634363128c8cce4bc3b2826526370a # v4.4.0
215+
216+ - if : steps.get-docker-config.outputs.platform-exists != 'true'
217+ uses : docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
218+ with :
219+ platforms : ${{ inputs.platform }}
220+
221+ - uses : docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
222+ with :
223+ # FIXME: upgrade version when available (https://github.com/docker/buildx/releases)
224+ version : v0.29.1
225+ # FIXME: upgrade version when available (https://hub.docker.com/r/moby/buildkit)
226+ driver-opts : |
227+ image=moby/buildkit:v0.25.1
228+
229+ # Caching setup
230+ - id : cache-arguments
205231 uses : int128/docker-build-cache-config-action@fb186e80c08f14a2e56ed9105d4594562bff013f # v1.40.0
206232 with :
207233 image : ${{ steps.get-docker-config.outputs.cache-image }}
@@ -216,8 +242,8 @@ runs:
216242 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
217243 with :
218244 script : |
219- const cacheFrom = `${{ steps.cache.outputs.cache-from }}`;
220- const cacheTo = `${{ steps.cache.outputs.cache-to }}`;
245+ const cacheFrom = `${{ steps.cache-arguments .outputs.cache-from }}`;
246+ const cacheTo = `${{ steps.cache-arguments .outputs.cache-to }}`;
221247
222248 core.info(`Original cache-from: ${cacheFrom}`);
223249 core.info(`Original cache-to: ${cacheTo}`);
@@ -234,22 +260,19 @@ runs:
234260 core.setOutput('cache-from', transformedCacheFrom);
235261 core.setOutput('cache-to', transformedCacheTo);
236262
237- - if : steps.get-docker-config.outputs.docker-exists != 'true'
238- uses : docker/setup-docker-action@3fb92d6d9c634363128c8cce4bc3b2826526370a # v4.4.0
239-
240- - if : steps.get-docker-config.outputs.platform-exists != 'true'
241- uses : docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
263+ - uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
264+ id : cache
242265 with :
243- platforms : ${{ inputs.platform }}
266+ path : cache-mount
267+ key : cache-mount-${{ hashFiles(steps.get-docker-config.outputs.dockerfile-path) }}
244268
245- # jscpd:ignore-start
246- - uses : docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
269+ - name : Restore Docker cache mounts
270+ uses : reproducible-containers/buildkit-cache-dance@5b81f4d29dc8397a7d341dba3aeecc7ec54d6361 # v3.3.0
247271 with :
248- # FIXME: upgrade version when available (https://github.com/docker/buildx/releases)
249- version : v0.27.0
250- # FIXME: upgrade version when available (https://hub.docker.com/r/moby/buildkit)
251- driver-opts : |
252- image=moby/buildkit:v0.23.2
272+ builder : ${{ steps.setup-buildx.outputs.name }}
273+ cache-dir : cache-mount
274+ dockerfile : ${{ steps.get-docker-config.outputs.dockerfile-path }}
275+ skip-extraction : ${{ steps.cache.outputs.cache-hit }}
253276
254277 - uses : docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
255278 with :
@@ -264,19 +287,22 @@ runs:
264287 context : ${{ inputs.context }}
265288 build-args : ${{ inputs.build-args }}
266289 target : ${{ inputs.target }}
267- file : ${{ github.workspace }}/${{ inputs.context }}/${{ inputs .dockerfile }}
290+ file : ${{ steps.get-docker-config.outputs .dockerfile-path }}
268291 secrets : ${{ inputs.secrets }}
269292 secret-envs : ${{ inputs.secret-envs }}
270293 platforms : ${{ inputs.platform }}
271294 # FIXME: Remove 'inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-from ||'
272295 # when https://github.com/int128/docker-build-cache-config-action/pull/1213 is merged
273- cache-from : ${{ inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-from || steps.cache.outputs.cache-from }}
296+ cache-from : ${{ inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-from || steps.cache-arguments .outputs.cache-from }}
274297 # FIXME: Remove 'inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-to ||'
275298 # when https://github.com/int128/docker-build-cache-config-action/pull/1213 is merged
276- cache-to : ${{ inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-to || steps.cache.outputs.cache-to }}
277- outputs : " type=image,push=true,push -by-digest=true,name-canonical=true,name=${{ steps.metadata.outputs.image }} "
299+ cache-to : ${{ inputs.cache-type == 'gha' && steps.transform-cache-gha.outputs.cache-to || steps.cache-arguments .outputs.cache-to }}
300+ outputs : type=image,push-by-digest=true,name-canonical=true,push=true
278301 labels : ${{ steps.metadata.outputs.labels }}
279302 annotations : ${{ steps.metadata.outputs.annotations }}
303+ tags : ${{ steps.metadata.outputs.image }}
304+ provenance : false # Disable provenance to avoid unknown/unknown arch
305+ sbom : false # Disable sbom to avoid unknown/unknown arch
280306
281307 - id : get-built-image
282308 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
@@ -288,10 +314,6 @@ runs:
288314 return;
289315 }
290316
291- if (builtMetadata["containerimage.digest"] === undefined) {
292- return core.setFailed('Given "metadata"."containerimage.digest" output is undefined.');
293- }
294-
295317 const name = `${{ inputs.image }}`;
296318 const image = `${{ steps.metadata.outputs.image }}`;
297319 const registryMatch = image.match(/^([^\/]+)\/.*/);
@@ -304,6 +326,37 @@ runs:
304326 .map(tag => tag.replace(/[^\/]+\/[^:]+:(.+)/,'$1').trim())
305327 .filter(tag => tag !== "");
306328
329+ let platform;
330+
331+ const buildxProvenance = builtMetadata?.["buildx.build.provenance"];
332+ if (buildxProvenance !== undefined) {
333+ platform = buildxProvenance.invocation?.environment?.platform;
334+ if (platform === undefined) {
335+ return core.setFailed('Given "metadata"."buildx.build.provenance"."invocation"."environment"."platform" output is undefined.');
336+ }
337+ if (typeof platform !== "string") {
338+ return core.setFailed('Given "metadata"."buildx.build.provenance"."invocation"."environment"."platform" is not a string.');
339+ }
340+ platform = platform.trim();
341+ if (platform === "") {
342+ return core.setFailed('Given "metadata"."buildx.build.provenance"."invocation"."environment"."platform" is empty.');
343+ }
344+ } else {
345+ const descriptor = builtMetadata?.["containerimage.descriptor"];
346+ if (descriptor?.["platform"] === undefined) {
347+ return core.setFailed('Given "metadata"."containerimage.descriptor"."platform" output is undefined.');
348+ }
349+ const platformData = descriptor["platform"];
350+ if (typeof platformData !== 'object' || platformData.os === undefined || platformData.architecture === undefined) {
351+ return core.setFailed('Given "metadata"."containerimage.descriptor"."platform" does not contain required "os" and "architecture" fields.');
352+ }
353+ platform = `${platformData.os}/${platformData.architecture}${platformData.variant ? `/${platformData.variant}` : ''}`;
354+ }
355+
356+ if (builtMetadata?.["containerimage.digest"] === undefined) {
357+ return core.setFailed('Given "metadata"."containerimage.digest" output is undefined.');
358+ }
359+
307360 const digests = builtMetadata["containerimage.digest"]
308361 .split(",")
309362 .map(digest => {
@@ -346,7 +399,8 @@ runs:
346399 registry,
347400 repository,
348401 image: imageWithDigest,
349- digest
402+ digest,
403+ platform
350404 };
351405
352406 core.setOutput("built-image", JSON.stringify(builtImage));
0 commit comments