name: Release

on:
  push:
    branches:
      - main
    paths:
      - package.json
  workflow_dispatch:

permissions:
  contents: write
  id-token: write

concurrency:
  group: pi-herdr-subagents-release
  cancel-in-progress: false

jobs:
  detect:
    name: Detect version bump
    runs-on: ubuntu-latest
    outputs:
      release: ${{ steps.version.outputs.release }}
      version: ${{ steps.version.outputs.version }}
      tag: ${{ steps.version.outputs.tag }}

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Detect package version bump
        id: version
        shell: bash
        env:
          BEFORE_SHA: ${{ github.event.before }}
        run: |
          version="$(node --input-type=module -e "import pkg from './package.json' with { type: 'json' }; process.stdout.write(pkg.version)")"
          release=true

          if [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then
            previous_version="$(git show "${BEFORE_SHA}:package.json" | node --input-type=module -e "let input=''; process.stdin.on('data', chunk => input += chunk); process.stdin.on('end', () => process.stdout.write(JSON.parse(input).version));")"
            if [[ "$version" == "$previous_version" ]]; then
              release=false
              echo "package.json changed without a version bump; no release is needed."
            fi
          fi

          echo "release=$release" >> "$GITHUB_OUTPUT"
          echo "version=$version" >> "$GITHUB_OUTPUT"
          echo "tag=v$version" >> "$GITHUB_OUTPUT"

  release:
    name: Tag, publish, and create GitHub release
    needs: detect
    if: needs.detect.outputs.release == 'true'
    runs-on: ubuntu-latest

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org
          cache: npm

      - name: Verify package version is unpublished
        id: npm
        shell: bash
        env:
          VERSION: ${{ needs.detect.outputs.version }}
        run: |
          if npm view "pi-herdr-subagents@${VERSION}" version >/dev/null 2>&1; then
            echo "published=true" >> "$GITHUB_OUTPUT"
            echo "pi-herdr-subagents@${VERSION} is already published; npm publish will be skipped."
          else
            echo "published=false" >> "$GITHUB_OUTPUT"
          fi

      - name: Install dependencies
        run: npm ci

      - name: Run lint
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Verify package contents
        run: npm pack --dry-run

      - name: Create and push tag
        shell: bash
        env:
          TAG: ${{ needs.detect.outputs.tag }}
        run: |
          if git rev-parse "$TAG" >/dev/null 2>&1; then
            tagged_sha="$(git rev-list -n 1 "$TAG")"
            if [[ "$tagged_sha" != "$GITHUB_SHA" ]]; then
              echo "$TAG already points to $tagged_sha instead of $GITHUB_SHA."
              exit 1
            fi
            echo "$TAG already exists on this commit."
          else
            git config user.name "github-actions[bot]"
            git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
            git tag -a "$TAG" -m "Release $TAG"
            git push origin "$TAG"
          fi

      - name: Publish package to npm
        if: steps.npm.outputs.published != 'true'
        run: npm publish --access public --provenance
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Create GitHub release
        shell: bash
        env:
          GH_TOKEN: ${{ github.token }}
          TAG: ${{ needs.detect.outputs.tag }}
          VERSION: ${{ needs.detect.outputs.version }}
        run: |
          if gh release view "$TAG" >/dev/null 2>&1; then
            echo "GitHub release $TAG already exists."
          else
            gh release create "$TAG" \
              --verify-tag \
              --title "$TAG" \
              --generate-notes \
              --notes "Published package: [pi-herdr-subagents@${VERSION}](https://www.npmjs.com/package/pi-herdr-subagents/v/${VERSION})"
          fi

      - name: Release summary
        env:
          TAG: ${{ needs.detect.outputs.tag }}
          VERSION: ${{ needs.detect.outputs.version }}
        run: |
          echo "Released [$TAG](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${TAG}) and [pi-herdr-subagents@${VERSION}](https://www.npmjs.com/package/pi-herdr-subagents/v/${VERSION})." >> "$GITHUB_STEP_SUMMARY"
