Docker #33
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 | |
| build_version: | |
| description: 'The version of pushpin to build and push (ex: 1.40.1)' | |
| required: true | |
| type: string | |
| build_tag: | |
| description: 'The tag to use for the docker image (ex: 1.40.1) (ex: 1.40.1-2)' | |
| required: true | |
| type: string | |
| env: | |
| REGISTRY: docker.io | |
| IMAGE_NAME: fanout/pushpin | |
| SET_LATEST: ${{ github.event.inputs.set_latest_tag }} | |
| BUILD_VERSION: ${{ github.event.inputs.build_version }} | |
| BUILD_TAG: ${{ github.event.inputs.build_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: Docker meta | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| flavor: | | |
| latest=${{ env.SET_LATEST }} | |
| tags: | | |
| type=ref,event=branch,pattern={{branch}} | |
| type=semver,pattern={{version}},value=${{ env.BUILD_TAG }} | |
| - 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.BUILD_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: 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=ref,event=branch,pattern={{branch}} | |
| type=semver,pattern={{version}},value=${{ env.BUILD_TAG }} | |
| - 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 |