Streamline/refactor GH pipelines #742
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: Docker | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - '*' | |
| pull_request: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-per-architecture: | |
| if: github.repository_owner == 'pitkley' && github.actor != 'dependabot[bot]' | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| matrix: | |
| include: | |
| - platform: linux/amd64 | |
| runner: ubuntu-24.04 | |
| arch: amd64 | |
| - platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| arch: arm64 | |
| - platform: linux/arm/v7 | |
| runner: ubuntu-24.04 #-arm | |
| arch: armv7 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU | |
| if: matrix.arch == 'armv7' | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: arm | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to ghcr.io | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ github.token }} | |
| - name: Build and push by digest to GHCR | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| outputs: type=image,name=ghcr.io/pitkley/dfw,push-by-digest=true,name-canonical=true,push=true | |
| cache-from: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} | |
| cache-to: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-${{ matrix.arch }} | |
| path: /tmp/digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| merge-manifests: | |
| if: github.repository_owner == 'pitkley' && github.actor != 'dependabot[bot]' | |
| permissions: | |
| contents: read | |
| packages: write | |
| attestations: write | |
| id-token: write | |
| runs-on: ubuntu-24.04 | |
| needs: build-per-architecture | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/digests | |
| pattern: digests-* | |
| merge-multiple: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| if: github.event_name == 'push' | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_ACCESSTOKEN }} | |
| - name: Login to ghcr.io | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ github.token }} | |
| - name: Prepare Docker image metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: | | |
| ${{ github.event_name == 'push' && 'pitkley/dfw' || '' }} | |
| ghcr.io/pitkley/dfw | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| - name: Get execution timestamp with RFC3339 format | |
| id: timestamp | |
| run: | | |
| echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT | |
| - name: Create manifest list and push to GHCR | |
| working-directory: /tmp/digests | |
| run: | | |
| docker buildx imagetools create \ | |
| $(jq -cr '.tags | map(select(startswith("ghcr.io"))) | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| --annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \ | |
| --annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \ | |
| --annotation='index:org.opencontainers.image.source=${{ github.event.repository.html_url }}' \ | |
| $(printf 'ghcr.io/pitkley/dfw@sha256:%s ' *) | |
| - name: Inspect GHCR image | |
| run: | | |
| docker buildx imagetools inspect ghcr.io/pitkley/dfw:${{ steps.meta.outputs.version }} | |
| - name: Copy multi-arch image from GHCR to Docker Hub | |
| if: github.event_name == 'push' | |
| run: | | |
| # Extract all Docker Hub tags from metadata | |
| dockerhub_tags=$(jq -cr '.tags | map(select(startswith("pitkley/dfw"))) | .[]' <<< "$DOCKER_METADATA_OUTPUT_JSON") | |
| # Copy the merged image from GHCR to Docker Hub for each tag | |
| for tag in $dockerhub_tags; do | |
| echo "Copying to $tag" | |
| docker buildx imagetools create \ | |
| --tag "$tag" \ | |
| ghcr.io/pitkley/dfw:${{ steps.meta.outputs.version }} | |
| done | |
| - name: Inspect Docker Hub image | |
| if: github.event_name == 'push' | |
| run: | | |
| docker buildx imagetools inspect pitkley/dfw:${{ steps.meta.outputs.version }} |