name: Auto Release

on:
  push:
    branches: [ main ]
    # 忽略release commit，避免循环触发
    paths-ignore:
      - 'CHANGELOG.md'
  # 手动触发：用于补发失败的发布，或让 npm / GitHub Packages 的包页面
  # 同步最新 README（包页面读的是 tarball 内的副本，只能靠发版更新）。
  workflow_dispatch:

# 为GitHub Actions bot赋予必要权限
permissions:
  contents: write    # 允许修改仓库内容（推送commits和tags）
  actions: read      # 允许读取actions状态
  packages: write    # 允许发布packages
  pull-requests: read # 允许读取PR信息
  id-token: write    # npm Trusted Publisher (OIDC) 换取发布凭证

env:
  PNPM_CACHE_FOLDER: .pnpm-store

jobs:
  # 检查是否需要发布
  check-release:
    name: Check Release Need
    runs-on: ubuntu-latest
    outputs:
      should-release: ${{ steps.check.outputs.should-release }}
      commit-message: ${{ steps.check.outputs.commit-message }}
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v7
        with:
          fetch-depth: 2  # 获取最近两个commit用于比较
      
      - name: Check commit message for release keywords
        id: check
        run: |
          # 获取最新的commit message
          COMMIT_MSG=$(git log -1 --pretty=format:'%s')
          echo "commit-message=$COMMIT_MSG" >> $GITHUB_OUTPUT
          echo "Latest commit message: $COMMIT_MSG"
          
          # 手动触发时直接放行，不看 commit 前缀；版本级别仍由 release-it
          # 依据全部未发布 commit 推断。
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "should-release=true" >> $GITHUB_OUTPUT
            echo "🖐 Manually dispatched, proceeding to release"
            exit 0
          fi

          # 检查是否是release commit，如果是则跳过
          if [[ "$COMMIT_MSG" =~ ^chore:\ release\ v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
            echo "This is a release commit, skipping auto-release"
            echo "should-release=false" >> $GITHUB_OUTPUT
            exit 0
          fi
          
          # 只判定「要不要发」；「发哪一级」由 release-it 依据全部未发布
          # commit 推断，见下方 Release 步骤。
          if [[ "$COMMIT_MSG" =~ ^(feat|fix|perf)(\(.+\))?!?: ]]; then
            echo "should-release=true" >> $GITHUB_OUTPUT
            echo "✅ Release-worthy commit detected, will trigger release"
          else
            # 其他类型的commit (docs, style, refactor, test, chore等) 不触发发布
            echo "should-release=false" >> $GITHUB_OUTPUT
            echo "📝 Non-release commit type, skipping auto-release"
            echo "Supported prefixes: feat, fix, perf (with optional ! for breaking changes)"
          fi

  # 自动发布
  auto-release:
    name: Auto Release
    runs-on: ubuntu-latest
    needs: check-release
    if: needs.check-release.outputs.should-release == 'true'
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v7
        with:
          fetch-depth: 0  # 获取完整历史，用于changelog生成
          token: ${{ secrets.GITHUB_TOKEN }}
          persist-credentials: true  # 保持认证信息，用于后续git操作

      - name: Setup pnpm
        uses: pnpm/setup@v2.1.0
        with:
          install: false
          cache: true

      # 不设 registry-url：它只会往 .npmrc 写 _authToken=${NODE_AUTH_TOKEN}，
      # 而 OIDC 不使用该变量，留下的空 token 反而会让认证失败。
      - name: Setup Node.js
        uses: actions/setup-node@v7
        with:
          node-version: '24.20.0'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile
      
      - name: Configure Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git config --global url."https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/"
      
      - name: Run quality checks
        run: |
          echo "🔍 Running linting..."
          pnpm run lint
          
          echo "🧪 Running tests..."
          pnpm run test
          
          echo "🏗️ Building project..."
          pnpm run build
      
      # 版本号由 release-it 依据「全部未发布 commit」推断，而非仅看最新一条。
      # check-release 只负责决定「要不要发」，不再决定「发哪一级」——否则一条 fix
      # 会把累积的 feat 降级成 patch。
      # npm 认证走 Trusted Publisher (OIDC)，不再需要 NPM_TOKEN。
      # --npm.skipChecks 跳过 publish 前的 npm whoami：OIDC 的凭证是在 publish
      # 那一刻才换取的，whoami 阶段尚无凭证，检查必然失败。
      - name: Release
        run: |
          echo "📝 Triggered by commit: ${{ needs.check-release.outputs.commit-message }}"
          pnpm exec release-it --ci --npm.skipChecks
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # 把同一份产物再发一份到 GitHub Packages。两点约束：
      # 1. 该 registry 要求 scoped 包名且 scope 必须等于仓库 owner，故临时改名
      #    为 @chaslui/textrank4zh-ts 发布后还原 package.json；
      # 2. --ignore-scripts 跳过 prepublishOnly，dist 在上一步已构建，重跑只会
      #    先 clean 掉再重建并跑一遍全量测试。
      # npm registry 上的 textrank4zh-ts 仍是主入口：GitHub Packages 即便包是
      # 公开的，安装方也必须持 PAT 认证。
      - name: Publish to GitHub Packages
        run: |
          echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc
          npm pkg set name="@chaslui/textrank4zh-ts"
          npm publish --registry=https://npm.pkg.github.com --ignore-scripts
          git checkout -- package.json
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Notify release completion
        if: success()
        run: |
          echo "✅ Release completed successfully!"
          echo "📦 New package version has been published to npm"
          echo "🏷️ GitHub release has been created"
          echo "📋 CHANGELOG.md has been updated"

  # 发布失败通知
  release-failure:
    name: Release Failure Notification
    runs-on: ubuntu-latest
    needs: [check-release, auto-release]
    if: needs.check-release.outputs.should-release == 'true' && failure()
    
    steps:
      - name: Notify failure
        run: |
          echo "❌ Auto-release failed!"
          echo "💡 Please check the logs and run manual release if needed:"
          echo "   pnpm run release:dry   # Check what would be released"
          echo "   pnpm run release       # Manual release"
          exit 1

  # 跳过发布通知（可选）
  skip-release:
    name: Skip Release Notification  
    runs-on: ubuntu-latest
    needs: check-release
    if: needs.check-release.outputs.should-release == 'false'
    
    steps:
      - name: Notify skip
        run: |
          COMMIT_MSG="${{ needs.check-release.outputs.commit-message }}"
          echo "⏭️ Skipping auto-release"
          echo "📝 Commit message: $COMMIT_MSG"
          echo ""
          echo "💡 To trigger auto-release, use conventional commit prefixes:"
          echo "   feat: / fix: / perf:  (optional scope, optional ! for breaking)"
          echo ""
          echo "📊 版本级别由 release-it 依据全部未发布 commit 推断："
          echo "   含破坏性变更(!) → major；含 feat → minor；仅 fix/perf → patch"
          echo ""
          echo "🔧 For manual release, run: pnpm run release"