Files
tutti/tools/scripts/run-check-changed-targets.test.mjs
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

384 lines
10 KiB
JavaScript

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
buildGoLintLane,
buildGoTestLane,
buildPackageTestCommand,
discoverGoModuleRoots,
isBuiltinGenerateRequired,
resolveGoModuleRoot,
resolveGoValidationTargets
} from "./run-check-changed-targets.mjs";
const goModuleRoots = [
"apps/cli",
"packages/agent/daemon",
"packages/agent/session-replay",
"packages/agent/store-sqlite",
"packages/agent/store-sqlite/canonical",
"packages/clients/market-go",
"packages/connector/daemon/adapters/controlplane",
"packages/connector/daemon/adapters/sqlite",
"packages/connector/daemon/application",
"packages/connector/daemon/core",
"packages/connector/runtime",
"packages/device-link",
"packages/events/stream-go",
"packages/workspace/issues",
"services/tuttid"
];
describe("discoverGoModuleRoots", () => {
it("reads every module from go.work instead of a maintained whitelist", () => {
const roots = discoverGoModuleRoots({
root: "/repo",
spawnSyncImpl: () => ({
status: 0,
stdout: JSON.stringify({
Use: [
{ DiskPath: "./packages/connector/daemon/core" },
{ DiskPath: "./packages/agent/session-replay" },
{ DiskPath: "./services/tuttid" }
]
})
})
});
assert.deepEqual(roots, [
"packages/agent/session-replay",
"packages/connector/daemon/core",
"services/tuttid"
]);
});
});
describe("resolveGoModuleRoot", () => {
it("maps changed files to their Go module root", () => {
assert.equal(
resolveGoModuleRoot(
"services/tuttid/service/workspace/apps_install_progress.go",
goModuleRoots
),
"services/tuttid"
);
assert.equal(
resolveGoModuleRoot("apps/cli/internal/app/foo.go", goModuleRoots),
"apps/cli"
);
assert.equal(
resolveGoModuleRoot(
"packages/agent/session-replay/replay.go",
goModuleRoots
),
"packages/agent/session-replay"
);
assert.equal(
resolveGoModuleRoot(
"packages/connector/daemon/core/application.go",
goModuleRoots
),
"packages/connector/daemon/core"
);
assert.equal(
resolveGoModuleRoot(
"packages/clients/market-go/client.go",
goModuleRoots
),
"packages/clients/market-go"
);
assert.equal(
resolveGoModuleRoot(
"packages/agent/store-sqlite/store.go",
goModuleRoots
),
"packages/agent/store-sqlite"
);
assert.equal(
resolveGoModuleRoot(
"packages/agent/store-sqlite/canonical/vocabulary.go",
goModuleRoots
),
"packages/agent/store-sqlite/canonical"
);
assert.equal(
resolveGoModuleRoot(
"packages/device-link/mobile/probe.go",
goModuleRoots
),
"packages/device-link"
);
assert.equal(
resolveGoModuleRoot("packages/events/stream-go/stream.go", goModuleRoots),
"packages/events/stream-go"
);
assert.equal(
resolveGoModuleRoot(
"packages/workspace/issues/service.go",
goModuleRoots
),
"packages/workspace/issues"
);
});
});
describe("resolveGoValidationTargets", () => {
it("scopes lint and test targets to changed Go packages", () => {
const targets = resolveGoValidationTargets(
[
"services/tuttid/service/workspace/apps_install_progress.go",
"services/tuttid/service/workspace/apps_install_progress_test.go"
],
{ moduleRoots: goModuleRoots }
);
assert.deepEqual(Array.from(targets.lintByModule.get("services/tuttid")), [
"./service/workspace"
]);
assert.deepEqual(Array.from(targets.testByModule.get("services/tuttid")), [
"./service/workspace/..."
]);
});
it("runs the full module when go.mod changes", () => {
const targets = resolveGoValidationTargets(["services/tuttid/go.mod"], {
moduleRoots: goModuleRoots
});
assert.deepEqual(Array.from(targets.testByModule.get("services/tuttid")), [
"./..."
]);
});
it("skips deleted Go packages when the path no longer exists", () => {
const targets = resolveGoValidationTargets(
[
"packages/agent/daemon/activity/hostquery/service.go",
"packages/agent/daemon/activity/ingress/service.go",
"packages/agent/daemon/internal/guestdesktoprelay/v1/types.go"
],
{ moduleRoots: goModuleRoots, pathExists: () => false }
);
assert.equal(targets, null);
});
it("keeps Go lanes for deleted files inside existing packages", () => {
const targets = resolveGoValidationTargets(
["services/tuttid/service/workspace/deleted_file.go"],
{ moduleRoots: goModuleRoots, pathExists: () => true }
);
assert.deepEqual(Array.from(targets.lintByModule.get("services/tuttid")), [
"./service/workspace"
]);
assert.deepEqual(Array.from(targets.testByModule.get("services/tuttid")), [
"./service/workspace/..."
]);
});
it("does not create Go lanes for shared selector scripts", () => {
const targets = resolveGoValidationTargets(
["tools/scripts/run-changed-go-validation.mjs"],
{
moduleRoots: goModuleRoots,
pathExists: () => true
}
);
assert.equal(targets, null);
});
});
describe("buildPackageTestCommand", () => {
it("runs only changed test files", () => {
const command = buildPackageTestCommand({
baseRef: "origin/main",
fileExists: () => true,
packageFiles: [
"packages/agent/gui/agent-gui/agentGuiNode/AgentComposerSettingsMenus.spec.tsx"
],
packageInfo: {
name: "@tutti-os/agent-gui",
root: "packages/agent/gui",
scripts: {
test: "vitest run --environment jsdom"
}
},
pnpmCommand: "pnpm"
});
assert.deepEqual(command, [
"pnpm",
"--filter",
"@tutti-os/agent-gui",
"exec",
"vitest",
"run",
"--environment",
"jsdom",
"agent-gui/agentGuiNode/AgentComposerSettingsMenus.spec.tsx"
]);
});
it("skips package test lanes for deleted test files", () => {
const command = buildPackageTestCommand({
baseRef: "origin/main",
fileExists: () => false,
packageFiles: [
"packages/ui/system/src/components/style-contracts.test.ts"
],
packageInfo: {
name: "@tutti-os/ui-system",
root: "packages/ui/system",
scripts: {
test: "vitest run"
}
},
pnpmCommand: "pnpm"
});
assert.equal(command, null);
});
it("uses vitest --changed for source-only package changes", () => {
const command = buildPackageTestCommand({
baseRef: "origin/main",
packageFiles: [
"packages/agent/gui/agent-gui/agentGuiNode/AgentComposer.tsx"
],
packageInfo: {
name: "@tutti-os/agent-gui",
root: "packages/agent/gui",
scripts: {
test: "vitest run --environment jsdom"
}
},
pnpmCommand: "pnpm"
});
assert.deepEqual(command, [
"pnpm",
"--filter",
"@tutti-os/agent-gui",
"exec",
"vitest",
"run",
"--environment",
"jsdom",
"--changed",
"origin/main"
]);
});
it("uses the package test script for compound vitest scripts", () => {
const command = buildPackageTestCommand({
baseRef: "origin/main",
fileExists: () => true,
packageFiles: [
"services/tuttid/builtin-apps/tutti-onboarding/src/App.test.jsx"
],
packageInfo: {
name: "@tutti-os/builtin-tutti-onboarding",
root: "services/tuttid/builtin-apps/tutti-onboarding",
scripts: {
test: "vitest run && node scripts/check-assets.mjs"
}
},
pnpmCommand: "pnpm"
});
assert.deepEqual(command, [
"pnpm",
"--filter",
"@tutti-os/builtin-tutti-onboarding",
"test"
]);
});
it("runs the full package test script for source-only compound scripts", () => {
const command = buildPackageTestCommand({
baseRef: "origin/main",
packageFiles: [
"services/tuttid/builtin-apps/tutti-onboarding/src/App.jsx"
],
packageInfo: {
name: "@tutti-os/builtin-tutti-onboarding",
root: "services/tuttid/builtin-apps/tutti-onboarding",
scripts: {
test: "vitest run && node scripts/check-assets.mjs"
}
},
pnpmCommand: "pnpm"
});
assert.deepEqual(command, [
"pnpm",
"--filter",
"@tutti-os/builtin-tutti-onboarding",
"test"
]);
});
});
describe("builtin onboarding ensure", () => {
it("requires full generate when onboarding sources change", () => {
assert.equal(
isBuiltinGenerateRequired([
"services/tuttid/builtin-apps/tutti-onboarding/src/App.jsx"
]),
true
);
assert.equal(
isBuiltinGenerateRequired([
"services/tuttid/builtin-apps/generated/tutti-onboarding/placeholder.txt"
]),
false
);
});
it("prepends ensure commands for tuttid Go tests", () => {
const lane = buildGoTestLane({
moduleRoot: "services/tuttid",
targets: new Set(["./service/workspace/..."]),
pnpmCommand: "pnpm",
shellQuote: (value) => value,
forceBuiltinGenerate: false
});
assert.match(lane.command[2], /package:builtin:check/);
assert.match(lane.command[2], /generate:builtin-apps\) && cd/);
assert.match(lane.command[2], /go test \.\/service\/workspace\/\.\.\./);
});
it("requires forced builtin generation before tuttid Go tests", () => {
const lane = buildGoTestLane({
moduleRoot: "services/tuttid",
targets: new Set(["./service/workspace/..."]),
pnpmCommand: "pnpm",
shellQuote: (value) => value,
forceBuiltinGenerate: true
});
assert.match(lane.command[2], /^pnpm generate:builtin-apps/);
assert.match(lane.command[2], /generate:builtin-apps && cd/);
});
});
describe("buildGoLintLane", () => {
it("ensures builtin assets before linting tuttid", () => {
const lane = buildGoLintLane({
forceBuiltinGenerate: false,
golangciLintBinary: "/tmp/go/bin/golangci-lint",
moduleRoot: "services/tuttid",
pnpmCommand: "pnpm",
targets: new Set(["./service/workspace/..."]),
workspaceRoot: "/repo",
shellQuote: (value) => value
});
assert.match(lane.command[2], /package:builtin:check/);
assert.match(lane.command[2], /generate:builtin-apps\) && cd/);
assert.match(lane.command[2], /\/tmp\/go\/bin\/golangci-lint run/);
assert.match(lane.command[2], /--allow-parallel-runners/);
});
});