name: Service Image

on:
  pull_request:
    branches: [main]
    paths:
      - "crates/kache-service/**"
      - "docker/**"
      - "docker-bake.hcl"
      - "Justfile"
      - ".github/workflows/service-image.yml"
  push:
    branches: [main]
    tags: ["v*"]
    paths:
      - "crates/kache-service/**"
      - "docker/**"
      - "docker-bake.hcl"
      - "Justfile"
      - ".github/workflows/service-image.yml"
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  docker-dry-run:
    if: github.event_name == 'pull_request'
    name: Build Service Image (Dry Run)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: docker/setup-buildx-action@v4
      - name: Build image (dry-run, no cache)
        run: docker buildx bake -f docker-bake.hcl --set '*.cache-from=' service

  release:
    if: github.event_name != 'pull_request'
    name: Build Service Image
    runs-on: ubuntu-latest
    permissions:
      contents: read
      actions: read # read CI job conclusions for the pushed commit (gate below)
    steps:
      - uses: actions/checkout@v6

      - name: Check tag matches manifest (tag builds)
        # A versioned image tag is derived from the git tag (see "Derive release
        # metadata"); gate it on the same version-consistency check as the
        # release so a drifted tag can't ship a mislabeled `zondax/...:X.Y.Z`
        # image even though crates.io publishing is blocked. No-op on `edge`
        # (non-tag main) builds.
        if: github.ref_type == 'tag'
        run: ./scripts/check-version-consistency.sh "$GITHUB_REF_NAME"

      - name: Require CI green for this commit
        # Don't push an image built from a commit whose CI hasn't passed. The
        # `Check (Linux)` job runs the full `just ci` (which compiles
        # kache-service), so it's the relevant gate for the image.
        env:
          GH_TOKEN: ${{ github.token }}
        run: ./scripts/require-ci-green.sh "$(git rev-parse HEAD)" "Check (Linux)"

      - uses: jdx/mise-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/setup-qemu-action@v4

      - uses: docker/setup-buildx-action@v4

      - uses: docker/login-action@v4
        with:
          username: ${{ secrets.DOCKERHUB_USER }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Derive release metadata
        id: meta
        run: |
          if [[ "${GITHUB_REF_TYPE}" == "tag" && "${GITHUB_REF_NAME}" == v* ]]; then
            VERSION="${GITHUB_REF_NAME#v}"
            IMAGE_TAG="${VERSION}"
            BUILD_VERSION="${GITHUB_REF_NAME}"
          else
            VERSION="0.0.0"
            # Non-tag main builds: `edge` (the dev branch is gone under the
            # trunk-based model, so a `dev` image tag no longer maps to anything).
            IMAGE_TAG="edge"
            BUILD_VERSION="${GITHUB_REF_NAME}"
          fi
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
          echo "build_version=${BUILD_VERSION}" >> "$GITHUB_OUTPUT"
          echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"

      - name: Push service image
        env:
          REGISTRY: zondax
          VERSION: ${{ steps.meta.outputs.version }}
          IMAGE_TAG: ${{ steps.meta.outputs.image_tag }}
          BUILD_VERSION: ${{ steps.meta.outputs.build_version }}
          BUILD_COMMIT: ${{ github.sha }}
          BUILD_DATE: ${{ steps.meta.outputs.build_date }}
        run: just image-service-release
