name: Docker Image CI

on:
    push:
        tags: ["*"]

env:
    REGISTRY: ghcr.io
    IMAGE_NAME: ${{ github.repository }}

jobs:
    build:
        name: Build multi-platform Docker image
        runs-on: ubuntu-22.04

        permissions:
            contents: read
            packages: write
            id-token: write
            attestations: write

        strategy:
            fail-fast: false
            matrix:
                platform:
                    - linux/amd64
                    # - linux/arm/v6
                    # - linux/arm/v7
                    - linux/arm64
        steps:
            - name: Prepare
              run: |
                  platform=${{ matrix.platform }}
                  echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

            - name: Docker meta
              id: meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

            - name: Set up QEMU
              uses: docker/setup-qemu-action@v3

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

            - name: Login to registry
              uses: docker/login-action@v3
              with:
                  registry: ${{ env.REGISTRY }}
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}

            - name: Build and push by digest
              id: build
              uses: docker/build-push-action@v6
              with:
                  platforms: ${{ matrix.platform }}
                  labels: ${{ steps.meta.outputs.labels }}
                  outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
                  cache-from: type=gha
                  cache-to: type=gha,mode=max
                  build-args: |
                      VERSION=${{ github.ref_name }}

            - name: Generate artifact attestation
              uses: actions/attest-build-provenance@v1
              with:
                  subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
                  subject-digest: ${{ steps.build.outputs.digest }}
                  push-to-registry: true

            - 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-${{ env.PLATFORM_PAIR }}
                  path: /tmp/digests/*
                  if-no-files-found: error
                  retention-days: 1
    merge:
        runs-on: ubuntu-22.04
        needs:
            - build
        permissions:
            contents: read
            packages: write
            id-token: write
        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: Docker meta
              id: meta
              uses: docker/metadata-action@v5
              with:
                  images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

            - name: Login to registry
              uses: docker/login-action@v3
              with:
                  registry: ${{ env.REGISTRY }}
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}

            - name: Create manifest list and push
              id: push
              working-directory: /tmp/digests
              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
              run: |
                  docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
