# Per-repo release workflow — tagged releases only
# Generated by machines/clean-room/deploy-workflows.sh — do not edit manually.
# Spec: docs/specifications/sovereign-stack-protected-branch-strategy.md
#
# Flow: tag push → clean-room gate → package verify → trusted publish → GitHub Release
#
# Tag formats:
#   v1.0.0              — single-crate repos
#   v-<crate>-1.0.0     — workspace repos (e.g. v-apr-cli-0.4.0)
#
# IMPORTANT: Tags must be pushed with a PAT or deploy key (not GITHUB_TOKEN),
# otherwise this workflow will not trigger (GitHub anti-recursion measure).

name: Release

on:
  push:
    tags: ['v*']

permissions:
  contents: write    # create GitHub Release
  id-token: write    # OIDC for crates.io Trusted Publishing

# One release at a time per repo
concurrency:
  group: release-${{ github.repository }}
  cancel-in-progress: false

jobs:
  # ── Gate: clean-room must pass before publish ───────────
  gate:
    uses: paiml/infra/.github/workflows/clean-room-gate.yml@ba2f56a7d9f421feef737b6b642b644bcdaba567 # pin to SHA
    with:
      repo: ${{ github.event.repository.name }}
      pr_sha: ${{ github.sha }}
    secrets: inherit

  # ── Verify: tag-version match + package tarball ─────────
  verify:
    needs: gate
    runs-on: [self-hosted, clean-room]
    outputs:
      crate_name: ${{ steps.parse.outputs.crate_name }}
      version: ${{ steps.parse.outputs.version }}
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

      - name: Parse tag and verify version
        id: parse
        run: |
          TAG="${GITHUB_REF_NAME}"

          # Parse tag format: v1.0.0 or v-cratename-1.0.0
          if [[ "$TAG" =~ ^v-([a-z][a-z0-9_-]*)-([0-9]+\..+)$ ]]; then
            CRATE_NAME="${BASH_REMATCH[1]}"
            TAG_VER="${BASH_REMATCH[2]}"
            echo "Workspace release: crate=$CRATE_NAME version=$TAG_VER"
          elif [[ "$TAG" =~ ^v([0-9]+\..+)$ ]]; then
            CRATE_NAME=""
            TAG_VER="${BASH_REMATCH[1]}"
            echo "Single-crate release: version=$TAG_VER"
          else
            echo "::error::Tag '$TAG' does not match expected format (v1.0.0 or v-crate-1.0.0)"
            exit 1
          fi

          # Use cargo metadata for reliable version extraction
          if [ -n "$CRATE_NAME" ]; then
            CARGO_VER=$(cargo metadata --format-version 1 --no-deps \
              | jq -r ".packages[] | select(.name == \"$CRATE_NAME\") | .version")
            if [ -z "$CARGO_VER" ] || [ "$CARGO_VER" = "null" ]; then
              echo "::error::Crate '$CRATE_NAME' not found in workspace"
              exit 1
            fi
          else
            CARGO_VER=$(cargo metadata --format-version 1 --no-deps \
              | jq -r '.packages[0].version')
          fi

          if [ "$TAG_VER" != "$CARGO_VER" ]; then
            echo "::error::Tag version $TAG_VER != Cargo.toml version $CARGO_VER"
            exit 1
          fi

          echo "crate_name=$CRATE_NAME" >> "$GITHUB_OUTPUT"
          echo "version=$TAG_VER" >> "$GITHUB_OUTPUT"
          echo "Version verified: $TAG_VER"

      - name: Verify package tarball
        run: |
          CRATE="${{ steps.parse.outputs.crate_name }}"
          if [ -n "$CRATE" ]; then
            cargo package --verify -p "$CRATE"
          else
            cargo package --verify
          fi

  # ── Publish: OIDC trusted publishing to crates.io ──────
  publish:
    needs: verify
    runs-on: [self-hosted, clean-room]
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

      - name: Authenticate to crates.io (OIDC)
        uses: rust-lang/crates-io-auth-action@b7e9a28eded4986ec6b1fa40eeee8f8f165559ec  # v1.0.3

      - name: Publish
        run: |
          CRATE="${{ needs.verify.outputs.crate_name }}"
          if [ -n "$CRATE" ]; then
            cargo publish -p "$CRATE"
          else
            cargo publish
          fi

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "$GITHUB_REF_NAME" \
            --title "$GITHUB_REF_NAME" \
            --generate-notes
