@@ -321,6 +321,60 @@ jobs:
321321 docker rmi "${CACHE_FROM_IMAGE}"
322322 shell : bash
323323 if : always() && env.CACHE_FROM_IMAGE != ''
324+ # zstd stands in for the stash's zlib (compression-level 0 below), which every consumer inflates.
325+ # The .tar name, which every Breeze expects, stays: docker image load detects zstd by content.
326+ - name : " Export CI docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
327+ env :
328+ PLATFORM : ${{ inputs.platform }}
329+ COMMIT_FILE : " /mnt/ci-image-commit-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.txt"
330+ run : |
331+ breeze ci-image save --platform "${PLATFORM}" --image-file-dir "/mnt"
332+ for image_file in /mnt/ci-image-save-*-"${PYTHON_MAJOR_MINOR_VERSION}".tar; do
333+ zstd -6 -T0 --rm -o "${image_file}.zst" "${image_file}"
334+ mv "${image_file}.zst" "${image_file}"
335+ done
336+ git rev-parse HEAD > "${COMMIT_FILE}"
337+ shell : bash
338+ if : inputs.upload-image-artifact == 'true' && steps.stashed-image.outputs.reusable != 'true'
339+ - name : " Stash CI docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
340+ uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
341+ with :
342+ key : ci-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}
343+ path : " /mnt/ci-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar"
344+ if-no-files-found : ' error'
345+ compression-level : ' 0'
346+ retention-days : ' 2'
347+ if : inputs.upload-image-artifact == 'true' && inputs.image-stash-ref == ''
348+ # The per-branch stash above is written by every build on this branch, so an image built
349+ # from a ref other than the branch tip cannot live there: whoever restores it next would
350+ # get sources they never asked for. The ref keeps its own stash instead, which is also
351+ # what a later publish of that same ref reads - hence a retention that outlives the shared
352+ # one, the same ref being rebuilt three days apart at the very least.
353+ - name : " Stash CI docker image built for ref ${{ inputs.image-stash-ref }}"
354+ uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
355+ with :
356+ key : " ci-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}\
357+ -${{ inputs.image-stash-ref }}"
358+ path : " /mnt/ci-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar"
359+ if-no-files-found : ' error'
360+ compression-level : ' 0'
361+ retention-days : ' 6'
362+ if : >
363+ inputs.upload-image-artifact == 'true' && inputs.image-stash-ref != '' &&
364+ steps.stashed-image.outputs.reusable != 'true'
365+ # Saved last and with the image's retention, so that finding this commit is enough to
366+ # know the image it describes is there to be restored.
367+ - name : " Stash the commit the CI image for ref ${{ inputs.image-stash-ref }} was built from"
368+ uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
369+ with :
370+ key : " ci-image-commit-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}\
371+ -${{ inputs.image-stash-ref }}"
372+ path : " /mnt/ci-image-commit-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.txt"
373+ if-no-files-found : ' error'
374+ retention-days : ' 6'
375+ if : >
376+ inputs.upload-image-artifact == 'true' && inputs.image-stash-ref != '' &&
377+ steps.stashed-image.outputs.reusable != 'true'
324378 - name : " Export mount cache ${{ inputs.platform }}:${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
325379 env :
326380 PYTHON_MAJOR_MINOR_VERSION : ${{ env.PYTHON_MAJOR_MINOR_VERSION }}
@@ -345,10 +399,10 @@ jobs:
345399 if: >
346400 inputs.upload-mount-cache-artifact == 'true' &&
347401 steps.stashed-image.outputs.reusable != 'true'
348- # Every job that prepares the CI image would otherwise `docker image load` the stash below ,
402+ # Every job that prepares the CI image would otherwise `docker image load` the image stash ,
349403 # unpacking and checksumming each layer again; a copy of the image store restores with one
350- # extraction. Taken while the freshly built layers are still in the page cache, and after the
351- # mount cache export, as it drops the build cache that the export reads .
404+ # extraction. Run after the authoritative image and mount- cache publications: snapshot
405+ # creation prunes the build cache and must not affect the artifacts those steps publish .
352406 # Snapshots are handoffs within this run, not branch caches. An arbitrary checkout ref
353407 # must not publish raw daemon state for a later run on the default branch.
354408 - name : " Snapshot CI image ${{ inputs.platform }}:${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
@@ -379,59 +433,5 @@ jobs:
379433 github.event_name == 'pull_request' && steps.snapshot-export.outcome == 'success' &&
380434 inputs.upload-image-artifact == 'true' && inputs.image-stash-ref == '' &&
381435 steps.stashed-image.outputs.reusable != 'true'
382- # zstd stands in for the stash's zlib (compression-level 0 below), which every consumer inflates.
383- # The .tar name, which every Breeze expects, stays: docker image load detects zstd by content.
384- - name : " Export CI docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
385- env :
386- PLATFORM : ${{ inputs.platform }}
387- COMMIT_FILE : " /mnt/ci-image-commit-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.txt"
388- run : |
389- breeze ci-image save --platform "${PLATFORM}" --image-file-dir "/mnt"
390- for image_file in /mnt/ci-image-save-*-"${PYTHON_MAJOR_MINOR_VERSION}".tar; do
391- zstd -6 -T0 --rm -o "${image_file}.zst" "${image_file}"
392- mv "${image_file}.zst" "${image_file}"
393- done
394- git rev-parse HEAD > "${COMMIT_FILE}"
395- shell : bash
396- if : inputs.upload-image-artifact == 'true' && steps.stashed-image.outputs.reusable != 'true'
397- - name : " Stash CI docker image ${{ env.PYTHON_MAJOR_MINOR_VERSION }}"
398- uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
399- with :
400- key : ci-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}
401- path : " /mnt/ci-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar"
402- if-no-files-found : ' error'
403- compression-level : ' 0'
404- retention-days : ' 2'
405- if : inputs.upload-image-artifact == 'true' && inputs.image-stash-ref == ''
406- # The per-branch stash above is written by every build on this branch, so an image built
407- # from a ref other than the branch tip cannot live there: whoever restores it next would
408- # get sources they never asked for. The ref keeps its own stash instead, which is also
409- # what a later publish of that same ref reads - hence a retention that outlives the shared
410- # one, the same ref being rebuilt three days apart at the very least.
411- - name : " Stash CI docker image built for ref ${{ inputs.image-stash-ref }}"
412- uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
413- with :
414- key : " ci-image-save-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}\
415- -${{ inputs.image-stash-ref }}"
416- path : " /mnt/ci-image-save-*-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.tar"
417- if-no-files-found : ' error'
418- compression-level : ' 0'
419- retention-days : ' 6'
420- if : >
421- inputs.upload-image-artifact == 'true' && inputs.image-stash-ref != '' &&
422- steps.stashed-image.outputs.reusable != 'true'
423- # Saved last and with the image's retention, so that finding this commit is enough to
424- # know the image it describes is there to be restored.
425- - name : " Stash the commit the CI image for ref ${{ inputs.image-stash-ref }} was built from"
426- uses : apache/infrastructure-actions/stash/save@61dcea11f19e2bbe1263f14d72235e8da17d3ad0 # save/v1.0.0
427- with :
428- key : " ci-image-commit-v3-${{ inputs.platform }}-${{ env.PYTHON_MAJOR_MINOR_VERSION }}\
429- -${{ inputs.image-stash-ref }}"
430- path : " /mnt/ci-image-commit-${{ env.PYTHON_MAJOR_MINOR_VERSION }}.txt"
431- if-no-files-found : ' error'
432- retention-days : ' 6'
433- if : >
434- inputs.upload-image-artifact == 'true' && inputs.image-stash-ref != '' &&
435- steps.stashed-image.outputs.reusable != 'true'
436436 - name : " Check disk space after build"
437437 run : df -H
0 commit comments