name: Performance Benchmark History

on:
  push:
    branches: [main, perf/auto-perf-tuning]
    paths-ignore:
      - 'website/**'
      - '*.md'
      - 'LICENSE'

concurrency:
  group: perf-benchmark-history
  cancel-in-progress: false

permissions:
  contents: read

jobs:
  benchmark:
    name: Benchmark (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    timeout-minutes: 15
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            runs: 20
          - os: macos-latest
            runs: 30
          - os: windows-latest
            runs: 20
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version-file: .tool-versions
          cache: npm

      - name: Install and build
        run: npm ci && node --run build

      - name: Run benchmark
        shell: bash
        env:
          BENCH_RUNS: ${{ matrix.runs }}
        run: node .github/scripts/perf-benchmark-history/bench-run.mjs "$GITHUB_WORKSPACE"

      - name: Upload benchmark result
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: bench-history-${{ matrix.os }}
          path: ${{ runner.temp }}/bench-result.json
          retention-days: 1

  store:
    name: Store Results
    needs: benchmark
    runs-on: ubuntu-latest
    if: ${{ always() && !cancelled() }}
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Ensure gh-pages branch exists
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if ! git ls-remote --heads origin gh-pages | grep -q gh-pages; then
            CURRENT_BRANCH=$(git branch --show-current)
            git config user.name "github-actions[bot]"
            git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
            git switch --orphan gh-pages
            git commit --allow-empty -m "Initial gh-pages branch for benchmark data"
            git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
            git push origin gh-pages
            git switch "$CURRENT_BRANCH"
          fi

      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          path: results
          pattern: bench-history-*

      - name: Combine results
        shell: bash
        run: |
          node -e '
            const fs = require("fs");
            const path = require("path");
            const combined = [];
            const resultsDir = "results";
            if (fs.existsSync(resultsDir)) {
              for (const dir of fs.readdirSync(resultsDir).sort()) {
                const file = path.join(resultsDir, dir, "bench-result.json");
                if (fs.existsSync(file)) {
                  combined.push(...JSON.parse(fs.readFileSync(file, "utf8")));
                }
              }
            }
            if (combined.length === 0) {
              console.error("No benchmark results found");
              process.exit(1);
            }
            fs.writeFileSync("combined-bench-result.json", JSON.stringify(combined, null, 2));
            console.log(JSON.stringify(combined, null, 2));
          '

      - name: Store benchmark result
        uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1
        with:
          name: ${{ github.ref == 'refs/heads/main' && 'Repomix Performance' || 'Repomix Performance (auto-perf-tuning)' }}
          benchmark-data-dir-path: ${{ github.ref == 'refs/heads/main' && 'dev/bench' || 'dev/bench/auto-perf-tuning' }}
          tool: customSmallerIsBetter
          output-file-path: combined-bench-result.json
          github-token: ${{ secrets.GITHUB_TOKEN }}
          auto-push: true
          # Alert on 30% regression
          alert-threshold: '130%'
          comment-on-alert: true
          summary-always: true
          fail-on-alert: false
