Skip to content

V5.0.0

V5.0.0 #7

name: Update Benchmark Docs
on:
pull_request:
branches: [dev]
types: [opened, synchronize, reopened]
# Manual rerun from the Actions tab. When dispatched manually we benchmark the
# chosen ref but do NOT commit back (the numbers are left as an artifact).
workflow_dispatch:
inputs:
ref:
description: 'Branch/tag/SHA to benchmark (defaults to the branch the workflow runs from)'
required: false
default: ''
permissions:
contents: write
concurrency:
group: bench-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Benchmark numbers can only move when JavaScript changes. Docs-only pushes skip the
# long benchmark entirely (and don't produce a bot commit that races local work).
changes:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
js: ${{ steps.filter.outputs.js }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect JS changes
id: filter
env:
EVENT_ACTION: ${{ github.event.action }}
BEFORE: ${{ github.event.before }}
AFTER: ${{ github.event.after }}
BASE_REF: ${{ github.base_ref }}
run: |
if [ "$EVENT_ACTION" = "synchronize" ]; then
# Only the files changed by THIS push; fall back to the whole PR when the
# previous head is unreachable (force push).
changed=$(git diff --name-only "$BEFORE" "$AFTER" 2>/dev/null) \
|| changed=$(git diff --name-only "origin/$BASE_REF...HEAD")
else
changed=$(git diff --name-only "origin/$BASE_REF...HEAD")
fi
echo "Changed files:"
echo "$changed"
if echo "$changed" | grep -q '\.js$'; then
echo "js=true" >> "$GITHUB_OUTPUT"
else
echo "js=false" >> "$GITHUB_OUTPUT"
fi
benchmark:
needs: changes
# Run when: manually dispatched; or a same-repo PR (the default token cannot push
# back to a fork) whose triggering push touched at least one .js file. If the
# detection job itself failed, fail open and benchmark anyway.
if: >-
always() &&
(github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.head.repo.full_name == github.repository &&
(needs.changes.outputs.js == 'true' || needs.changes.result == 'failure')))
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout target ref
uses: actions/checkout@v4
with:
# pull_request: check out the PR branch so the refreshed docs can be pushed back.
# workflow_dispatch: check out the supplied ref (defaults to the branch the dispatch ran from).
ref: ${{ github.event.pull_request.head.ref || inputs.ref || github.ref_name }}
fetch-depth: 0
persist-credentials: true
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 26
cache: 'npm'
- name: Install packages
run: npm ci
# Gate the benchmark on a green test run: if tests fail, the workflow stops
# before benchmarking, so the docs are never refreshed from a broken build.
- name: Run tests
run: npm test
# All tests passed: produce fresh JSON benchmark numbers.
- name: Run benchmarks (JSON)
run: |
node benchmark2.js --json > bench-sequential.json
node benchmark.js --json > bench-comprehensive.json
- name: Upload benchmark JSON artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: |
bench-sequential.json
bench-comprehensive.json
retention-days: 30
- name: Refresh performance tables in README.md + docs/PERFORMANCE.md
run: node scripts/update-benchmark-docs.js bench-comprehensive.json bench-sequential.json
- name: Commit refreshed docs
# Only push the refresh back on PR events. Manual dispatch leaves the artifacts
# for the operator to inspect without mutating any branch.
if: github.event_name == 'pull_request'
run: |
git add README.md docs/PERFORMANCE.md
if git diff --cached --quiet; then
echo "No benchmark changes to commit."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# The ci-skip marker is built by concatenation so this auto-commit does not
# re-trigger the workflow (and so this file itself contains no literal directive).
MARKER="[skip"" ci]"
git commit -m "chore(bench): refresh performance numbers $MARKER"
git push origin HEAD:${{ github.head_ref }}