name: Benchmark # Runs bench/run.sh and publishes the result table to the job summary. # # GitHub-hosted runners are noisier and weaker than a dedicated machine, so # treat these numbers as regression signal against previous runs of this # workflow, not as the headline figures for the README — see bench/README.md # for the reference run those figures are backed by. # # Also runs the full test262 conformance suite (~53k tests, language/ + # built-ins/ + intl402/) and reports 3va's real pass rate — this is why the # job can take noticeably longer than a pure perf benchmark would; see # docs/09-testing/06-test262.md for the methodology and known gaps. on: workflow_dispatch: push: tags: - "v[0-9]+.[0-9]+.[0-9]*" schedule: - cron: "0 6 * * 1" # weekly, Monday 06:00 UTC env: CARGO_TERM_COLOR: always # Least privilege: jobs get a read-only token unless they ask for more. permissions: contents: read jobs: benchmark: name: Run benchmarks runs-on: ubuntu-latest permissions: contents: read # the README sync commit is pushed with the deploy key steps: - uses: actions/checkout@v4 with: # main is protected by a ruleset; this deploy key is the only # bypass, used for the README benchmark sync commit below. ssh-key: ${{ secrets.MAIN_PUSH_DEPLOY_KEY }} - uses: dtolnay/rust-toolchain@stable # Deliberately no Swatinem/rust-cache here (unlike other workflows in # this repo that don't need one either — release.yml builds `v8` from # scratch every time and never hits this). rusty_v8's build script # produces a ~100+ MB static lib that rust-cache's size-based pruning # strips before saving, but the "build script already ran" fingerprint # gets cached anyway — cargo then skips re-running it and the linker # can't find the .a file that was never actually restored. Three # consecutive runs of this workflow failed on exactly that ("could not # find native static library `rusty_v8`") before this got removed. - uses: actions/setup-node@v4 with: node-version: "24" - uses: oven-sh/setup-bun@v2 with: bun-version: latest - name: Install benchmark tools # hyperfine 2.0 changed its --export-json schema (no top-level `mean`), which bench/run.sh parses. run: cargo install hyperfine@1.20.0 oha --locked - name: Build 3va (release) run: cargo build --release -p vvva_cli - name: Run benchmarks run: | set -o pipefail { echo "# Benchmark results" echo echo "Runner: $(nproc) vCPU, $(free -h | awk '/Mem:/ {print $2}') RAM, $(uname -r)" echo "Commit: \`${{ github.sha }}\`" echo bash bench/run.sh } | tee "$GITHUB_STEP_SUMMARY" /tmp/bench-output.txt - name: Sync README benchmark cells # Tag-triggered runs check out a detached tag ref, not a branch — # nothing sane to push to. Only commit back on main (schedule / # manual dispatch), same as any other push-to-main automation. if: github.ref == 'refs/heads/main' run: | bash bench/sync-readme.sh /tmp/bench-output.txt if ! git diff --quiet -- README.md; then git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add README.md git commit -s -m "chore(bench): update benchmark figures [skip ci]" git push fi