feat: initial release #1
This file contains 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 30 * * 0 | ||
jobs: | ||
build: | ||
runs-on: ubuntu-24.04 # uses podman from 24.04 or later | ||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE: ghcr.io/${{ github.repository_owner }}/signal-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: | ||
- env: | ||
USERNAME: ${{ github.actor }} | ||
PASSWORD: ${{ secrets.GITHUB_TOKEN }} | ||
run: printenv PASSWORD | podman login -v ${{ env.REGISTRY }} -u "$USERNAME" --password-stdin | ||
- 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" | ||
- 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 }} |