Skip to content

fix(ci): hash every test task's workspace closure and cache Turbo on Windows - #55719

Closed
neriousy wants to merge 1 commit into
windows-bun-cachefrom
turbo-test-hashes
Closed

neriousy wants to merge 1 commit into
windows-bun-cachefrom
turbo-test-hashes

Conversation

@neriousy

@neriousy neriousy commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Issue for this PR

No issue. Fifth PR in the test speed-up stack, based on #55692.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Linux CI replays stale test passes. unit (linux) has used the Blacksmith runner's Turbo remote cache since early October. A test task's hash covers its package plus its ^build dependencies, and each build hash covers only that package's own files (build has dependsOn: []). tui and script have no build task, so core, codemode, plugin-browser, simulation and ui never reach cli#test's hash. codemode and plugin-browser likewise never reach server#test or tui#test. All packages export src, so these tests do run the changed code.

Example: runs 38691743520 and 38692392415 on dev both changed only packages/core/src/mcp/client.ts, and both logged @opencode/cli:test: cache hit, replaying logs 021fe0708552bc59. cli's tests never ran against either change. Over the last 60 dev pushes, 14 Linux cli:test executions were replays like this.

Every <pkg>#test now also depends on a transit task ("transit": { "dependsOn": ["^transit"] }). No package has a transit script, so nothing new executes, but each test hash now folds in its whole workspace closure. The root package.json is also a global dependency now: a Bun upgrade through packageManager alone changed no test hash before (for example df05945, Bun 1.3.14 → 1.4.0).

Checked with turbo run test --dry=json:

Edit Test hashes that change, before After
packages/core/src/account/sql.ts core, server, tui cli, core, server, tui
packages/codemode/src/index.ts codemode, core cli, codemode, core, server, tui
executed tasks 27 the same 27

Windows gets a Turbo cache. Windows runners have no remote cache (Remote caching disabled), so every unit (windows) run rebuilds all ^build dependencies. The old actions/cache step for Turbo (removed in #55690) cached node_modules/.cache/turbo, a path Turbo 2 never writes to. Windows now restores .turbo/cache:

  • The key is the ISO week plus the commit, with a same-week restore key. That bounds how far the cache grows (about 19 MB a day of entries) and how old a replayed entry can get.
  • It's saved only from pushes to dev, and manual runs skip the restore so they execute everything.
  • A cache hit needs an exact task-hash match, and the transit fix makes those hashes complete.

From replaying the last ~140 Windows runs against a cache built from dev pushes: about 15s median / 22s mean off unit (windows), almost all from replayed builds (server, core and simulation builds are 27-34s each on Windows). The save step makes dev pushes a few seconds slower.

Measured on Windows with two back-to-back manual runs of this commit on a scratch branch (restore and save enabled for manual runs there only):

unit (windows) Cold run 38740228794 Warm run 38741866297
Restore Turbo cache 0s (miss) 1s (2.3 MB, turbo-Windows-2026-W42-…)
Run unit tests 388s 14s (26 cached, 27 total; desktop:test has cache: false)
Save Turbo cache 1s 0s

The warm run is the best case: the same tree, so everything replays. On a normal PR only the builds and the tests whose workspace closure didn't change replay, which the simulation above puts at about 15s median. Restore and save cost about 1s each.

Not included: typecheck has the same gap ("typecheck": {} has no ^ dependencies), but changing it affects check.yml and belongs in its own PR.

How did you verify your code works?

  • turbo run test --dry=json before and after, as above, including the executed task set.
  • actionlint (only the existing case() and Blacksmith runner label warnings).
  • Pre-commit lint and typecheck pass.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…Windows

A test task's hash only covered its direct dependencies' build tasks. tui
and script have no build task, so core, codemode, plugin-browser and ui
never reached cli#test's hash, and Linux replayed cached cli test passes
from the runner's remote cache for commits that changed core. Every test
task now also depends on a transit task, which runs nothing but folds the
whole workspace closure into its hash. The root package.json is a global
dependency, so a Bun upgrade through packageManager invalidates results.

Windows unit jobs had no Turbo cache at all. Restore one keyed by week on
Windows, save it from pushes to dev, and skip it on manual runs.
@neriousy

Copy link
Copy Markdown
Member Author

Combined into #55866, which squashes this whole stack into one change (rebased onto current dev). The evidence for this part stays here for reference.

@neriousy neriousy closed this Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant