name: Dev Release

on:
  push:
    branches: [dev]
  workflow_dispatch:

concurrency:
  group: dev-release-${{ github.ref }}
  cancel-in-progress: false

jobs:
  release:
    # Skip if commit message contains [skip ci]
    if: "!contains(github.event.head_commit.message, '[skip ci]')"
    runs-on: ubuntu-latest

    permissions:
      contents: write
      issues: write
      pull-requests: write
      id-token: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          # Always use the built-in workflow token; PAT rotation/breakage must not block dev releases.
          token: ${{ github.token }}

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: '1.3.9'

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          registry-url: 'https://registry.npmjs.org'

      - name: Install dependencies
        run: |
          bun install --frozen-lockfile
          cd ui && bun install --frozen-lockfile

      - name: Build
        run: bun run build:all

      - name: Validate (typecheck + lint + format + tests)
        run: bun run validate

      - name: Release
        id: release
        env:
          HUSKY: 0
          # Use built-in GITHUB_TOKEN for release + issue operations.
          # Checkout credentials are resolved above with PAT fallback.
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          # Use custom dev release script instead of semantic-release
          # This ensures dev versions follow {stable}-dev.{N} pattern
          chmod +x scripts/dev-release.sh
          if ./scripts/dev-release.sh; then
            echo "released=true" >> $GITHUB_OUTPUT
          else
            echo "Dev release failed or skipped"
            echo "released=false" >> $GITHUB_OUTPUT
          fi

      - name: Notify Discord
        if: success() && steps.release.outputs.released == 'true'
        env:
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
        run: |
          if [ -z "$DISCORD_WEBHOOK_URL" ]; then
            echo "DISCORD_WEBHOOK_URL not set, skipping"
            exit 0
          fi
          node scripts/send-discord-release.cjs dev "$DISCORD_WEBHOOK_URL"

      - name: Tag resolved issues
        if: success() && steps.release.outputs.released == 'true'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Get version from package.json
          VERSION=$(jq -r '.version' package.json)

          # Get commits ONLY since last dev tag (not all release commits)
          # This prevents re-tagging issues from older releases
          LAST_DEV_TAG=$(git tag -l "v*-dev.*" --sort=-v:refname | head -1 || echo "")

          if [ -n "$LAST_DEV_TAG" ]; then
            # Commits between last dev tag and current (excluding release commit)
            RANGE="${LAST_DEV_TAG}..HEAD~1"
          else
            # First dev release - check commits since last stable tag
            STABLE_TAG=$(git tag -l "v[0-9]*.[0-9]*.[0-9]" --merged origin/main --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1 || echo "")
            RANGE="${STABLE_TAG:-HEAD~10}..HEAD~1"
          fi

          echo "Checking commits in range: $RANGE"

          # Extract issue numbers from commit messages
          ISSUES=$(git log $RANGE --pretty=format:"%s %b" 2>/dev/null | \
            grep -oE "(Fixes|Closes|Resolves|Refs?) #[0-9]+" | \
            grep -oE "#[0-9]+" | sort -u || true)

          if [[ -z "$ISSUES" ]]; then
            echo "No linked issues found in range"
            exit 0
          fi

          # Create label if needed
          gh label create "released-dev" \
            --color "1d76db" \
            --description "Fix available in @dev npm channel" \
            --repo ${{ github.repository }} 2>/dev/null || true

          for ISSUE in $ISSUES; do
            NUM=${ISSUE#\#}

            # Skip if already has ANY release label (prevents duplicate comments)
            RELEASE_LABELS=$(gh issue view "$NUM" --repo "${{ github.repository }}" --json labels --jq '[.labels[].name | select(startswith("released"))] | length' 2>/dev/null || echo "0")
            if [[ "$RELEASE_LABELS" -gt 0 ]]; then
              echo "Issue #$NUM already released, skipping"
              continue
            fi

            echo "Tagging issue #$NUM"
            # Remove pending-release (transition), add released-dev
            gh issue edit "$NUM" --remove-label "pending-release" --add-label "released-dev" --repo "${{ github.repository }}" 2>/dev/null || \
              gh issue edit "$NUM" --add-label "released-dev" --repo "${{ github.repository }}" || true
            gh issue comment "$NUM" --repo "${{ github.repository }}" --body "[bot] Available in \`$VERSION\`. Install: \`ccs update --dev\`" || true
          done
