name: Benchmark on: push: branches: - master paths: - 'internal/**/*.go' - 'go.mod' - 'go.sum' pull_request: branches: - master paths: - 'internal/**/*.go' - 'go.mod' - 'go.sum' workflow_dispatch: permissions: contents: write jobs: benchmark: name: Run Benchmarks runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v5 with: go-version-file: 'go.mod' cache: true - name: Install benchstat run: go install golang.org/x/perf/cmd/benchstat@latest - name: Download dependencies run: go mod download - name: Fetch baseline benchmark run: | if git show origin/master:benchmark-baseline.txt >/dev/null 2>&1; then git show origin/master:benchmark-baseline.txt > benchmark-baseline.txt echo "baseline_found=true" >> $GITHUB_ENV else echo "baseline_found=false" >> $GITHUB_ENV fi - name: Run benchmarks run: | go test -bench=. -benchmem -count=10 ./... 2>&1 | tee benchmark-current.txt - name: Compare benchmarks if: env.baseline_found == 'true' run: | benchstat benchmark-baseline.txt benchmark-current.txt > benchmark-comparison.txt cat benchmark-comparison.txt - name: Check for regressions if: env.baseline_found == 'true' run: | if command -v python3 >/dev/null 2>&1; then benchstat benchmark-baseline.txt benchmark-current.txt | \ python3 scripts/check_regression.py - \ --config .benchmark-thresholds.yaml \ --environment ci \ || echo "regression_detected=$?" >> $GITHUB_OUTPUT else echo "Python3 not available, skipping regression check" fi id: regression_check - name: Save current benchmark as baseline if: github.ref == 'refs/heads/master' run: | cp benchmark-current.txt benchmark-baseline.txt git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add benchmark-baseline.txt || true git commit -m "chore(bench): update benchmark baseline" || true git push || true - name: Upload benchmark results uses: actions/upload-artifact@v4 with: name: benchmark-results path: | benchmark-current.txt benchmark-baseline.txt benchmark-comparison.txt retention-days: 30 - name: Fail on regression if: steps.regression_check.outputs.regression_detected == '2' run: | echo "::error::BLOCK level performance regression detected" exit 2