name: Release

on:
  push:
    tags:
      - 'v*.*.*'

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

jobs:
  build-platform:
    runs-on: ${{ matrix.runner }}
    permissions:
      contents: read
      packages: write
      id-token: write
    strategy:
      matrix:
        include:
          - platform: linux/amd64
            runner: ubuntu-latest
          - platform: linux/arm64
            runner: ubuntu-24.04-arm

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

      - 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: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}},enable=${{ !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc') }}
            type=semver,pattern={{major}},enable=${{ !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc') }}
            type=sha,prefix=sha-
          labels: |
            org.opencontainers.image.title=Barycenter
            org.opencontainers.image.description=OpenID Connect Identity Provider with federation and auto-registration
            org.opencontainers.image.vendor=${{ github.repository_owner }}
          flavor: |
            suffix=-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}

      - name: Build and push platform-specific image
        id: build
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: ${{ matrix.platform }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha,scope=${{ matrix.platform }}
          cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
          build-args: |
            VERSION=${{ github.ref_name }}
            REVISION=${{ github.sha }}

  create-manifest:
    runs-on: ubuntu-latest
    needs: build-platform
    permissions:
      contents: read
      packages: write
      id-token: write
      attestations: write

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

      - name: Extract metadata for manifest
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}},enable=${{ !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc') }}
            type=semver,pattern={{major}},enable=${{ !contains(github.ref_name, 'alpha') && !contains(github.ref_name, 'beta') && !contains(github.ref_name, 'rc') }}
            type=sha,prefix=sha-

      - name: Create and push multi-platform manifest
        id: manifest
        run: |
          # Extract tags into an array
          TAGS=$(echo '${{ steps.meta.outputs.tags }}' | tr '\n' ' ')

          # For each tag, create a manifest combining both platform images
          for TAG in $TAGS; do
            echo "Creating manifest for $TAG"
            docker buildx imagetools create -t $TAG \
              ${TAG}-amd64 \
              ${TAG}-arm64
          done

          # Get the digest of the first tag (version tag) for attestation
          FIRST_TAG=$(echo '${{ steps.meta.outputs.tags }}' | head -n1)
          DIGEST=$(docker buildx imagetools inspect ${FIRST_TAG} --raw | sha256sum | cut -d' ' -f1 | awk '{print "sha256:" $0}')
          echo "digest=${DIGEST}" >> $GITHUB_OUTPUT

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

  create-github-release:
    runs-on: ubuntu-latest
    needs: create-manifest
    permissions:
      contents: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate changelog
        id: changelog
        run: |
          # Get previous tag
          PREVIOUS_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1) 2>/dev/null || echo "")

          # Generate changelog
          if [ -z "$PREVIOUS_TAG" ]; then
            CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges)
          else
            CHANGELOG=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
          fi

          # Save to file for multiline output
          echo "$CHANGELOG" > /tmp/changelog.txt

          # Set output
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          cat /tmp/changelog.txt >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          body: |
            ## What's Changed

            ${{ steps.changelog.outputs.changelog }}

            ## Docker Images

            Pull the Docker image:
            ```bash
            docker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}
            ```

            Available platforms:
            - linux/amd64
            - linux/arm64

            ## Installation

            See [DEPLOYMENT.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/DEPLOYMENT.md) for installation instructions.
          draft: false
          prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
