name: CI - Perf # EXPERIMENTAL: This workflow is running with --tolerate-failure flag for phpbench # This is to gather data for a future historical interleaving of performance benchmarks. on: # Run once per day no matter what schedule: - cron: '0 0 * * *' # Run on push to main, so we get a data point every merge push: branches: - main # Allow manual triggering with rebaseline option workflow_dispatch: inputs: baseline: description: 'Baseline mode. latest: compare against latest benchmarks; rebaseline: store new baseline.' type: choice default: 'latest' options: - 'latest' - 'rebaseline' pull: description: 'Pull request number to benchmark (optional)' required: false jobs: pr-benchmarks: name: PR Benchmarks if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.pull }} runs-on: ubuntu-latest env: BENCHMARK_SHA: ${{ github.sha }} permissions: contents: read steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: Checkout PR head run: | set -euo pipefail PR=${{ github.event.inputs.pull }} # Validate that PR is numeric to avoid injection or unexpected ref resolution if ! printf '%s\n' "$PR" | grep -Eq '^[0-9]+$'; then echo "Invalid pull request number: '$PR'. Expected a numeric value." >&2 exit 1 fi # fetch the pull request head (works for forks) git fetch origin "pull/${PR}/head:pr-${PR}" || git fetch origin "+refs/pull/${PR}/head:pr-${PR}" git checkout "pr-${PR}" echo "Checked out PR #${PR}" echo "BENCHMARK_SHA=$(git rev-parse --verify HEAD)" >> "$GITHUB_ENV" - uses: ./.github/actions/setup-action with: extensions: xdebug - name: Fetch Benchmarks run: | git fetch origin benchmarks mkdir -p .phpbench git checkout origin/benchmarks -- .phpbench || echo "No previous benchmarks found" - name: Run Benchmarks run: | # Baseline does not exist or rebaseline requested. Generate it. if [ -z "$(ls -A .phpbench)" ] || [ "${{ github.event.inputs.baseline || 'latest' }}" = "rebaseline" ]; then vendor/bin/phpbench run --report=aggregate --progress=plain --store --tag=${BENCHMARK_SHA} # Baseline exists. Compare against it. else vendor/bin/phpbench run --report=aggregate --progress=plain --store --tag=${BENCHMARK_SHA} --ref=latest --tolerate-failure fi # Generate report for human consumption vendor/bin/phpbench report --report=aggregate --ref=latest | tail -n+2 | head -n-2 | tr '+' '|' > report.md cat report.md > "$GITHUB_STEP_SUMMARY" historical-benchmarks: name: Historical Benchmarks if: >- github.event_name != 'workflow_dispatch' || !github.event.inputs.pull runs-on: ubuntu-latest env: BENCHMARK_SHA: ${{ github.sha }} permissions: contents: write steps: - uses: actions/checkout@v6 with: persist-credentials: true - uses: ./.github/actions/setup-action with: extensions: xdebug - name: Fetch Benchmarks run: | git fetch origin benchmarks mkdir -p .phpbench git checkout origin/benchmarks -- .phpbench || echo "No previous benchmarks found" - name: Run Benchmarks run: | # Baseline does not exist or rebaseline requested. Generate it. if [ -z "$(ls -A .phpbench)" ] || [ "${{ github.event.inputs.baseline || 'latest' }}" = "rebaseline" ]; then vendor/bin/phpbench run --report=aggregate --progress=plain --store --tag=${BENCHMARK_SHA} # Baseline exists. Compare against it. else vendor/bin/phpbench run --report=aggregate --progress=plain --store --tag=${BENCHMARK_SHA} --ref=latest --tolerate-failure fi # Generate report for human consumption vendor/bin/phpbench report --report=aggregate --ref=latest | tail -n+2 | head -n-2 | tr '+' '|' > report.md cat report.md - name: Commit Results # only on: main push, schedule, workflow_dispatch+rebaseline if: >- (github.ref == 'refs/heads/main' && github.event_name == 'push') || (github.event_name == 'schedule') || (github.event_name == 'workflow_dispatch' && github.event.inputs.baseline == 'rebaseline') run: | set -euo pipefail git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git checkout benchmarks mv -f report.md latest.md git add .phpbench latest.md git commit -m "Store benchmark results [skip ci]" || echo "No changes to commit" git push origin benchmarks - name: Restore workspace if: always() run: | set -euo pipefail echo "Restoring workspace to original commit: ${GITHUB_SHA}" git fetch origin || true git checkout --detach "${GITHUB_SHA}" git reset --hard "${GITHUB_SHA}"