slowest-tests
Slowest CI tests
Args: [N] [#channel] — both optional. N defaults to 500. If #channel is omitted, just print the table and stop.
1. Gather the data
Run the script. With no build number it auto-picks the most recent finished build from a merged PR.
bun run ci:slowest # top 500 from a recent merged-PR build → TSV on stdout
bun run ci:slowest 47324 100 # specific build, top 100
bun run ci:slowest --json > /tmp/slow.json
The script (scripts/ci-slowest-tests.ts) does the heavy lifting:
- Lists
test-bunjobs frombk build view <N>, skippingretried: true. - Fetches each job's
raw_log_urldirectly withAuthorization: Bearer $BUILDKITE_TOKEN. Do not usebk job log— it hangs indefinitely on some Windows/alpine jobs. - Caches logs to
$TMPDIR/bun-ci-logs-<build>/so re-runs are instant. - Parses
_bk;t=<ms> ... --- [N/TOTAL] <file>group headers, normalising backslashes to/and stripping[attempt #N]retries. - Aggregates each file's duration as the max across all platforms (a file appears once per platform; shards within a platform are disjoint).
- Drops
package.json/ non-JS entries — those are setup steps, not tests.
If the script can't find a build automatically (rare — it walks the last 10 merged PRs), pick one yourself: gh pr list --state merged --limit 10 --json number,headRefName, then bk build list --branch <headRefName> and pass the first build with a finished_at. Merged-PR builds usually report state: failed because of flaky tests — that's fine, the timing data is still valid.
2. Post to Slack (only if a channel was given)
slack_send_message does NOT support markdown tables — its markdown→blocks converter rejects | a | b | syntax with invalid_blocks. Don't use Canvases either; they render tables but the MCP proxy 502s above ~10 KB and the result is clunky.
Procedure:
-
Look up the channel ID with
slack_search_channels(the user gives a name, you need theC…ID). -
Write the full N-row markdown table to
~/code/tmp/top<N>-slow-tests.md, then upload it as a secret gist:gh gist create <file> --desc "Bun CI: top N slowest test files (build #<num>)". (The Slack MCP has no file-upload tool; secret gist is the agreed fallback. Do not ask the user to attach anything manually.) -
Post the main message: header (build link + gist link, "Rest in thread.") followed by the top 20 bullets. Row format:
• 325s `test/js/bun/cron/in-process-cron.test.ts` 🐧 x64-baseline • 96s `test/js/bun/http/serve-body-leak.test.ts` 🐧 x64-asan- seconds: plain text, left-aligned, padded so the backticks line up
- filepath: code-font, full path including
test/prefix and extension — do not strip anything - platform: standard Unicode emoji only (🐧 linux, 🪟 windows, 🍎 macOS — never workspace-custom shortcodes) followed by the arch/variant verbatim from the job name (
x64-asan,aarch64,x64-baseline— do not abbreviate)
-
Reply in-thread (
thread_ts= the main message) with rows 21–N in the same bullet format, packed into chunks under 4800 chars each (~70 rows per chunk). Post chunks sequentially so they stay ordered.
More from oven-sh/bun
zig-system-calls
Guides using bun.sys for system calls and file I/O in Zig. Use when implementing file operations instead of std.fs or std.posix.
137writing-dev-server-tests
Guides writing HMR/Dev Server tests in test/bake/. Use when creating or modifying dev server, hot reloading, or bundling tests.
85implementing-jsc-classes-cpp
Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.
80writing-bundler-tests
Guides writing bundler tests using itBundled/expectBundled in test/bundler/. Use when creating or modifying bundler, transpiler, or code transformation tests.
79implementing-jsc-classes-zig
Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.
79javascriptcore-garbage-collector
JSC GC reference for Bun. Use for use-after-free, JS object leaks, "collected too early", or when touching WriteBarrier, visitChildren, visitAdditionalChildren, JSRef, JSC::Strong/Weak, hasPendingActivity, ensureStillAlive, addOpaqueRoot, reportExtraMemoryAllocated, IsoSubspace, HeapAnalyzer, finalize.
2