name: Build and push a Docker image

on:
    push:
        branches: ["main"]
        tags: ["v*.*.*"]
    workflow_dispatch:
        inputs:
            git_ref:
                description: 'Git Ref (Branch, Tag or Release)'
                required: true
                default: 'main'
                type: string
            image_name:
                description: 'Docker image name (api, web, or both)'
                required: true
                default: 'both'
                type: choice
                options:
                    - api
                    - web
                    - both

env:
    # Use docker.io for Docker Hub if empty
    REGISTRY: ghcr.io
    # github.repository as <account>/<repo>
    #IMAGE_NAME: ${{ github.repository }}

jobs:
    build:
        name: Build and push Docker image
        runs-on: ubuntu-latest
        permissions:
            contents: read
            packages: write
            # This is used to complete the identity challenge
            # with sigstore/fulcio when running outside of PRs.
            id-token: write

        steps:
            - name: Checkout repository
              uses: actions/checkout@v4
              with:
                  ref: ${{ github.event.inputs.git_ref || github.ref }}

            - name: Set up QEMU
              uses: docker/setup-qemu-action@v2
              with:
                  platforms: "arm64,amd64"

            # Workaround: https://github.com/docker/build-push-action/issues/461
            - name: Setup Docker buildx
              uses: docker/setup-buildx-action@v2

            # Login against a Docker registry except on PR
            # https://github.com/docker/login-action
            - name: Log into registry ${{ env.REGISTRY }}
              if: github.event_name != 'pull_request'
              uses: docker/login-action@v2
              with:
                  registry: ${{ env.REGISTRY }}
                  username: ${{ github.actor }}
                  password: ${{ secrets.GITHUB_TOKEN }}

            # Extract metadata (tags, labels) for Docker
            # https://github.com/docker/metadata-action
            - name: Extract Docker metadata for API
              id: meta-api
              if: ${{ github.event.inputs.image_name == 'api' || github.event.inputs.image_name == 'both' || github.event_name != 'workflow_dispatch' }}
              uses: docker/metadata-action@v5
              with:
                  github-token: ${{ secrets.GITHUB_TOKEN }}
                  images: ${{ env.REGISTRY }}/${{ github.repository }}/api
                  tags: |
                      type=raw,value=latest,enable={{is_default_branch}}
                      type=semver,pattern=v{{version}}
                      type=semver,pattern=v{{major}}.{{minor}}
                      type=semver,pattern=v{{major}}
                      type=raw,value=${{ github.event.inputs.git_ref }},enable=${{ github.event_name == 'workflow_dispatch' }}

            # Build and push Docker image with Buildx (don't push on PR)
            # https://github.com/docker/build-push-action
            - name: Build and push Docker image for API
              id: build-and-push-api
              if: ${{ github.event.inputs.image_name == 'api' || github.event.inputs.image_name == 'both' || github.event_name != 'workflow_dispatch' }}
              uses: docker/build-push-action@v5
              with:
                  context: api
                  build-args: VERSION=${{ github.event.inputs.git_ref || github.ref_name }}
                  push: ${{ github.event_name != 'pull_request' }}
                  tags: ${{ steps.meta-api.outputs.tags }}
                  platforms: linux/amd64,linux/arm64
                  labels: ${{ steps.meta-api.outputs.labels }}

            # Extract metadata (tags, labels) for Docker
            # https://github.com/docker/metadata-action
            - name: Extract Docker metadata for Web
              id: meta-web
              if: ${{ github.event.inputs.image_name == 'web' || github.event.inputs.image_name == 'both' || github.event_name != 'workflow_dispatch' }}
              uses: docker/metadata-action@v5
              with:
                  github-token: ${{ secrets.GITHUB_TOKEN }}
                  images: ${{ env.REGISTRY }}/${{ github.repository }}/web
                  tags: |
                      type=raw,value=latest,enable={{is_default_branch}}
                      type=semver,pattern=v{{version}}
                      type=semver,pattern=v{{major}}.{{minor}}
                      type=semver,pattern=v{{major}}
                      type=raw,value=${{ github.event.inputs.git_ref }},enable=${{ github.event_name == 'workflow_dispatch' }}

            # Build and push Docker image with Buildx (don't push on PR)
            # https://github.com/docker/build-push-action
            - name: Build and push Docker image for Web
              id: build-and-push-web
              if: ${{ github.event.inputs.image_name == 'web' || github.event.inputs.image_name == 'both' || github.event_name != 'workflow_dispatch' }}
              uses: docker/build-push-action@v5
              with:
                  context: web
                  build-args: VERSION=${{ github.event.inputs.git_ref || github.ref_name }}
                  push: ${{ github.event_name != 'pull_request' }}
                  tags: ${{ steps.meta-web.outputs.tags }}
                  platforms: linux/amd64,linux/arm64
                  labels: ${{ steps.meta-web.outputs.labels }}