From 708767e6b091c45d9e820578920c11aa5faa05d9 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sat, 31 Oct 2026 19:01:20 +0000 Subject: [PATCH 1/2] fix(ci): a change to the T3 Connect troubleshooting guide runs the server test that reads it ci-changes.cjs treats everything under docs/ as inert, but ConnectReachability.test.ts checks that each troubleshooting section names a heading in docs/user/t3-connect-troubleshooting.md. A docs-only PR that renames one of those headings skipped the server tests, so main's own full run failed after it merged. The guide now maps to the server package, and check:changed runs that test when the guide changes. Co-Authored-By: Claude Opus 5.5 --- .github/scripts/ci-changes.cjs | 6 ++++-- scripts/check-changed.test.ts | 9 +++++++++ scripts/check-changed.ts | 4 ++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/scripts/ci-changes.cjs b/.github/scripts/ci-changes.cjs index 77a526076de4..0f817be60c35 100644 --- a/.github/scripts/ci-changes.cjs +++ b/.github/scripts/ci-changes.cjs @@ -27,6 +27,8 @@ const EXTRA_OWNERS = [ [/^native\/browser-secret\//, ["@t3tools/desktop"]], [/^native\/kde-snap-shot\//, ["@t3tools/desktop"]], [/^native\/libghostty-vt\//, ["@t3tools/web"]], + // apps/server/src/cloud/ConnectReachability.test.ts checks the guide's headings. + [/^docs\/user\/t3-connect-troubleshooting\.md$/, ["t3"]], ]; const RUST = /^native\/(resource-monitor|kde-snap-shot|hyprland-snap-shot)\//; @@ -92,11 +94,11 @@ function readWorkspace() { // [] means inert; null means unknown and requires every job. function ownersOf(file, packages) { - if (INERT.some((pattern) => pattern.test(file))) return []; + const extra = EXTRA_OWNERS.flatMap(([pattern, names]) => (pattern.test(file) ? names : [])); + if (INERT.some((pattern) => pattern.test(file))) return extra; // A manifest can change dependencies or versions other packages read. if (path.posix.basename(file) === "package.json") return null; if (RUNS_EVERYTHING.some((pattern) => pattern.test(file))) return null; - const extra = EXTRA_OWNERS.flatMap(([pattern, names]) => (pattern.test(file) ? names : [])); // scripts/build-desktop-artifact.test.ts reads the crates' sources. if (RUST.test(file)) return ["@t3tools/scripts", ...extra]; diff --git a/scripts/check-changed.test.ts b/scripts/check-changed.test.ts index b01c3556766c..06391184cbf3 100644 --- a/scripts/check-changed.test.ts +++ b/scripts/check-changed.test.ts @@ -21,6 +21,7 @@ import { runSteps, type Step, } from "./check-changed.ts"; +import { decide, readWorkspace } from "../.github/scripts/ci-changes.cjs"; const GiB = 1024 ** 3; @@ -33,6 +34,14 @@ describe("check:changed", () => { assert.strictEqual(defaultConcurrency(1, 64 * GiB), 1); }); + it("runs the server tests for the one guide they read and leaves other docs inert", () => { + const packages = readWorkspace(); + assert.isTrue( + decide(["docs/user/t3-connect-troubleshooting.md"], packages, false).outputs.test_server, + ); + assert.deepStrictEqual(decide(["docs/user/install.md"], packages, false).affected, []); + }); + it.effect( "keeps weighted steps within the budget, in order, and serial steps one at a time", () => diff --git a/scripts/check-changed.ts b/scripts/check-changed.ts index b23289211b90..97512b59b128 100644 --- a/scripts/check-changed.ts +++ b/scripts/check-changed.ts @@ -312,6 +312,10 @@ const checkChanged = Effect.fn("checkChanged")(function* (input: { // It reads files other than the ones beside it, so no changed file selects it. if (affected.includes("t3")) tests.add("apps/server/src/provider/AgentContextBudget.test.ts"); + if (files.includes("docs/user/t3-connect-troubleshooting.md")) { + tests.add("apps/server/src/cloud/ConnectReachability.test.ts"); + } + // React Compiler coverage compiles every client source file, so run only the // changed files' cases, in one extra step: a -t filter in the main test step // would drop every other test. An app is skipped when the main step already From f60977a3fc76910efc75f948511e287a0e5dfaa3 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sat, 31 Oct 2026 19:37:08 +0000 Subject: [PATCH 2/2] test(scripts): cover check:changed selecting the T3 Connect guide's test The guide-specific selection lived inline in checkChanged, so no test failed if it was removed. It moves into docReaderTests, which the guide test now checks, and runs before the AgentContextBudget line. Co-Authored-By: Claude Opus 5.5 --- scripts/check-changed.test.ts | 4 ++++ scripts/check-changed.ts | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/check-changed.test.ts b/scripts/check-changed.test.ts index 06391184cbf3..b0e0fe01e851 100644 --- a/scripts/check-changed.test.ts +++ b/scripts/check-changed.test.ts @@ -17,6 +17,7 @@ import * as TestClock from "effect/testing/TestClock"; import { comparisonBase, defaultConcurrency, + docReaderTests, gitLines, runSteps, type Step, @@ -39,6 +40,9 @@ describe("check:changed", () => { assert.isTrue( decide(["docs/user/t3-connect-troubleshooting.md"], packages, false).outputs.test_server, ); + assert.deepStrictEqual(docReaderTests(["docs/user/t3-connect-troubleshooting.md"]), [ + "apps/server/src/cloud/ConnectReachability.test.ts", + ]); assert.deepStrictEqual(decide(["docs/user/install.md"], packages, false).affected, []); }); diff --git a/scripts/check-changed.ts b/scripts/check-changed.ts index 97512b59b128..583b00b5361c 100644 --- a/scripts/check-changed.ts +++ b/scripts/check-changed.ts @@ -190,6 +190,12 @@ const override = Effect.fn("checkChanged.override")(function* ( return value; }); +// Tests that read a doc; a changed doc has no test beside it to select them. +export const docReaderTests = (files: ReadonlyArray) => + files.includes("docs/user/t3-connect-troubleshooting.md") + ? ["apps/server/src/cloud/ConnectReachability.test.ts"] + : []; + const checkChanged = Effect.fn("checkChanged")(function* (input: { readonly ref: Option.Option; readonly concurrency: Option.Option; @@ -309,13 +315,10 @@ const checkChanged = Effect.fn("checkChanged")(function* (input: { if (entry.startsWith(prefix) && TEST.test(entry)) tests.add(path.join(dir, entry)); } } + for (const test of docReaderTests(files)) tests.add(test); // It reads files other than the ones beside it, so no changed file selects it. if (affected.includes("t3")) tests.add("apps/server/src/provider/AgentContextBudget.test.ts"); - if (files.includes("docs/user/t3-connect-troubleshooting.md")) { - tests.add("apps/server/src/cloud/ConnectReachability.test.ts"); - } - // React Compiler coverage compiles every client source file, so run only the // changed files' cases, in one extra step: a -t filter in the main test step // would drop every other test. An app is skipped when the main step already