ci: move Fork CI test and nightly Windows to free runners - #112
Merged
Conversation
incognitojam
force-pushed
the
t3code/audit-blacksmith-ci-usage
branch
from
August 13, 2026 12:09
253c24d to
52a8a51
Compare
yngatech-nightly
Bot
force-pushed
the
main
branch
from
August 13, 2026 12:15
21f3064 to
90e6a92
Compare
The repository is public, so standard GitHub-hosted runners are free. Fork Test is the largest paid line item yet is long-poled by apps/server's await-bound suite rather than by cores, and nightly Windows was the least CPU-bound desktop target, so both move to free runners. Fork Check drops 8 -> 4 vCPU to match its 4-5 core typecheck peak. macOS stays on Blacksmith; it is genuinely CPU-bound and paces the nightly.
incognitojam
force-pushed
the
t3code/audit-blacksmith-ci-usage
branch
from
August 13, 2026 12:31
52a8a51 to
8ce70c1
Compare
This was referenced Aug 13, 2026
incognitojam
added a commit
that referenced
this pull request
Aug 13, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
incognitojam
added a commit
that referenced
this pull request
Aug 13, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
> [!NOTE] > The repo is public, so standard GitHub-hosted runners are free. Moves the two > jobs that gain least from paid hardware onto free runners and right-sizes a > third. Runner changes only — follow-ups tracked at the bottom. ## Problem An audit of the last 8 days of run history (all GitHub retains) put Blacksmith at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were paying for cores they could not use: - **Fork Test** spends 209s of its 248s in the `Test` step. Only the first ~30s is parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at 15-20% is `apps/server` alone (`transform 4.85s, import 75s, tests 211s` — await-bound tests pinning one or two workers while every other package has finished). It is long-poled, not short of cores, so slower cores cost far less than proportionally. - **Nightly Windows x64** was the least CPU-bound of the three desktop targets per the #51 metrics review. - **Fork Check** peaks at 4-5 cores during Typecheck; only ~54s of its 97s is CPU work at all. ## Fix - Fork Test → `ubuntu-24.04`, nightly Windows → `windows-2025` (free). - Fork Check → `blacksmith-4vcpu-ubuntu-2404`. macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%) and paces the whole nightly. Expected cost after this lands: ~$176/mo → ~$90/mo, leaving macOS (~$29/mo) as the largest Blacksmith item. ## Verification `actionlint` reports no new findings, both workflows parse, and the desktop build matrix script still emits the expected runner for each target (`macos-arm64` → `blacksmith-6vcpu-macos-15`, `linux-x64` → `blacksmith-8vcpu-ubuntu-2404`, `windows-x64` → `windows-2025`). Note this PR's own checks run under the **old** config; the new runner choices are not exercised until it lands on main. ## Risks Two things only a real run can confirm: disk headroom for the NSIS build on the GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores (predicted ~250s → ~300s, since only the 30s phase scales with cores). ## Follow-ups Split out of this PR to keep it to one concern: 1. **`MessagesTimeline.test.tsx` silently skips itself under load.** It defers `await import("./MessagesTimeline")` into `beforeAll(..., 30_000)`. In isolation the file runs in 3s, but under full-suite contention that hook hits its timeout and the file reports `18 tests | 18 skipped` at 30100ms *without failing*. Moving the DOM stubs to `vi.hoisted` fixes it structurally. This is pre-existing, but the slower runner in this PR makes it more likely — worth landing soon after. 2. **Drop the `merge_group` trigger**, now that the merge queue is retired. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
> [!NOTE] > The repo is public, so standard GitHub-hosted runners are free. Moves the two > jobs that gain least from paid hardware onto free runners and right-sizes a > third. Runner changes only — follow-ups tracked at the bottom. ## Problem An audit of the last 8 days of run history (all GitHub retains) put Blacksmith at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were paying for cores they could not use: - **Fork Test** spends 209s of its 248s in the `Test` step. Only the first ~30s is parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at 15-20% is `apps/server` alone (`transform 4.85s, import 75s, tests 211s` — await-bound tests pinning one or two workers while every other package has finished). It is long-poled, not short of cores, so slower cores cost far less than proportionally. - **Nightly Windows x64** was the least CPU-bound of the three desktop targets per the #51 metrics review. - **Fork Check** peaks at 4-5 cores during Typecheck; only ~54s of its 97s is CPU work at all. ## Fix - Fork Test → `ubuntu-24.04`, nightly Windows → `windows-2025` (free). - Fork Check → `blacksmith-4vcpu-ubuntu-2404`. macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%) and paces the whole nightly. Expected cost after this lands: ~$176/mo → ~$90/mo, leaving macOS (~$29/mo) as the largest Blacksmith item. ## Verification `actionlint` reports no new findings, both workflows parse, and the desktop build matrix script still emits the expected runner for each target (`macos-arm64` → `blacksmith-6vcpu-macos-15`, `linux-x64` → `blacksmith-8vcpu-ubuntu-2404`, `windows-x64` → `windows-2025`). Note this PR's own checks run under the **old** config; the new runner choices are not exercised until it lands on main. ## Risks Two things only a real run can confirm: disk headroom for the NSIS build on the GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores (predicted ~250s → ~300s, since only the 30s phase scales with cores). ## Follow-ups Split out of this PR to keep it to one concern: 1. **`MessagesTimeline.test.tsx` silently skips itself under load.** It defers `await import("./MessagesTimeline")` into `beforeAll(..., 30_000)`. In isolation the file runs in 3s, but under full-suite contention that hook hits its timeout and the file reports `18 tests | 18 skipped` at 30100ms *without failing*. Moving the DOM stubs to `vi.hoisted` fixes it structurally. This is pre-existing, but the slower runner in this PR makes it more likely — worth landing soon after. 2. **Drop the `merge_group` trigger**, now that the merge queue is retired. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
> [!NOTE] > The repo is public, so standard GitHub-hosted runners are free. Moves the two > jobs that gain least from paid hardware onto free runners and right-sizes a > third. Runner changes only — follow-ups tracked at the bottom. ## Problem An audit of the last 8 days of run history (all GitHub retains) put Blacksmith at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were paying for cores they could not use: - **Fork Test** spends 209s of its 248s in the `Test` step. Only the first ~30s is parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at 15-20% is `apps/server` alone (`transform 4.85s, import 75s, tests 211s` — await-bound tests pinning one or two workers while every other package has finished). It is long-poled, not short of cores, so slower cores cost far less than proportionally. - **Nightly Windows x64** was the least CPU-bound of the three desktop targets per the #51 metrics review. - **Fork Check** peaks at 4-5 cores during Typecheck; only ~54s of its 97s is CPU work at all. ## Fix - Fork Test → `ubuntu-24.04`, nightly Windows → `windows-2025` (free). - Fork Check → `blacksmith-4vcpu-ubuntu-2404`. macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%) and paces the whole nightly. Expected cost after this lands: ~$176/mo → ~$90/mo, leaving macOS (~$29/mo) as the largest Blacksmith item. ## Verification `actionlint` reports no new findings, both workflows parse, and the desktop build matrix script still emits the expected runner for each target (`macos-arm64` → `blacksmith-6vcpu-macos-15`, `linux-x64` → `blacksmith-8vcpu-ubuntu-2404`, `windows-x64` → `windows-2025`). Note this PR's own checks run under the **old** config; the new runner choices are not exercised until it lands on main. ## Risks Two things only a real run can confirm: disk headroom for the NSIS build on the GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores (predicted ~250s → ~300s, since only the 30s phase scales with cores). ## Follow-ups Split out of this PR to keep it to one concern: 1. **`MessagesTimeline.test.tsx` silently skips itself under load.** It defers `await import("./MessagesTimeline")` into `beforeAll(..., 30_000)`. In isolation the file runs in 3s, but under full-suite contention that hook hits its timeout and the file reports `18 tests | 18 skipped` at 30100ms *without failing*. Moving the DOM stubs to `vi.hoisted` fixes it structurally. This is pre-existing, but the slower runner in this PR makes it more likely — worth landing soon after. 2. **Drop the `merge_group` trigger**, now that the merge queue is retired. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
> [!NOTE] > The repo is public, so standard GitHub-hosted runners are free. Moves the two > jobs that gain least from paid hardware onto free runners and right-sizes a > third. Runner changes only — follow-ups tracked at the bottom. ## Problem An audit of the last 8 days of run history (all GitHub retains) put Blacksmith at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were paying for cores they could not use: - **Fork Test** spends 209s of its 248s in the `Test` step. Only the first ~30s is parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at 15-20% is `apps/server` alone (`transform 4.85s, import 75s, tests 211s` — await-bound tests pinning one or two workers while every other package has finished). It is long-poled, not short of cores, so slower cores cost far less than proportionally. - **Nightly Windows x64** was the least CPU-bound of the three desktop targets per the #51 metrics review. - **Fork Check** peaks at 4-5 cores during Typecheck; only ~54s of its 97s is CPU work at all. ## Fix - Fork Test → `ubuntu-24.04`, nightly Windows → `windows-2025` (free). - Fork Check → `blacksmith-4vcpu-ubuntu-2404`. macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%) and paces the whole nightly. Expected cost after this lands: ~$176/mo → ~$90/mo, leaving macOS (~$29/mo) as the largest Blacksmith item. ## Verification `actionlint` reports no new findings, both workflows parse, and the desktop build matrix script still emits the expected runner for each target (`macos-arm64` → `blacksmith-6vcpu-macos-15`, `linux-x64` → `blacksmith-8vcpu-ubuntu-2404`, `windows-x64` → `windows-2025`). Note this PR's own checks run under the **old** config; the new runner choices are not exercised until it lands on main. ## Risks Two things only a real run can confirm: disk headroom for the NSIS build on the GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores (predicted ~250s → ~300s, since only the 30s phase scales with cores). ## Follow-ups Split out of this PR to keep it to one concern: 1. **`MessagesTimeline.test.tsx` silently skips itself under load.** It defers `await import("./MessagesTimeline")` into `beforeAll(..., 30_000)`. In isolation the file runs in 3s, but under full-suite contention that hook hits its timeout and the file reports `18 tests | 18 skipped` at 30100ms *without failing*. Moving the DOM stubs to `vi.hoisted` fixes it structurally. This is pre-existing, but the slower runner in this PR makes it more likely — worth landing soon after. 2. **Drop the `merge_group` trigger**, now that the merge queue is retired. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
incognitojam
added a commit
that referenced
this pull request
Aug 15, 2026
> [!NOTE] > The repo is public, so standard GitHub-hosted runners are free. Moves the two > jobs that gain least from paid hardware onto free runners and right-sizes a > third. Runner changes only — follow-ups tracked at the bottom. ## Problem An audit of the last 8 days of run history (all GitHub retains) put Blacksmith at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were paying for cores they could not use: - **Fork Test** spends 209s of its 248s in the `Test` step. Only the first ~30s is parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at 15-20% is `apps/server` alone (`transform 4.85s, import 75s, tests 211s` — await-bound tests pinning one or two workers while every other package has finished). It is long-poled, not short of cores, so slower cores cost far less than proportionally. - **Nightly Windows x64** was the least CPU-bound of the three desktop targets per the #51 metrics review. - **Fork Check** peaks at 4-5 cores during Typecheck; only ~54s of its 97s is CPU work at all. ## Fix - Fork Test → `ubuntu-24.04`, nightly Windows → `windows-2025` (free). - Fork Check → `blacksmith-4vcpu-ubuntu-2404`. macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%) and paces the whole nightly. Expected cost after this lands: ~$176/mo → ~$90/mo, leaving macOS (~$29/mo) as the largest Blacksmith item. ## Verification `actionlint` reports no new findings, both workflows parse, and the desktop build matrix script still emits the expected runner for each target (`macos-arm64` → `blacksmith-6vcpu-macos-15`, `linux-x64` → `blacksmith-8vcpu-ubuntu-2404`, `windows-x64` → `windows-2025`). Note this PR's own checks run under the **old** config; the new runner choices are not exercised until it lands on main. ## Risks Two things only a real run can confirm: disk headroom for the NSIS build on the GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores (predicted ~250s → ~300s, since only the 30s phase scales with cores). ## Follow-ups Split out of this PR to keep it to one concern: 1. **`MessagesTimeline.test.tsx` silently skips itself under load.** It defers `await import("./MessagesTimeline")` into `beforeAll(..., 30_000)`. In isolation the file runs in 3s, but under full-suite contention that hook hits its timeout and the file reports `18 tests | 18 skipped` at 30100ms *without failing*. Moving the DOM stubs to `vi.hoisted` fixes it structurally. This is pre-existing, but the slower runner in this PR makes it more likely — worth landing soon after. 2. **Drop the `merge_group` trigger**, now that the merge queue is retired. --- Written by an agent (Claude Code, claude-opus-5).
incognitojam
added a commit
that referenced
this pull request
Aug 15, 2026
## Problem The merge queue was retired because it duplicated CI work, but Fork CI still carries its plumbing: a `merge_group` trigger and `github.event.merge_group.*` fallbacks in the `changes` job's SHA resolution. Nothing fires it, so it is dead config that implies a workflow the repo no longer uses. ## Fix Remove the trigger and the two fallbacks. `pull_request` and `push` events already resolve the same SHAs on their own: - `BASE_SHA` → `pull_request.base.sha` or `github.event.before` - `HEAD_SHA` → `pull_request.head.sha` or `github.sha` ## Verification Confirmed no merge queue is configured, so nothing is stranded by this: - The `PR + CI` ruleset on `main` contains only `pull_request` and `required_status_checks` rules — no `merge_queue` rule. - All four required checks (`Fork Changes`, `Fork Check`, `Fork Release Smoke`, `Fork Test`) run on `pull_request`, so they still report on every PR. Workflow parses and `actionlint` reports no new findings. Follow-up to #112. --- Written by an agent (Claude Code, claude-opus-5).
incognitojam
added a commit
that referenced
this pull request
Aug 15, 2026
…118) ## Problem `MessagesTimeline.test.tsx` needs DOM globals stubbed before its module graph is evaluated, because the web `unit` project runs on the **node** environment. It did that by deferring the import into a hook: ```ts let MessagesTimeline: typeof import("./MessagesTimeline").MessagesTimeline; beforeAll(async () => { vi.stubGlobal("window", { /* ... */ }); ({ MessagesTimeline } = await import("./MessagesTimeline")); }, 30_000); ``` That puts the module graph's transform cost *inside a hook timeout*. Run alone the file takes 3s, but under full-suite contention the hook hit its 30s timeout and the file reported `18 tests | 18 skipped` at 30100ms — **without failing**. CI stayed green having run 18 fewer tests than it appeared to. This is pre-existing, but #112 moved Fork Test to a 4-core free runner, which makes the contention that triggers it more likely. ## Fix Move the stubs into `vi.hoisted`, which runs ahead of imports, so `MessagesTimeline` is imported statically and no hook timeout wraps the module graph. This removes the failure mode structurally rather than by raising the timeout. `vi.hoisted` is already the idiom in ~10 other web test files. ## Verification - File alone: 18/18 pass. - Timing confirms the cost moved out of the hook phase: `tests 2.62s / import 619ms` before, `tests 98ms / import 2.16s` after. No hook timeout applies to the import phase. - Full `@t3tools/web` suite: 250 files / 2451 tests, **0 skipped**, exit 0. Previously this run showed MessagesTimeline at `18 tests | 18 skipped`. - `@t3tools/web` typecheck clean. Worth noting the original stall was intermittent (1 of 2 full runs), so a green run is not by itself proof. The argument for the fix is structural: there is no longer a timed hook around the import. --- Written by an agent (Claude Code, claude-opus-5).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The repo is public, so standard GitHub-hosted runners are free. Moves the two
jobs that gain least from paid hardware onto free runners and right-sizes a
third. Runner changes only — follow-ups tracked at the bottom.
Problem
An audit of the last 8 days of run history (all GitHub retains) put Blacksmith
at roughly $176/mo, with Fork CI the largest bucket at ~$80/mo. Two jobs were
paying for cores they could not use:
Teststep. Only the first ~30sis parallel transform/import fan-out at 100% CPU; the remaining ~2.5min at
15-20% is
apps/serveralone (transform 4.85s, import 75s, tests 211s—await-bound tests pinning one or two workers while every other package has
finished). It is long-poled, not short of cores, so slower cores cost far
less than proportionally.
per the Review Fork Nightly runner sizing with Blacksmith metrics #51 metrics review.
CPU work at all.
Fix
ubuntu-24.04, nightly Windows →windows-2025(free).blacksmith-4vcpu-ubuntu-2404.macOS deliberately stays on Blacksmith — it is genuinely CPU-bound (P95 ≥ 91%)
and paces the whole nightly.
Expected cost after this lands: ~$176/mo →
$90/mo, leaving macOS ($29/mo) asthe largest Blacksmith item.
Verification
actionlintreports no new findings, both workflows parse, and the desktopbuild matrix script still emits the expected runner for each target
(
macos-arm64→blacksmith-6vcpu-macos-15,linux-x64→blacksmith-8vcpu-ubuntu-2404,windows-x64→windows-2025).Note this PR's own checks run under the old config; the new runner choices
are not exercised until it lands on main.
Risks
Two things only a real run can confirm: disk headroom for the NSIS build on the
GitHub-hosted Windows runner, and Fork Test's actual wall time on 4 cores
(predicted ~250s → ~300s, since only the 30s phase scales with cores).
Follow-ups
Split out of this PR to keep it to one concern:
MessagesTimeline.test.tsxsilently skips itself under load. It defersawait import("./MessagesTimeline")intobeforeAll(..., 30_000). Inisolation the file runs in 3s, but under full-suite contention that hook hits
its timeout and the file reports
18 tests | 18 skippedat 30100ms withoutfailing. Moving the DOM stubs to
vi.hoistedfixes it structurally. This ispre-existing, but the slower runner in this PR makes it more likely — worth
landing soon after.
merge_grouptrigger, now that the merge queue is retired.Written by an agent (Claude Code, claude-opus-5).