# Plugin release — fires on `v*` tags, publishes the crate when the
# CARGO_REGISTRY_TOKEN secret is configured, builds the matrix, and
# uploads binaries to a GitHub Release. Tier 3 #16 in ROADMAP.md.

name: release

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

permissions:
  contents: write   # for `gh release` artifact upload

# Do not let a duplicate tag run cancel an in-flight crates.io publish.
concurrency:
  group: release-${{ github.ref }}
  cancel-in-progress: false

env:
  CARGO_TERM_COLOR: always

jobs:
  publish-crate:
    name: crates.io publish
    needs: build
    runs-on: ubuntu-latest
    env:
      CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
      CRATE_NAME: heliosdb-codekb-mcp
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2

      - name: Verify tag matches Cargo.toml version
        id: package
        run: |
          version="$(cargo metadata --no-deps --format-version=1 | jq -r --arg name "$CRATE_NAME" '.packages[] | select(.name == $name).version')"
          if [ -z "$version" ] || [ "$version" = "null" ]; then
            echo "Could not read package version for ${CRATE_NAME}" >&2
            exit 1
          fi
          if [ "${GITHUB_REF_NAME}" != "v${version}" ]; then
            echo "Tag ${GITHUB_REF_NAME} does not match Cargo.toml version ${version}" >&2
            exit 1
          fi
          echo "version=${version}" >> "$GITHUB_OUTPUT"

      - name: Check crates.io version
        id: crates
        run: |
          url="https://crates.io/api/v1/crates/${CRATE_NAME}/${{ steps.package.outputs.version }}"
          status="$(
            curl -sS \
              -H "User-Agent: ${CRATE_NAME} release workflow (https://github.com/${GITHUB_REPOSITORY})" \
              -o /tmp/crates-version.json \
              -w "%{http_code}" \
              "$url"
          )"
          case "$status" in
            200)
              echo "exists=true" >> "$GITHUB_OUTPUT"
              ;;
            404)
              echo "exists=false" >> "$GITHUB_OUTPUT"
              ;;
            *)
              echo "Unexpected crates.io response: HTTP ${status}" >&2
              cat /tmp/crates-version.json >&2 || true
              exit 1
              ;;
          esac

      - name: Dry-run crate publish
        if: steps.crates.outputs.exists == 'false'
        env:
          OPENSSL_NO_VENDOR: "1"
        run: cargo publish --dry-run

      - name: Publish crate
        if: steps.crates.outputs.exists == 'false' && env.CARGO_REGISTRY_TOKEN != ''
        env:
          OPENSSL_NO_VENDOR: "1"
        run: cargo publish --token "$CARGO_REGISTRY_TOKEN"

      - name: Publish skipped
        if: steps.crates.outputs.exists == 'false' && env.CARGO_REGISTRY_TOKEN == ''
        run: |
          echo "::notice title=crates.io publish skipped::CARGO_REGISTRY_TOKEN repo secret is not configured."

      - name: Version already published
        if: steps.crates.outputs.exists == 'true'
        run: |
          echo "::notice title=crates.io publish skipped::${CRATE_NAME} ${{ steps.package.outputs.version }} is already published."

  build:
    name: ${{ matrix.os }} / ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          # linux x86_64 — the most-used pilot platform.
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact: heliosdb-codekb-mcp-linux-x86_64
            cross: false
          # macOS x86_64 (Intel) — older dev machines.
          - os: macos-15-intel
            target: x86_64-apple-darwin
            artifact: heliosdb-codekb-mcp-macos-x86_64
            cross: false
          # TODO: aarch64 builds (Linux + macOS) fail due to rocksdb cross-compilation issues.
          # Blocked on https://github.com/facebook/rocksdb/issues/...
          # Will re-enable after upstream improvements or workaround is found.

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      # `cross` for foreign-arch Linux; native cargo for everything else.
      - name: Install cross (aarch64 linux only)
        if: matrix.cross
        run: cargo install cross --locked

      - name: Build
        env:
          CARGO_BUILD_TARGET: ${{ matrix.target }}
        run: |
          cargo build --release --target ${{ matrix.target }} --features native-binary-docs

      - name: Strip binary (Unix only — keeps the artefact small)
        working-directory: target/${{ matrix.target }}/release
        run: |
          if [ -f heliosdb-codekb-mcp ]; then
            strip heliosdb-codekb-mcp || true
          fi

      - name: Compute sha256
        working-directory: target/${{ matrix.target }}/release
        run: |
          if command -v sha256sum >/dev/null; then
            sha256sum heliosdb-codekb-mcp > heliosdb-codekb-mcp.sha256
          else
            shasum -a 256 heliosdb-codekb-mcp > heliosdb-codekb-mcp.sha256
          fi

      - name: Package
        working-directory: target/${{ matrix.target }}/release
        run: |
          mkdir -p ../../../release
          cp heliosdb-codekb-mcp ../../../release/${{ matrix.artifact }}
          cp heliosdb-codekb-mcp.sha256 ../../../release/${{ matrix.artifact }}.sha256

      - uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.artifact }}
          path: release/

  publish:
    name: gh release
    needs: publish-crate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: ./release
          merge-multiple: true
      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
            gh release upload "${GITHUB_REF_NAME}" ./release/* --clobber
          else
            gh release create "${GITHUB_REF_NAME}" \
              --title "${GITHUB_REF_NAME}" \
              --generate-notes \
              ./release/*
          fi
