name: Build & Push Docker Image

# Multi-arch build using NATIVE runners for each platform, then a
# manifest-list push. No QEMU emulation — amd64 builds on x86 runner,
# arm64 builds on ubuntu-24.04-arm runner. argon2 and every other
# native dep compile natively on their target arch.
#
# Result: `danielonyejesi/pediatric-ai-scribe-v3:X.Y.Z` (and :latest)
# is one tag serving the correct variant to amd64 or arm64 hosts.

on:
  push:
    tags: ['v*']
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to publish (e.g. v6.2.0)'
        required: false
        default: 'latest'

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
  IMAGE: danielonyejesi/pediatric-ai-scribe-v3

jobs:
  build:
    # Build one variant per matrix entry, push by digest only.
    name: Build ${{ matrix.platform }}
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: linux/amd64
            runner: ubuntu-latest
          - platform: linux/arm64
            runner: ubuntu-24.04-arm
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Docker metadata (for labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.IMAGE }}

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build & push by digest
        id: build
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: ${{ matrix.platform }}
          labels: ${{ steps.meta.outputs.labels }}
          outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
          cache-from: type=gha,scope=${{ matrix.platform }}
          cache-to: type=gha,mode=max,scope=${{ matrix.platform }}

      - name: Export digest for the merge job
        run: |
          mkdir -p /tmp/digests
          DIG="${{ steps.build.outputs.digest }}"
          touch "/tmp/digests/${DIG#sha256:}"

      - name: Upload digest artifact
        uses: actions/upload-artifact@v4
        with:
          name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
          path: /tmp/digests/*
          if-no-files-found: error
          retention-days: 1

  merge:
    # Combine the two single-platform digests into one multi-arch manifest
    # published under the real tags (vX.Y.Z and latest).
    name: Merge manifests
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download digests
        uses: actions/download-artifact@v4
        with:
          path: /tmp/digests
          pattern: digests-*
          merge-multiple: true

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Resolve tag
        id: tag
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "tag=${{ github.event.inputs.tag || 'latest' }}" >> $GITHUB_OUTPUT
          else
            echo "tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
          fi

      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.IMAGE }}
          tags: |
            type=raw,value=${{ steps.tag.outputs.tag }}
            type=raw,value=latest

      - name: Create manifest list & push
        working-directory: /tmp/digests
        run: |
          docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
            $(printf "${{ env.IMAGE }}@sha256:%s " *)

      - name: Inspect final image
        run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.tag.outputs.tag }}

      - name: Summary
        run: |
          echo "### Multi-arch image published" >> $GITHUB_STEP_SUMMARY
          echo "- \`${{ env.IMAGE }}:${{ steps.tag.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
          echo "- \`${{ env.IMAGE }}:latest\`" >> $GITHUB_STEP_SUMMARY
          echo "- Platforms: linux/amd64, linux/arm64 (built on native runners)" >> $GITHUB_STEP_SUMMARY
