Docker #32
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: | |
| workflow_dispatch: | |
| inputs: | |
| set_latest_tag: | |
| description: 'Set to true to tag the image with `latest`' | |
| required: true | |
| default: false | |
| type: boolean | |
| env: | |
| REGISTRY: docker.io | |
| IMAGE_NAME: fanout/pushpin | |
| SET_LATEST: ${{ github.event.inputs.set_latest_tag }} | |
| jobs: | |
| build: | |
| # We use a matrix to run each docker container build for a specific platform on it's own native runner. | |
| # This avoids using virtualization and massively speeds up builds. | |
| strategy: | |
| matrix: | |
| platform: [linux/amd64, linux/arm64] | |
| include: | |
| - platform: linux/amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| runner: ubuntu-24.04-arm | |
| name: Build ${{ matrix.platform }} | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - name: Code checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Get source version | |
| run: echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV" | |
| - name: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| flavor: | | |
| latest=${{ env.SET_LATEST }} | |
| tags: | | |
| type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }} | |
| - name: Derive arch-suffixed tags as output | |
| id: archtags | |
| run: | | |
| set -euo pipefail | |
| ARCH="$(echo '${{ matrix.platform }}' | cut -d/ -f2)" | |
| T="$(printf '%s\n' "${{ steps.meta.outputs.tags }}" | sed "s/$/-${ARCH}/")" | |
| { | |
| echo 'tags<<EOF' | |
| echo "$T" | |
| echo 'EOF' | |
| echo "arch=$ARCH" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Login to ${{ env.REGISTRY }} | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Build & push ${{ matrix.platform }} | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| push: ${{ github.event_name != 'pull_request' }} | |
| build-args: | | |
| VERSION=${{ env.SOURCE_VERSION }} | |
| tags: ${{ steps.archtags.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| # In order to have a single tag that covers both archtectures we run one more job to create a multi-arch manifest | |
| # under a single tag. | |
| manifest: | |
| name: Create multi-arch manifest | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Code checkout | |
| uses: actions/checkout@v4 | |
| - name: Get source version | |
| run: echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV" | |
| - name: Docker meta (same base tags) | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| flavor: | | |
| latest=${{ env.SET_LATEST }} | |
| tags: | | |
| type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }} | |
| - name: Login | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Create manifest for each base tag | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| set -euo pipefail | |
| while IFS= read -r BASE; do | |
| echo "Preparing manifest for $BASE" | |
| AMD="${BASE}-amd64" | |
| ARM="${BASE}-arm64" | |
| # Skip if one arch is missing | |
| docker buildx imagetools inspect "$AMD" | |
| docker buildx imagetools inspect "$ARM" | |
| docker buildx imagetools create \ | |
| --tag "$BASE" \ | |
| "$AMD" \ | |
| "$ARM" | |
| echo "OK: $BASE now points to $AMD + $ARM" | |
| done <<'EOF' | |
| ${{ steps.meta.outputs.tags }} | |
| EOF |