name: Publish Docker Image

on:
  release:
    types:
      - published
  workflow_dispatch:
    inputs:
      tag:
        description: Stable tag to publish manually, for example v7.55.0
        required: true
        type: string

concurrency:
  group: docker-release-${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag || github.ref }}
  cancel-in-progress: false

jobs:
  publish:
    if: ${{ github.event_name != 'release' || !github.event.release.prerelease }}
    runs-on: ubuntu-latest

    permissions:
      contents: read
      packages: write

    steps:
      - name: Resolve target tag
        id: target
        env:
          MANUAL_TAG: ${{ inputs.tag }}
          RELEASE_EVENT_TAG: ${{ github.event.release.tag_name }}
        run: |
          if [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then
            TARGET_TAG="${RELEASE_EVENT_TAG}"
          else
            TARGET_TAG="${MANUAL_TAG}"
          fi

          echo "tag=${TARGET_TAG}" >> "$GITHUB_OUTPUT"

      - name: Validate stable semver tag
        id: tag
        run: |
          if [[ "${{ steps.target.outputs.tag }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "publish=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi

          echo "publish=false" >> "$GITHUB_OUTPUT"
          echo "Skipping non-stable semver tag ${{ steps.target.outputs.tag }}"

      - name: Checkout release tag
        if: steps.tag.outputs.publish == 'true'
        uses: actions/checkout@v4
        with:
          ref: ${{ steps.target.outputs.tag }}

      - name: Set up QEMU
        if: steps.tag.outputs.publish == 'true'
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        if: steps.tag.outputs.publish == 'true'
        uses: docker/setup-buildx-action@v3

      - name: Derive image metadata
        if: steps.tag.outputs.publish == 'true'
        id: meta
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION="${{ steps.target.outputs.tag }}"
          VERSION="${VERSION#v}"
          MINOR="${VERSION%.*}"
          MAJOR="${VERSION%%.*}"
          OWNER_LOWER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')
          IMAGE="ghcr.io/${OWNER_LOWER}/ccs-dashboard"
          REVISION=$(git rev-parse HEAD)
          TAGS="${IMAGE}:${VERSION}"

          if [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then
            TAGS="${TAGS}
          ${IMAGE}:${MINOR}
          ${IMAGE}:${MAJOR}
          ${IMAGE}:latest"
          fi

          {
            echo "version=${VERSION}"
            echo "minor=${MINOR}"
            echo "major=${MAJOR}"
            echo "image=${IMAGE}"
            echo "revision=${REVISION}"
            echo "tags<<EOF"
            echo "${TAGS}"
            echo "EOF"
          } >> "$GITHUB_OUTPUT"

      - name: Log in to GitHub Container Registry
        if: steps.tag.outputs.publish == 'true'
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push release image
        if: steps.tag.outputs.publish == 'true'
        uses: docker/build-push-action@v6
        with:
          context: .
          file: docker/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: |
            org.opencontainers.image.title=ccs-dashboard
            org.opencontainers.image.description=CCS Dashboard container image
            org.opencontainers.image.url=https://github.com/${{ github.repository }}
            org.opencontainers.image.source=https://github.com/${{ github.repository }}
            org.opencontainers.image.version=${{ steps.meta.outputs.version }}
            org.opencontainers.image.revision=${{ steps.meta.outputs.revision }}
          annotations: |
            index:org.opencontainers.image.source=https://github.com/${{ github.repository }}
            index:org.opencontainers.image.description=CCS Dashboard container image
          cache-from: type=gha
          cache-to: type=gha,mode=max
