Build Container #56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Container | |
| on: | |
| push: | |
| branches: | |
| - main | |
| schedule: | |
| - cron: 40 3 * * 0 | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE: ghcr.io/${{ github.repository_owner }}/smtp-proxy | |
| IMGCACHE_PATH: image_cache.tar | |
| # building using docker format is required to make builds | |
| # find cached build layers after a save/load cycle | |
| BUILDAH_FORMAT: docker | |
| steps: | |
| - id: restore-cache | |
| uses: actions/cache/restore@v4 | |
| with: | |
| # we can't precalculate the hash for a key so | |
| # set an invalid key and fall back to the most recent cache | |
| key: image-cache-INVALID | |
| restore-keys: image-cache- | |
| path: ${{ env.IMGCACHE_PATH }} | |
| - name: Import images from cache | |
| # skip step if no cache was restored | |
| if: steps.restore-cache.outputs.cache-matched-key != '' | |
| continue-on-error: true | |
| run: | | |
| podman load -i "${IMGCACHE_PATH:?}" \ | |
| || echo "::warning::Failure while importing images from cache" | |
| echo | |
| echo "Image Status:" | |
| podman image list | |
| echo "IMPORTED_CONTAINERS=$(podman image list -q --sort id | xargs)" >> "$GITHUB_ENV" | |
| - name: Check for newer package versions in apk | |
| # skip step if no cache was restored | |
| if: steps.restore-cache.outputs.cache-matched-key != '' | |
| continue-on-error: true | |
| run: | | |
| [ -n "$(podman run --pull never --rm -i ${{ env.IMAGE }} sh -c 'apk -q update && apk -q list -u dma msmtp s-nail')" ] || exit 0 | |
| podman image rm ${{ env.IMAGE }} | |
| podman image prune -f | |
| - env: | |
| USERNAME: ${{ github.actor }} | |
| PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
| run: printenv PASSWORD | podman login -v ${{ env.REGISTRY }} -u "$USERNAME" --password-stdin | |
| - uses: actions/checkout@v4 | |
| # TODO: switch to --pull=newer once supported https://github.com/containers/podman/issues/22845 | |
| - run: podman build --pull=always -t ${{ env.IMAGE }} . | |
| - run: podman push ${{ env.IMAGE }} | |
| - if: ${{ !cancelled() }} # runs even if previous steps failed | |
| run: podman logout ${{ env.REGISTRY }} | |
| - id: export-cache | |
| name: Export images to cache | |
| continue-on-error: true | |
| run: | | |
| echo "Existing Images:" | |
| podman image list | |
| echo | |
| rm -f "${IMGCACHE_PATH:?}" | |
| if [ "$(podman image list -q --sort id | xargs)" = "$IMPORTED_CONTAINERS" ]; then | |
| echo 'Images unchanged, skipping export!' | |
| echo 'export-skipped=true' >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Saving Images:" | |
| for tgt in $( | |
| # list latest potential build cache images: dangling images that are the most | |
| # recent ancestor of images that is still labeled (I.E. not untagged/replaced) | |
| seen=" " | |
| for img in $(podman image list -q --filter dangling=true); do | |
| l_ancest=$( i="$img"; i="$(podman image inspect -f '{{ .Parent }}' "$i")"; while [ -n "$i" ]; do if [ "$(podman image inspect -f '{{ len .RepoTags }}' "$i")" -gt 0 ]; then echo "$i"; break; else i="$(podman image inspect -f '{{ .Parent }}' "$i")"; fi; done; ) | |
| [ -z "$l_ancest" ] && continue | |
| case "$seen" in (*" $l_ancest "*) continue ;; esac | |
| seen="$seen$l_ancest " | |
| echo "$img" | |
| done | |
| # labeled images | |
| podman image list --filter dangling=false --format '{{ range .Names }}{{ . }} {{ end }}' | xargs -n 1 | sort -u | |
| ); do | |
| echo $( i="$tgt" ids=; while [ -n "$i" ]; do ids="$ids $i" i="$(podman image inspect -f '{{ .Parent }}' "$i")"; done; echo "$ids"; ) | |
| done \ | |
| | xargs -n 1 | sort -u \ | |
| | tee /dev/stderr \ | |
| | xargs podman save -m -o "${IMGCACHE_PATH:?}" \ | |
| || echo "::error::Failure while exporting images to cache" | |
| - uses: actions/cache/save@v4 | |
| if: steps.export-cache.outcome == 'success' && !steps.export-cache.outputs.export-skipped && !endsWith(steps.restore-cache.outputs.cache-matched-key, hashFiles(env.IMGCACHE_PATH)) | |
| with: | |
| key: image-cache-${{ hashFiles(env.IMGCACHE_PATH) }} | |
| path: ${{ env.IMGCACHE_PATH }} |