name: "🐳 Publish Webapp"

permissions:
  contents: read
  packages: write
  id-token: write
  attestations: write

on:
  workflow_call:
    inputs:
      image_tag:
        description: The image tag to publish
        type: string
        required: false
        default: ""
      image_registry:
        description: The registry namespace to publish under (e.g. ghcr.io/<owner>)
        type: string
        required: false
        default: ""
    outputs:
      version:
        description: The published image tag
        value: ${{ jobs.publish.outputs.version }}
      short_sha:
        description: Short commit SHA of the published build
        value: ${{ jobs.publish.outputs.short_sha }}
      image_repo:
        description: The image repository the build was published to (without tag)
        value: ${{ jobs.publish.outputs.image_repo }}
      digest:
        description: Multi-arch index digest (sha256:...) of the published image
        value: ${{ jobs.publish.outputs.digest }}
    secrets:
      SENTRY_AUTH_TOKEN:
        required: false

jobs:
  publish:
    runs-on: warp-ubuntu-latest-x64-2x
    env:
      PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: 1
    outputs:
      version: ${{ steps.get_tag.outputs.tag }}
      short_sha: ${{ steps.get_commit.outputs.sha_short }}
      image_repo: ${{ steps.set_tags.outputs.image_repo }}
      digest: ${{ steps.build_push.outputs.digest }}
    steps:
      - name: 🏭 Setup Depot CLI
        uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1

      - name: ⬇️ Checkout repo
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          submodules: recursive
          persist-credentials: false

      - name: "#️⃣ Get the image tag"
        id: get_tag
        uses: ./.github/actions/get-image-tag
        with:
          tag: ${{ inputs.image_tag }}

      - name: 🔢 Get the commit hash
        id: get_commit
        run: |
          echo "sha_short=$(echo "${GITHUB_SHA}" | cut -c1-7)" >> "$GITHUB_OUTPUT"

      - name: 📛 Set the tags
        id: set_tags
        run: |
          # The registry namespace is resolved by the caller (defaulting to
          # ghcr.io/<owner>, overridable via the IMAGE_REGISTRY repository
          # variable); the webapp image lives at <registry>/<repo-name>. A fork
          # therefore publishes to its own package automatically.
          image_tags=$REF_WITHOUT_TAG:${STEPS_GET_TAG_OUTPUTS_TAG}

          if [[ "${STEPS_GET_TAG_OUTPUTS_TAG}" =~ ^v4\.[0-9]+\.[0-9]+$ ]]; then
            image_tags=$image_tags,$REF_WITHOUT_TAG:v4,$REF_WITHOUT_TAG:latest
          fi

          # when pushing the mutable main tag, also push an immutable-by-convention
          # full-commit-sha tag so a commit can be resolved to a specific digest
          if [[ "${STEPS_GET_TAG_OUTPUTS_TAG}" == "main" ]]; then
            image_tags=$image_tags,$REF_WITHOUT_TAG:${GITHUB_SHA}
          fi

          echo "image_tags=${image_tags}" >> "$GITHUB_OUTPUT"
          echo "image_repo=${REF_WITHOUT_TAG}" >> "$GITHUB_OUTPUT"
        env:
          REF_WITHOUT_TAG: ${{ format('{0}/{1}', inputs.image_registry || vars.IMAGE_REGISTRY || format('ghcr.io/{0}', github.repository_owner), github.event.repository.name) }}
          STEPS_GET_TAG_OUTPUTS_TAG: ${{ steps.get_tag.outputs.tag }}
          STEPS_GET_TAG_OUTPUTS_IS_SEMVER: ${{ steps.get_tag.outputs.is_semver }}

      - name: 📝 Set the build info
        id: set_build_info
        run: |
          {
            tag="${STEPS_GET_TAG_OUTPUTS_TAG}"
            if [[ "${STEPS_GET_TAG_OUTPUTS_IS_SEMVER}" == true ]]; then
              echo "BUILD_APP_VERSION=${tag}"
            fi
            echo "BUILD_GIT_SHA=${GITHUB_SHA}"
            echo "BUILD_GIT_REF_NAME=${GITHUB_REF_NAME}"
            echo "BUILD_TIMESTAMP_SECONDS=$(date +%s)"
            echo "BUILD_TIMESTAMP_RFC3339=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
          } >> "$GITHUB_OUTPUT"
        env:
          STEPS_GET_TAG_OUTPUTS_TAG: ${{ steps.get_tag.outputs.tag }}
          STEPS_GET_TAG_OUTPUTS_IS_SEMVER: ${{ steps.get_tag.outputs.is_semver }}

      - name: 🐙 Login to GitHub Container Registry
        uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: 🐳 Build image and push to GitHub Container Registry
        id: build_push
        uses: depot/build-push-action@98e78adca7817480b8185f474a400b451d74e287 # v1.18.0
        with:
          file: ./docker/Dockerfile
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.set_tags.outputs.image_tags }}
          push: true
          build-args: |
            BUILD_APP_VERSION=${{ steps.set_build_info.outputs.BUILD_APP_VERSION }}
            BUILD_GIT_SHA=${{ steps.set_build_info.outputs.BUILD_GIT_SHA }}
            BUILD_GIT_REF_NAME=${{ steps.set_build_info.outputs.BUILD_GIT_REF_NAME }}
            BUILD_TIMESTAMP_SECONDS=${{ steps.set_build_info.outputs.BUILD_TIMESTAMP_SECONDS }}
            BUILD_TIMESTAMP_RFC3339=${{ steps.set_build_info.outputs.BUILD_TIMESTAMP_RFC3339 }}
            SENTRY_RELEASE=${{ steps.set_build_info.outputs.BUILD_GIT_SHA }}
            SENTRY_ORG=triggerdev
            SENTRY_PROJECT=trigger-cloud
          secrets: |
            sentry_auth_token=${{ secrets.SENTRY_AUTH_TOKEN }}

      - name: 🪪 Attest build provenance
        # Image is already pushed by this point — don't fail releases (and the
        # downstream publish-helm job) on a Sigstore/GHCR-referrer hiccup. Real
        # config errors still surface as a step warning in the workflow run.
        continue-on-error: true
        uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
        with:
          subject-name: ${{ steps.set_tags.outputs.image_repo }}
          subject-digest: ${{ steps.build_push.outputs.digest }}
          push-to-registry: true
