# The release controller locates release runs by the default title (the tag),
# so this workflow must not set run-name.
name: Trigger Build Release

permissions:
  contents: read

on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      version:
        description: Version of Valkey to build
        required: true
      environment:
        description: Environment to build
        required: true
        type: choice
        options:
          - dev
          - prod

jobs:
  trigger:
    runs-on: ubuntu-latest
    steps:
      - name: Determine version and environment
        id: determine-vars
        env:
          EVENT_NAME: ${{ github.event_name }}
          RELEASE_TAG: ${{ github.event.release.tag_name }}
          INPUT_VERSION: ${{ inputs.version }}
          INPUT_ENVIRONMENT: ${{ inputs.environment }}
        run: |
          set -euo pipefail
          if [[ "${EVENT_NAME}" == "release" ]]; then
            echo "Triggered by a release event."
            VERSION="${RELEASE_TAG}"
            ENVIRONMENT="prod"
          else
            echo "Triggered manually (workflow_dispatch)."
            VERSION="${INPUT_VERSION}"
            ENVIRONMENT="${INPUT_ENVIRONMENT}"
          fi
          if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$ && "${VERSION}" != "unstable" ]]; then
            echo "::error::Invalid version: ${VERSION}"
            exit 1
          fi
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          echo "environment=${ENVIRONMENT}" >> "$GITHUB_OUTPUT"

      - name: Resolve version tag to its commit
        id: resolve-sha
        env:
          GH_TOKEN: ${{ github.token }}
          EVENT_NAME: ${{ github.event_name }}
          REPO: ${{ github.repository }}
          VERSION: ${{ steps.determine-vars.outputs.version }}
          ENVIRONMENT: ${{ steps.determine-vars.outputs.environment }}
        run: |
          set -euo pipefail
          resolve_tag() {
            local tag="$1" level="$2" ref_json obj_json obj_type obj_sha
            ref_json=$(gh api "repos/${REPO}/git/ref/tags/${tag}") || return 1
            obj_type=$(jq -r '.object.type' <<< "$ref_json")
            obj_sha=$(jq -r '.object.sha' <<< "$ref_json")
            if [[ "$obj_type" == "tag" ]]; then
              obj_json=$(gh api "repos/${REPO}/git/tags/${obj_sha}") || return 1
              obj_type=$(jq -r '.object.type' <<< "$obj_json")
              obj_sha=$(jq -r '.object.sha' <<< "$obj_json")
            fi
            if [[ "$obj_type" != "commit" ]]; then
              echo "::${level}::Tag ${tag} does not peel to a commit (got object type '${obj_type}')." >&2
              return 1
            fi
            printf '%s' "$obj_sha"
          }
          if [[ "$EVENT_NAME" == "release" ]]; then
            SOURCE_SHA=$(resolve_tag "$VERSION" error)
          elif [[ "$ENVIRONMENT" == "prod" ]]; then
            # Production builds require an existing tag.
            if ! SOURCE_SHA=$(resolve_tag "$VERSION" error); then
              echo "::error::Could not resolve tag ${VERSION} to a commit; a prod dispatch requires an existing, resolvable tag."
              exit 1
            fi
          else
            # Development builds may use an untagged version.
            SOURCE_SHA=$(resolve_tag "$VERSION" warning) || SOURCE_SHA=""
          fi
          if [[ -n "$SOURCE_SHA" && ! "$SOURCE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
            echo "::error::Resolved source_sha is not a full lowercase 40-hex commit: ${SOURCE_SHA}"
            exit 1
          fi
          echo "source_sha=${SOURCE_SHA}" >> "$GITHUB_OUTPUT"

      - name: Compose dispatch payload
        id: compose-payload
        env:
          VERSION: ${{ steps.determine-vars.outputs.version }}
          ENVIRONMENT: ${{ steps.determine-vars.outputs.environment }}
          SOURCE_SHA: ${{ steps.resolve-sha.outputs.source_sha }}
        run: |
          set -euo pipefail
          PAYLOAD=$(jq -cn \
            --arg version "$VERSION" \
            --arg environment "$ENVIRONMENT" \
            --arg source_sha "$SOURCE_SHA" \
            '{version: $version, environment: $environment, source_sha: $source_sha}')
          echo "payload=${PAYLOAD}" >> "$GITHUB_OUTPUT"

      - name: Generate token
        id: generate-token
        if: github.repository_owner == 'valkey-io'
        uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
        with:
          app-id: ${{ secrets.VALKEYRIE_BOT_APP_ID }}
          private-key: ${{ secrets.VALKEYRIE_BOT_PRIVATE_KEY }}
          owner: ${{ github.repository_owner }}
          repositories: valkey-release-automation
          permission-contents: write

      - name: Trigger build
        uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
        with:
          token: ${{ github.repository_owner == 'valkey-io' && steps.generate-token.outputs.token || secrets.AUTOMATION_PAT }}
          repository: ${{ github.repository_owner }}/valkey-release-automation
          event-type: build-release
          client-payload: ${{ steps.compose-payload.outputs.payload }}
