Build and Push Container #81
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
| # Workflow: Build and Push Docker Container | |
| # Description: Builds and pushes Docker image for the Auth service whenever code is pushed to main branch. | |
| # Why: Provides reproducible, versioned container images for deployments. | |
| # Note: AMD64 and ARM64 builds run in parallel for faster builds, then merged into multi-platform manifests. | |
| name: Build and Push Container | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| # Build auth images for each architecture in parallel | |
| build-auth: | |
| runs-on: ubuntu-latest | |
| # Allow ARM64 builds to fail without failing the workflow | |
| continue-on-error: ${{ matrix.platform == 'linux/arm64' }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: | |
| - linux/amd64 | |
| - linux/arm64 | |
| steps: | |
| - name: Prepare platform pair | |
| run: | | |
| platform=${{ matrix.platform }} | |
| echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| driver-opts: | | |
| image=moby/buildkit:latest | |
| network=host | |
| - name: Log in to the Container registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for Auth | |
| id: meta-auth | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| - name: Build and push Auth image by digest | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| platforms: ${{ matrix.platform }} | |
| labels: ${{ steps.meta-auth.outputs.labels }} | |
| cache-from: type=gha,scope=auth-${{ env.PLATFORM_PAIR }} | |
| cache-to: type=gha,mode=max,scope=auth-${{ env.PLATFORM_PAIR }} | |
| provenance: false | |
| outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true | |
| - name: Export digest | |
| run: | | |
| mkdir -p /tmp/digests/auth | |
| digest="${{ steps.build.outputs.digest }}" | |
| touch "/tmp/digests/auth/${digest#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: digests-auth-${{ env.PLATFORM_PAIR }} | |
| path: /tmp/digests/auth/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| # Merge Auth digests into multi-platform manifest | |
| merge-auth: | |
| runs-on: ubuntu-latest | |
| needs: build-auth | |
| # Run even if ARM64 build failed (as long as not cancelled) | |
| if: always() && !cancelled() | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Download digests | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/digests/auth | |
| pattern: digests-auth-* | |
| merge-multiple: true | |
| - name: Check for digests | |
| id: check | |
| run: | | |
| if [ -d "/tmp/digests/auth" ] && [ "$(ls -A /tmp/digests/auth 2>/dev/null)" ]; then | |
| echo "has_digests=true" >> $GITHUB_OUTPUT | |
| echo "Found digests:" | |
| ls -la /tmp/digests/auth | |
| else | |
| echo "has_digests=false" >> $GITHUB_OUTPUT | |
| echo "No digests found, skipping manifest creation" | |
| fi | |
| - name: Set up Docker Buildx | |
| if: steps.check.outputs.has_digests == 'true' | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to the Container registry | |
| if: steps.check.outputs.has_digests == 'true' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for Auth | |
| if: steps.check.outputs.has_digests == 'true' | |
| id: meta-auth | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=latest | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| - name: Create manifest list and push | |
| if: steps.check.outputs.has_digests == 'true' | |
| working-directory: /tmp/digests/auth | |
| run: | | |
| docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | |
| $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) | |
| - name: Inspect image | |
| if: steps.check.outputs.has_digests == 'true' | |
| run: | | |
| docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest |