fix(ci): scope maintainer activity helper checks (#130790)

This commit is contained in:
Peter Steinberger
2026-08-27 00:45:54 -07:00
committed by GitHub
parent fa19150155
commit 63dcd40724
4 changed files with 136 additions and 20 deletions
+3
View File
@@ -16,6 +16,9 @@ const SURFACE_PATTERNS = [
["app", /^(?:apps\/|Swabble\/|appcast\.xml$)/u],
["rootTest", /^test\//u],
["testFixture", /^test-fixtures\//u],
// This hidden helper only reports maintainer activity; it has no product consumers.
// Match the reviewed leaf exactly so unreviewed skill executables still fail safe.
["rootTooling", /^\.agents\/skills\/openclaw-pr-maintainer\/scripts\/github-activity\.sh$/u],
[
"rootTooling",
/^(?:scripts\/|test\/vitest\/|\.github\/|\.vscode\/|config\/|deploy\/|git-hooks\/|Dockerfile\.sandbox(?:-(?:browser|common))?$|Makefile$|docker-setup\.sh$|setup-podman\.sh$|openclaw\.podman\.env$|skills\/pyproject\.toml$|vitest(?:\..+)?\.config\.ts$|tsconfig.*\.json$|\.dockerignore$|\.gitignore$|\.jscpd\.json$|\.npmignore$|\.pre-commit-config\.yaml$|\.swiftformat$|\.swiftlint\.yml$|\.oxlint.*|\.oxfmt.*)/u,
+89 -19
View File
@@ -45,6 +45,7 @@ import { cleanupTempDirs, makeTempDir as makeTempRepoRoot } from "../helpers/tem
const tempDirs: string[] = [];
const repoRoot = process.cwd();
const githubActivityHelper = ".agents/skills/openclaw-pr-maintainer/scripts/github-activity.sh";
const tsxImport = pathToFileURL(createRequire(import.meta.url).resolve("tsx")).href;
type ExecFileSyncFailure = Error & { status?: number | null; stderr?: Buffer };
const nestedGitEnvKeys = [
@@ -380,6 +381,41 @@ describe("scripts/changed-lanes", () => {
);
});
it("keeps the hidden maintainer helper trio on tooling checks through both CLIs", () => {
const paths = [
githubActivityHelper,
".agents/skills/openclaw-pr-maintainer/SKILL.md",
"test/scripts/github-activity-helper.test.ts",
];
const lanes = runChangedLanesCli(repoRoot, ["--json", "--", ...paths]);
const result = runRepoScript("scripts/check-changed.mjs", ["--dry-run", "--", ...paths]);
expectLanes(lanes.lanes, { docs: true, testRoot: true, tooling: true });
expect(lanes).toMatchObject({ extensionImpactFromCore: false, docsOnly: false });
expect(lanes.paths.toSorted()).toEqual(paths.toSorted());
expect(result.status).toBe(0);
expect(result.stderr).toContain("[check:changed:dry-run] lanes=testRoot, docs, tooling");
const commands = result.stderr
.split("\n")
.filter((line) => line.startsWith("[check:changed:dry-run] would run: "))
.map((line) => line.replace("[check:changed:dry-run] would run: ", ""));
expect(commands).toEqual([
"pnpm check:no-conflict-markers",
"pnpm check:changelog-attributions",
"pnpm check:doctor-deprecation-registry",
"pnpm lint:extensions:no-guarded-wildcard-reexports",
"pnpm lint:extensions:no-plugin-sdk-wildcard-reexports",
"pnpm dup:check:coverage",
"pnpm check:coercion-helpers",
"pnpm deps:pins:check",
`pnpm format:check --no-error-on-unmatched-pattern -- ${lanes.paths.join(" ")}`,
"pnpm deps:patches:check",
"node scripts/report-test-temp-creations.mjs --base origin/main --head HEAD",
"pnpm tsgo:test:root",
"pnpm lint:scripts",
]);
});
it("includes untracked worktree files in the default local diff", () => {
const dir = makeTempRepoRoot(tempDirs, "openclaw-changed-lanes-");
git(dir, ["init", "-q", "--initial-branch=main"]);
@@ -1276,31 +1312,64 @@ describe("scripts/changed-lanes", () => {
}
});
it("expands public core/plugin contracts to extension validation", () => {
const result = detectChangedLanes(["src/plugin-sdk/core.ts"]);
const plan = createChangedCheckPlan(result);
it.each([{ otherPaths: [] }, { otherPaths: [githubActivityHelper] }])(
"expands public core/plugin contracts with $otherPaths to extension validation",
({ otherPaths }) => {
const result = detectChangedLanes(["src/plugin-sdk/core.ts", ...otherPaths]);
const plan = createChangedCheckPlan(result);
expect(result.extensionImpactFromCore).toBe(true);
expectLanes(result.lanes, {
core: true,
coreTests: true,
extensions: true,
extensionTests: true,
});
expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:core");
expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:extensions:test");
});
expect(result.extensionImpactFromCore).toBe(true);
expectLanes(result.lanes, {
core: true,
coreTests: true,
extensions: true,
extensionTests: true,
tooling: otherPaths.length > 0,
});
expect(plan.commands.map((command) => command.args[0])).toEqual(
expect.arrayContaining([
"tsgo:core",
"tsgo:core:test",
"tsgo:extensions",
"tsgo:extensions:test",
]),
);
},
);
it("fails safe for root config changes", () => {
const result = detectChangedLanes(["pnpm-lock.yaml"]);
const plan = createChangedCheckPlan(result);
it.each([
"pnpm-lock.yaml",
".agents/skills/openclaw-pr-maintainer/scripts/unknown-helper.sh",
`${githubActivityHelper}.bak`,
`${githubActivityHelper}/child.sh`,
`other/${githubActivityHelper}`,
".agents/skills/openclaw-pr-maintainer-extra/scripts/github-activity.sh",
".agents/config.json",
".agents/skills/autoreview/scripts/autoreview",
".agents/skills/openclaw-changelog-update/scripts/verify-release-notes.mjs",
])("fails safe for %s even alongside the hidden maintainer helper", (changedPath) => {
for (const paths of [[changedPath], [githubActivityHelper, changedPath]]) {
const result = detectChangedLanes(paths);
const plan = createChangedCheckPlan(result);
expect(result.lanes.all).toBe(true);
expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:all");
expect(plan.commands.map((command) => command.args[0])).not.toContain("test");
expectLanes(result.lanes, { all: true, tooling: paths.includes(githubActivityHelper) });
expect(result.extensionImpactFromCore).toBe(true);
expect(plan.commands.map((command) => command.args[0])).toContain("tsgo:all");
expect(plan.commands.map((command) => command.args[0])).toContain("lint");
expect(plan.commands.map((command) => command.args[0])).not.toContain("test");
}
});
it.each([
...[
githubActivityHelper,
`./${githubActivityHelper}`,
githubActivityHelper.replaceAll("/", "\\"),
].map((helperPath) => ({
name: `routes hidden maintainer helper ${helperPath} to tooling instead of all lanes`,
paths: [helperPath],
excludesTests: true,
})),
{
name: "routes gitignore changes to tooling instead of all lanes",
paths: [".gitignore"],
@@ -1356,6 +1425,7 @@ describe("scripts/changed-lanes", () => {
const commands = createChangedCheckPlan(result).commands.map((command) => command.args[0]);
expectLanes(result.lanes, { tooling: true });
expect(result.extensionImpactFromCore).toBe(false);
expect(commands).toContain("lint:scripts");
expect(commands).not.toContain("tsgo:all");
if (excludesTests) {
+3
View File
@@ -17,6 +17,9 @@ describe("changed path facts", () => {
["test/scripts/changed-lanes.test.ts", "rootTest"],
["test-fixtures/sample.ts", "testFixture"],
["scripts/check-changed.mjs", "rootTooling"],
[".agents/skills/openclaw-pr-maintainer/scripts/github-activity.sh", "rootTooling"],
[".agents/skills/openclaw-pr-maintainer/SKILL.md", "docs"],
["test/scripts/github-activity-helper.test.ts", "rootTest"],
[".github/workflows/ci.yml", "rootTooling"],
["package.json", "rootGlobal"],
["assets/legacy.png", "legacyRootAsset"],
+41 -1
View File
@@ -17,11 +17,15 @@ import {
listExtensionTestFilesForRoots,
resolveExtensionTestConfig,
} from "../../scripts/lib/extension-test-plan.mts";
import { hasImportGraphImpactOnTargets } from "../../scripts/test-projects.test-support.mts";
import {
hasImportGraphImpactOnTargets,
resolveChangedTestTargetPlan,
} from "../../scripts/test-projects.test-support.mts";
import { listGitTrackedFiles } from "../../src/test-utils/repo-files.js";
import { isGatewayServerTestFile } from "../vitest/vitest.gateway-server-paths.mjs";
const CODEX_TEST_PROCESS_FILE_LIMIT = 12;
const githubActivityHelper = ".agents/skills/openclaw-pr-maintainer/scripts/github-activity.sh";
function expectBoundedCodexFallback(
shards: ReturnType<typeof createChangedExtensionFallbackShards>,
@@ -402,6 +406,42 @@ describe("CI changed Node test plan", () => {
expect(createChangedExtensionFallbackShards(["docs/ci.md"])).toEqual([]);
});
it.each([
{ name: "helper alone", changedPaths: [githubActivityHelper] },
{
name: "helper trio",
changedPaths: [
githubActivityHelper,
".agents/skills/openclaw-pr-maintainer/SKILL.md",
"test/scripts/github-activity-helper.test.ts",
],
},
])(
"keeps hidden maintainer helper targets and compact core fallback for $name",
({ changedPaths }) => {
expect(hasCoreExtensionImpact(changedPaths)).toBe(false);
expect(createChangedExtensionFallbackShards(changedPaths)).toEqual([]);
expect(resolveChangedTestTargetPlan(changedPaths, { broad: true })).toMatchObject({
mode: "targets",
targets: expect.arrayContaining(["test/scripts/github-activity-helper.test.ts"]),
});
expect(createChangedNodeTestShards(changedPaths)).toBeNull();
},
);
it.each([
"src/plugin-sdk/core.ts",
".agents/skills/openclaw-pr-maintainer/scripts/unknown-helper.sh",
])(
"retains all extension configs for the hidden maintainer helper mixed with %s",
(changedPath) => {
const paths = [githubActivityHelper, changedPath];
expect(hasCoreExtensionImpact(paths)).toBe(true);
expect(createChangedNodeTestShards(paths)).toBeNull();
expectAllExtensionConfigs(createChangedExtensionFallbackShards(paths));
},
);
it.each([
{
changedPath: "extensions/browser/src/browser/cdp.helpers.test.ts",