Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .github/workflows/benchmark-pr-vs-frameworks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Benchmark PR vs frameworks

on:
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pull-requests: write

jobs:
benchmark:
name: Benchmark
runs-on: ubuntu-latest
env:
npm_config_legacy_peer_deps: "true"
steps:
- name: Checkout PR branch
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Install repository dependencies
run: npm ci

- name: Build repository
run: npm run build

- name: Clone benchmark suite
run: git clone --depth=1 https://github.com/milomg/js-reactivity-benchmark.git .tmp/js-reactivity-benchmark

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pin benchmark suite revision before cloning

The workflow clones milomg/js-reactivity-benchmark from its moving default branch, so upstream changes can break this repo’s PR checks without any change here. That risk is concrete in this commit because scripts/ci/benchmark-pr-vs-frameworks.mjs expects specific framework names and throws if they change. Cloning a fixed tag or commit SHA will make CI results reproducible and prevent flaky external breakages.

Useful? React with 👍 / 👎.


- name: Install benchmark dependencies
working-directory: .tmp/js-reactivity-benchmark
run: pnpm install --frozen-lockfile

- name: Build benchmark core runtime bundle
working-directory: .tmp/js-reactivity-benchmark/packages/core
run: pnpm exec esbuild src/index.ts --bundle --format=esm --target=esnext --outdir=dist --sourcemap=external

- name: Run PR vs frameworks benchmark
run: node scripts/ci/benchmark-pr-vs-frameworks.mjs
env:
BENCH_CORE_DIST_DIR: .tmp/js-reactivity-benchmark/packages/core/dist
CURRENT_SIGNALS_DIR: packages/rescript-signals
BENCH_OUT_DIR: benchmark-results/ci/pr-vs-frameworks

- name: Upload benchmark artifacts
uses: actions/upload-artifact@v4
with:
name: benchmark-pr-vs-frameworks
path: benchmark-results/ci/pr-vs-frameworks
if-no-files-found: error

- name: Add workflow summary
run: |
echo "## ReScript Signals benchmark: PR vs frameworks" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
cat benchmark-results/ci/pr-vs-frameworks/pr-comment-latest.md >> "$GITHUB_STEP_SUMMARY"

- name: Upsert PR benchmark comment
if: github.event_name == 'pull_request'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard PR comment upsert against fork pull requests

This step runs for every pull_request event, but forked PRs get a read-only GITHUB_TOKEN; in that context, the github.rest.issues.*Comment calls fail with 403 and the benchmark job is marked failed even though benchmarking succeeded. Add a fork-aware condition (for example, skip when github.event.pull_request.head.repo.fork is true) or move comment writing to a trusted workflow context; the same pattern is also present in .github/workflows/benchmark-pr-vs-main.yml.

Useful? React with 👍 / 👎.

uses: actions/github-script@v7
with:
script: |
const fs = require("fs");
const marker = "<!-- rescript-signals-benchmark-pr-vs-frameworks -->";
const body = fs.readFileSync("benchmark-results/ci/pr-vs-frameworks/pr-comment-latest.md", "utf8");
const commentBody = `${marker}\n${body}`;

const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number,
per_page: 100,
});

const existing = comments.find((c) => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existing.id,
body: commentBody,
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body: commentBody,
});
}
119 changes: 119 additions & 0 deletions .github/workflows/benchmark-pr-vs-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Benchmark PR vs main

on:
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pull-requests: write

jobs:
benchmark:
name: Benchmark
runs-on: ubuntu-latest
env:
npm_config_legacy_peer_deps: "true"
steps:
- name: Checkout PR branch
uses: actions/checkout@v4

- name: Checkout main baseline
uses: actions/checkout@v4
with:
ref: main
path: main-baseline

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Install repository dependencies
run: npm ci

- name: Build repository
run: npm run build

- name: Install baseline dependencies
working-directory: main-baseline
run: npm ci

- name: Build baseline
working-directory: main-baseline
run: npm run build

- name: Clone benchmark suite
run: git clone --depth=1 https://github.com/milomg/js-reactivity-benchmark.git .tmp/js-reactivity-benchmark

- name: Install benchmark dependencies
working-directory: .tmp/js-reactivity-benchmark
run: pnpm install --frozen-lockfile

- name: Build benchmark core runtime bundle
working-directory: .tmp/js-reactivity-benchmark/packages/core
run: pnpm exec esbuild src/index.ts --bundle --format=esm --target=esnext --outdir=dist --sourcemap=external

- name: Run PR vs main benchmark
run: node scripts/ci/benchmark-pr-vs-main.mjs
env:
BENCH_CORE_DIST_DIR: .tmp/js-reactivity-benchmark/packages/core/dist
CURRENT_SIGNALS_DIR: packages/rescript-signals
MAIN_SIGNALS_DIR: main-baseline/packages/rescript-signals
BENCH_OUT_DIR: benchmark-results/ci/pr-vs-main

- name: Upload benchmark artifacts
uses: actions/upload-artifact@v4
with:
name: benchmark-pr-vs-main
path: benchmark-results/ci/pr-vs-main
if-no-files-found: error

- name: Add workflow summary
run: |
echo "## ReScript Signals benchmark: PR vs main" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
cat benchmark-results/ci/pr-vs-main/pr-comment-latest.md >> "$GITHUB_STEP_SUMMARY"

- name: Upsert PR benchmark comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require("fs");
const marker = "<!-- rescript-signals-benchmark-pr-vs-main -->";
const body = fs.readFileSync("benchmark-results/ci/pr-vs-main/pr-comment-latest.md", "utf8");
const commentBody = `${marker}\n${body}`;

const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number,
per_page: 100,
});

const existing = comments.find((c) => c.body && c.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existing.id,
body: commentBody,
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body: commentBody,
});
}
Loading
Loading