99 description : Pull request number
1010 required : true
1111 type : number
12+ suite :
13+ description : Benchmark suite
14+ required : true
15+ default : full
16+ type : choice
17+ options :
18+ - full
19+ - web
1220
1321permissions :
1422 contents : read
@@ -39,13 +47,21 @@ jobs:
3947 with :
4048 script : |
4149 const prNumber = context.eventName === 'workflow_dispatch'
42- ? Number(core.getInput('pr') )
50+ ? Number(context.payload.inputs?.pr )
4351 : context.payload.issue?.number;
4452
4553 if (!prNumber) {
4654 throw new Error('Unable to determine pull request number');
4755 }
4856
57+ const suite = context.eventName === 'workflow_dispatch'
58+ ? context.payload.inputs?.suite ?? 'full'
59+ : 'full';
60+ const benchmarkScripts = { full: 'benchmark', web: 'benchmark:web' };
61+ if (!Object.hasOwn(benchmarkScripts, suite)) {
62+ throw new Error(`Unsupported benchmark suite: ${suite}`);
63+ }
64+
4965 const { owner, repo } = context.repo;
5066 const pr = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
5167
5571 core.setOutput('base_ref', pr.data.base.ref);
5672 core.setOutput('head_ref', pr.data.head.ref);
5773 core.setOutput('head_repo', pr.data.head.repo.full_name);
74+ core.setOutput('suite', suite);
75+ core.setOutput('script', benchmarkScripts[suite]);
5876
5977 const sameRepo = pr.data.head.repo.full_name === `${owner}/${repo}`;
6078 core.setOutput('same_repo', sameRepo ? 'true' : 'false');
@@ -169,43 +187,73 @@ jobs:
169187 working-directory : bench-base
170188 run : pnpm install --frozen-lockfile=false
171189
190+ - name : Build project (base)
191+ if : steps.pr.outputs.same_repo == 'true'
192+ working-directory : bench-base
193+ run : pnpm run build
194+
172195 - name : Install dependencies (head)
173196 if : steps.pr.outputs.same_repo == 'true'
174197 working-directory : bench-head
175198 run : pnpm install --frozen-lockfile=false
176199
200+ - name : Build project (head)
201+ if : steps.pr.outputs.same_repo == 'true'
202+ working-directory : bench-head
203+ run : pnpm run build
204+
177205 - name : Install Playwright browsers
178206 if : steps.pr.outputs.same_repo == 'true'
179207 env :
180208 PLAYWRIGHT_BROWSERS_PATH : ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
181209 run : pnpm -C bench-head/packages/treecrdt-wa-sqlite/e2e exec playwright install --with-deps chromium
182210
183211 - name : Run benchmarks (base)
212+ id : benchmark_base
184213 if : steps.pr.outputs.same_repo == 'true'
214+ continue-on-error : true
185215 working-directory : bench-base
186216 env :
217+ BENCHMARK_SCRIPT : ${{ steps.pr.outputs.script }}
187218 PLAYWRIGHT_BROWSERS_PATH : ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
188- run : pnpm run benchmark
219+ run : |
220+ set -o pipefail
221+ status=0
222+ env -u CI pnpm run "$BENCHMARK_SCRIPT" 2>&1 | tee benchmark.log || status=$?
223+ pnpm run benchmark:aggregate || status=$?
224+ exit "$status"
189225
190226 - name : Run benchmarks (head)
227+ id : benchmark_head
191228 if : steps.pr.outputs.same_repo == 'true'
229+ continue-on-error : true
192230 working-directory : bench-head
193231 env :
232+ BENCHMARK_SCRIPT : ${{ steps.pr.outputs.script }}
194233 PLAYWRIGHT_BROWSERS_PATH : ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
195- run : pnpm run benchmark
234+ run : |
235+ set -o pipefail
236+ status=0
237+ env -u CI pnpm run "$BENCHMARK_SCRIPT" 2>&1 | tee benchmark.log || status=$?
238+ pnpm run benchmark:aggregate || status=$?
239+ exit "$status"
196240
197241 - name : Upload benchmark artifacts
198- if : steps.pr.outputs.same_repo == 'true'
242+ if : always() && steps.pr.outputs.same_repo == 'true'
199243 uses : actions/upload-artifact@v4
200244 with :
201245 name : benchmarks-${{ steps.pr.outputs.number }}
202246 if-no-files-found : warn
203247 path : |
204248 bench-base/benchmarks/**
205249 bench-head/benchmarks/**
250+ bench-base/benchmark.log
251+ bench-head/benchmark.log
252+ bench-base/packages/treecrdt-wa-sqlite/e2e/test-results/**
253+ bench-head/packages/treecrdt-wa-sqlite/e2e/test-results/**
206254
207255 - name : Prepare comment body
208- if : steps.pr.outputs.same_repo == 'true'
256+ if : always() && steps.pr.outputs.same_repo == 'true'
209257 id : render
210258 uses : actions/github-script@v7
211259 with :
@@ -290,6 +338,10 @@ jobs:
290338 const headSha = '${{ steps.pr.outputs.head_sha }}'.slice(0, 7);
291339 const baseRef = '${{ steps.pr.outputs.base_ref }}';
292340 const headRef = '${{ steps.pr.outputs.head_ref }}';
341+ const suite = '${{ steps.pr.outputs.suite }}';
342+ const baseOutcome = '${{ steps.benchmark_base.outcome }}';
343+ const headOutcome = '${{ steps.benchmark_head.outcome }}';
344+ const benchmarkFailed = [baseOutcome, headOutcome].includes('failure');
293345 const triggerLabel =
294346 context.eventName === 'workflow_dispatch' ? '`workflow_dispatch`' : '`/bench`';
295347
@@ -298,11 +350,16 @@ jobs:
298350 '## Benchmarks',
299351 '',
300352 `Triggered by ${triggerLabel} - Run: ${runUrl}`,
353+ `Suite: \`${suite}\` - Base command: ${baseOutcome} - Head command: ${headOutcome}`,
301354 `Base: ${baseRef} (${baseSha}) - Head: ${headRef} (${headSha})`,
302355 `Compared entries: ${keys.length} - Improved: ${improved} - Regressed: ${regressed}`,
303356 '',
304357 ];
305358
359+ if (benchmarkFailed) {
360+ parts.push('_At least one benchmark command failed. Available partial results and logs are included in the artifact._', '');
361+ }
362+
306363 if (keys.length === 0) {
307364 parts.push('_No benchmark results were found. Check the workflow logs for details._', '');
308365 } else {
@@ -314,13 +371,14 @@ jobs:
314371 'Artifacts:',
315372 '- base summary: `bench-base/benchmarks/summary.json`',
316373 '- head summary: `bench-head/benchmarks/summary.json`',
374+ '- command logs: `bench-base/benchmark.log`, `bench-head/benchmark.log`',
317375 ''
318376 );
319377
320378 return parts.join('\n');
321379
322380 - name : Comment results
323- if : steps.pr.outputs.same_repo == 'true'
381+ if : always() && steps.pr.outputs.same_repo == 'true' && steps.render.outcome == 'success '
324382 uses : actions/github-script@v7
325383 env :
326384 BENCH_BODY : ${{ steps.render.outputs.result }}
@@ -355,3 +413,10 @@ jobs:
355413 body,
356414 });
357415 }
416+
417+ - name : Fail after publishing partial results
418+ if : |
419+ always() &&
420+ steps.pr.outputs.same_repo == 'true' &&
421+ (steps.benchmark_base.outcome == 'failure' || steps.benchmark_head.outcome == 'failure')
422+ run : exit 1
0 commit comments