name: Build and Push MetadataRelay Docker Image

on:
  push:
    branches:
      - master
    paths:
      - 'metadata_relay/**'
      - '.github/workflows/metadata_relay.yaml'
  pull_request:
    paths:
      - 'metadata_relay/**'
      - '.github/workflows/metadata_relay.yaml'
  release:
    types: [ published ]
  workflow_dispatch:

jobs:
  lint-code:
    name: Lint Python Code
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v3
        with:
          src: "./metadata_relay"

  build:
    needs: lint-code
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: linux/arm64
            runner: ubuntu-24.04-arm
          - platform: linux/amd64
            runner: ubuntu-24.04
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set repository name to lowercase
        id: repo_name
        run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT

      - name: Prepare platform slug
        id: platform_slug
        run: echo "slug=${{ matrix.platform }}" | tr '/' '-' >> $GITHUB_OUTPUT

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

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract version
        id: version
        run: |
          if [[ "${{ github.event_name }}" == "release" ]]; then
            VERSION="${{ github.event.release.tag_name }}"
          elif [[ "${{ github.ref_type }}" == "tag" ]]; then
            VERSION="${{ github.ref_name }}"
          else
            DATE_STAMP=$(date -u +'%Y.%m.%d')
            VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Extract metadata (labels only)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay

      - name: Build and push by digest
        id: build
        uses: docker/build-push-action@v6
        with:
          context: ./metadata_relay
          file: ./metadata_relay/Dockerfile
          platforms: ${{ matrix.platform }}
          labels: ${{ steps.meta.outputs.labels }}
          outputs: type=image,name=ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
          cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/mediamanager:buildcache-${{ steps.platform_slug.outputs.slug }}
          cache-to: ${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref=ghcr.io/{0}/{1}/mediamanager:buildcache-{2},mode=max', github.repository_owner, steps.repo_name.outputs.name, steps.platform_slug.outputs.slug) || '' }}
          no-cache: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }}
          build-args: |
            VERSION=${{ steps.version.outputs.version }}

      - 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-relay-${{ strategy.job-index }}
          path: /tmp/digests/*
          if-no-files-found: error
          retention-days: 1

  merge:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
    steps:
      - name: Download digests
        uses: actions/download-artifact@v4
        with:
          pattern: digests-relay-*
          path: /tmp/digests
          merge-multiple: true

      - name: Set repository name to lowercase
        id: repo_name
        run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT

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

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract version
        id: version
        run: |
          if [[ "${{ github.event_name }}" == "release" ]]; then
            VERSION="${{ github.event.release.tag_name }}"
          elif [[ "${{ github.ref_type }}" == "tag" ]]; then
            VERSION="${{ github.ref_name }}"
          else
            DATE_STAMP=$(date -u +'%Y.%m.%d')
            VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Extract metadata (tags)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay
          tags: |
            type=raw,value=latest,enable=${{ github.event_name == 'release' }}
            type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.event_name != 'release' }}
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}
            type=sha

      - name: Create manifest list and push
        working-directory: /tmp/digests
        run: |
          docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
            $(printf 'ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay@sha256:%s ' *)

      - name: Inspect image
        run: |
          docker buildx imagetools inspect ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay:${{ steps.version.outputs.version }}