build(deps): bump distroless/static-debian12 base image #551
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
| # Runs on every push to main — publishes bleeding-edge Docker images and | |
| # deploys documentation when docs/ changed. Canonical writer for the | |
| # `:buildcache` registry cache consumed by ci.yml and release.yml. | |
| # | |
| # Multi-arch images are built natively per arch (amd64 on ubuntu-latest, | |
| # arm64 on ubuntu-24.04-arm) instead of via QEMU emulation — issue #9. | |
| # Each per-arch build pushes by digest only, then a manifest job per | |
| # image joins the digests into a single :main multi-arch tag. | |
| name: Main | |
| on: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: write | |
| packages: write | |
| pages: write | |
| env: | |
| REGISTRY: ghcr.io | |
| jobs: | |
| # Per-arch image builds. 2 images × 2 architectures = 4 jobs running in | |
| # parallel. Each pushes by digest only (push-by-digest=true) so the tag | |
| # remains free for the manifest job to claim. | |
| build: | |
| name: Build ${{ matrix.image.name }} (${{ matrix.arch.platform }}) | |
| runs-on: ${{ matrix.arch.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - { name: decree, dockerfile: build/Dockerfile } | |
| - { name: decree-cli, dockerfile: build/Dockerfile.decree } | |
| arch: | |
| - { platform: linux/amd64, runner: ubuntu-latest, suffix: amd64 } | |
| - { platform: linux/arm64, runner: ubuntu-24.04-arm, suffix: arm64 } | |
| env: | |
| IMAGE_REF: ${{ format('ghcr.io/{0}/{1}', github.repository_owner, matrix.image.name) }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to ghcr.io | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push by digest | |
| id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: ${{ matrix.image.dockerfile }} | |
| platforms: ${{ matrix.arch.platform }} | |
| build-args: | | |
| VERSION=main | |
| COMMIT=${{ github.sha }} | |
| # Per-arch buildcache tags so each architecture's layers stay | |
| # cleanly separated. Mixing them under a single tag confuses | |
| # cache-from when a downstream workflow only wants one arch. | |
| cache-from: type=registry,ref=${{ env.IMAGE_REF }}:buildcache-${{ matrix.arch.suffix }} | |
| cache-to: type=registry,ref=${{ env.IMAGE_REF }}:buildcache-${{ matrix.arch.suffix }},mode=max | |
| # push-by-digest pushes the image WITHOUT a tag, returning only | |
| # the manifest digest. The manifest job collects the digests | |
| # and assembles the final multi-arch tag. | |
| outputs: type=image,name=${{ env.IMAGE_REF }},push-by-digest=true,name-canonical=true,push=true | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| # Image name LAST so the manifest job's download pattern | |
| # (`digests-*-<image>`) doesn't accidentally match a different | |
| # image whose name starts with this one (decree vs decree-cli). | |
| name: digests-${{ matrix.arch.suffix }}-${{ matrix.image.name }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # One manifest job per image. Combines the per-arch digests into a | |
| # single multi-arch :main tag, the same shape consumers see today. | |
| manifest: | |
| name: Manifest ${{ matrix.image }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: [decree, decree-cli] | |
| env: | |
| IMAGE_REF: ${{ format('ghcr.io/{0}/{1}', github.repository_owner, matrix.image) }} | |
| steps: | |
| - name: Download digest artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-*-${{ matrix.image }} | |
| merge-multiple: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to ghcr.io | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create multi-arch manifest | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| --tag "${{ env.IMAGE_REF }}:main" \ | |
| $(printf '${{ env.IMAGE_REF }}@sha256:%s ' *) | |
| - name: Inspect manifest | |
| run: docker buildx imagetools inspect "${{ env.IMAGE_REF }}:main" | |
| # Rebuilds and deploys the MkDocs site to GitHub Pages whenever docs/ changes. | |
| docs: | |
| name: Deploy docs | |
| runs-on: ubuntu-latest | |
| if: contains(join(github.event.commits.*.modified, ','), 'docs/') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - name: Deploy to GitHub Pages | |
| # squidfunk/mkdocs-material:9.7.6 | |
| run: > | |
| docker run --rm | |
| -v ${{ github.workspace }}:/docs | |
| squidfunk/mkdocs-material@sha256:868ad4d39fb5865b72d00173ade00f4eae2b38dde7ff790a011cc44ce4a8ff8e | |
| gh-deploy --force |