Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -408,18 +408,19 @@ jobs:
- 'scripts/ci/docker-smoke.ts'
- 'scripts/generate-compatibility-version.ts'
- 'scripts/model-metadata.source.json'
# The image's final RUN imports version.ts to prove the generated compatibility
# manifest; these four files are its whole module closure (Bun.build metafile).
- 'src/routing/compatibility/version.ts'
- 'src/lab/digest.ts'
- 'src/lab/conformance/digest.ts'
- 'src/lab/conformance/jcs.ts'
- 'src/cli/index.ts'
# The image copies and runs src/, then builds the GUI with tsc and Vite.
# Include their inputs without selecting GUI tests or documentation alone.
- 'src/**'
- 'package.json'
- 'bun.lock'
- 'tsconfig.json'
- 'gui/package.json'
- 'gui/bun.lock'
- 'gui/src/**'
- 'gui/public/**'
- 'gui/index.html'
- 'gui/vite.config.ts'
- 'gui/tsconfig*.json'
- '.github/workflows/ci.yml'
# scripts/keyring-smoke.ts imports only src/lib/keyring-native.ts; the native binding
# itself arrives through package.json and bun.lock.
Expand Down
23 changes: 23 additions & 0 deletions tests/ci-workflows/ci-scope-gaps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ const scriptOf = (job: Job): string => (job.steps ?? []).map(step => step.run ??
const ACTION_PATH = ".github/actions/setup-project-bun/action.yml";
const HELPER_PATH = "native/remote-workspace-helper/src/main.rs";

describe("Docker build and runtime input scope", () => {
test("selects runtime sources and every GUI build input", () => {
for (const path of [
"src/config.ts", "src/config/paths.ts", "src/server/index.ts", "src/service.ts",
"gui/src/App.tsx", "gui/src/style.css", "gui/public/icon.svg", "gui/index.html",
"gui/vite.config.ts", "gui/tsconfig.json", "gui/tsconfig.app.json", "gui/tsconfig.node.json",
"gui/package.json", "gui/bun.lock",
]) {
expect(`${path}:ci=${matches(filters.ci, path)}`).toBe(`${path}:ci=true`);
expect(`${path}:docker=${matches(filters.docker, path)}`).toBe(`${path}:docker=true`);
}
});

test("does not select Docker for tests or documentation alone", () => {
for (const path of [
"tests/server/server-live.test.ts", "gui/tests/claude-code-save.test.ts",
"gui/README.md", "docs-site/src/content/docs/index.mdx", "structure/runtime.md",
]) {
expect(`${path}:docker=${matches(filters.docker, path)}`).toBe(`${path}:docker=false`);
}
});
});

describe("an edit to the setup action alone", () => {
test("selects a job that runs the action and checks what it installed", () => {
const selected = jobsSelectedBy(filtersMatching(ACTION_PATH))
Expand Down
19 changes: 18 additions & 1 deletion tests/ci-workflows/ci-scope-reduction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const MACOS_JOBS = ["platform-macos", "widget"] as const;
/** The two smoke jobs whose matrix legs shrink with the event and native selection. */
const MATRIX_JOBS = ["keyring-smoke", "npm-global-smoke"] as const;

type SelectionInputs = { event_name: string; ci: string; native: string; desktop?: string };
type SelectionInputs = { event_name: string; ci: string; native: string; desktop?: string; docker?: string };

function term(source: string, inputs: SelectionInputs): string | boolean {
const text = source.trim();
Expand All @@ -72,6 +72,7 @@ function term(source: string, inputs: SelectionInputs): string | boolean {
if (output[1] === "ci") return inputs.ci;
if (output[1] === "native") return inputs.native;
if (output[1] === "desktop") return inputs.desktop ?? "false";
if (output[1] === "docker") return inputs.docker ?? "false";
}
throw new Error(`unsupported expression term: ${text}`);
}
Expand Down Expand Up @@ -315,6 +316,22 @@ describe("the push trigger", () => {
});
});

describe("Docker PR selection", () => {
test("selects only its Ubuntu smoke for matching inputs without widening event policy", () => {
const job = jobs["docker-smoke"]!;
expect(job["runs-on"]).toBe("ubuntu-latest");
for (const ci of ["true", "false"]) {
for (const docker of ["true", "false"]) {
expect(evaluate(job.if!, { event_name: "pull_request", ci, docker, native: "false" }))
.toBe(ci === "true" && docker === "true");
}
}
for (const event_name of ["push", "workflow_dispatch", "schedule"]) {
expect(evaluate(job.if!, { event_name, ci: "false", docker: "false", native: "false" })).toBe(true);
}
});
});

describe("the native path filter", () => {
test("lists exactly the surfaces the native-gated jobs build", () => {
// Exact membership, because every pattern here is a cost decision: widening
Expand Down
Loading