Merge current master and preserve Pi instruction-copy imports

This commit is contained in:
Dotta committed 2026-10-09 08:09:06 -05:00
commit 2c88adc683
45 files changed
+6154 -4543

No files matched your search

@@ -244,10 +244,10 @@ test("release verify workflow covers the same split test surface as stable PR ve
assert.match(buildJob, /persist-credentials: false/);
assert.doesNotMatch(buildJob, /cache: pnpm/);
for (const group of ["general-server-without-chat", "general-chat", "general-workspaces-a", "general-workspaces-b"]) {
for (const group of ["general-server-without-chat-or-native-runner", "general-chat", "general-workspaces-a", "general-workspaces-b"]) {
assert.match(verifyWorkflow, new RegExp(`group: ${group}`));
}
for (const [group, count] of [["general-server-without-chat", 10], ["general-chat", 3]]) {
for (const [group, count] of [["general-server-without-chat-or-native-runner", 10], ["general-chat", 3]]) {
const rows = [...verifyWorkflow.matchAll(new RegExp(`group: ${group}\\n\\s+group_label: [^\\n]+\\n\\s+shard_index: (\\d+)\\n\\s+shard_count: (\\d+)`, "g"))];
assert.deepEqual(rows.map((row) => [Number(row[1]), Number(row[2])]),
Array.from({ length: count }, (_, index) => [index, count]));
@@ -271,6 +271,30 @@ test("release verify workflow covers the same split test surface as stable PR ve
assert.match(verifyWorkflow, /pnpm test:run:serialized -- --shard-index/);
});
test("release verification builds native test binaries in a required Rust-cached lane", () => {
const workflow = readWorkflow("release-verify.yml");
const runnerJob = workflow.match(/ verify_paperclip_runner:\n[\s\S]*?(?=\n [A-Za-z0-9_-]+:|$)/)?.[0] ?? "";
assert.equal((runnerJob.match(/- lane: server-integration/g) ?? []).length, 1);
assert.doesNotMatch(runnerJob, /continue-on-error/);
assert.match(runnerJob, /timeout-minutes: 20/);
assert.match(runnerJob, /shared-key: release-runner-v2/);
assert.match(runnerJob, /cache-workspace-crates: false/);
assert.match(runnerJob, /cache-bin: false/);
assert.match(runnerJob, /save-if: \$\{\{ matrix\.lane == 'rust'/);
assert.match(runnerJob, /Build native server test binaries\n\s+if: \$\{\{ matrix\.lane == 'server-integration' \}\}\n\s+timeout-minutes: 10/);
assert.match(runnerJob, /pnpm build:rust\n\s+cargo build --release --manifest-path runner\/Cargo\.toml --locked -p paperclip-runner-core --bin paperclip-runnerd --bin fake-codex-app-server/);
assert.match(runnerJob, /Run native server integration suites\n\s+if: \$\{\{ matrix\.lane == 'server-integration' \}\}\n\s+run: pnpm test:run:general -- --group general-server-native-runner/);
assert.ok(runnerJob.indexOf("Cache Runner Rust dependencies") < runnerJob.indexOf("Build native server test binaries"));
assert.ok(runnerJob.indexOf("Build native server test binaries") < runnerJob.indexOf("Run native server integration suites"));
// The reusable workflow result includes every matrix child. Its caller must
// await that result without an override that can certify a failed native lane.
const cloud = readWorkflow("cloud-readiness.yml");
assert.match(cloud, /verify:[\s\S]*?uses: \.\/\.github\/workflows\/release-verify\.yml/);
assert.match(cloud, /source_verified:[\s\S]*?needs: \[verify\]/);
assert.doesNotMatch(cloud, /continue-on-error|always\(\)/);
});
test("Runner eval workflows pin actions and gate paid live execution", () => {
const actionPinWorkflows = [
readWorkflow("release-verify.yml"),
@@ -319,9 +319,8 @@ test("12 PR without-chat shards plus the dedicated chat and native-runner lanes
assert.ok(defaultRun.generalServerSuiteCount === full.generalServerSuiteCount);
});
// Mirrors release-verify.yml (10 shards, called by the Release and Cloud
// readiness workflows) and local runs: no Rust-cached vitest lane exists
// there, so the native-runner suite must stay in the server shards.
// The legacy group and local default must remain complete when a caller has
// not selected a separate native lane.
for (const [caller, envOverrides] of [["Release", { GITHUB_WORKFLOW: "Release" }], ["no ambient workflow", {}]]) {
test(`10 without-chat shards under ${caller} keep the native-runner suite and cover the server group with chat alone`, () => {
const full = dryRunJson(["--mode", "general", "--group", "general-server", "--shard-index", "0", "--shard-count", "1"], envOverrides);
@@ -339,6 +338,23 @@ for (const [caller, envOverrides] of [["Release", { GITHUB_WORKFLOW: "Release" }
});
}
// Release verification selects its dedicated lane explicitly. Do not infer it
// from the caller name: previews and future workflow callers need the same cover.
for (const caller of ["Release", "Cloud readiness", "another caller"]) {
test(`release server, chat, and native lanes cover every server suite once under ${caller}`, () => {
const env = { GITHUB_WORKFLOW: caller };
const full = dryRunJson(["--mode", "general", "--group", "general-server", "--shard-index", "0", "--shard-count", "1"], env);
const files = Array.from({ length: 10 }, (_, index) => dryRunJson([
"--mode", "general", "--group", "general-server-without-chat-or-native-runner",
"--shard-index", String(index), "--shard-count", "10",
], env)).flatMap((shard) => shard.selectedGeneralServerSuites);
const native = dryRunJson(["--mode", "general", "--group", "general-server-native-runner"], env);
const combined = [...files, chatSuitePath, ...native.selectedGeneralServerSuites];
assert.equal(new Set(combined).size, combined.length, "lanes must not overlap");
assert.deepEqual(combined.sort(), full.selectedGeneralServerSuites.sort());
});
}
test("the native-runner lane runs exactly the cargo-dependent suites", () => {
const lane = dryRunJson(["--mode", "general", "--group", "general-server-native-runner"]);
assert.deepEqual(lane.selectedGeneralServerSuites, [
+24 -20
View File
@@ -76,6 +76,7 @@ const generalModeName = "general";
const allModeName = "all";
const generalServerGroupName = "general-server";
const generalServerWithoutChatGroupName = "general-server-without-chat";
const generalServerWithoutChatOrNativeRunnerGroupName = "general-server-without-chat-or-native-runner";
const generalChatGroupName = "general-chat";
const generalServerNativeRunnerGroupName = "general-server-native-runner";
const chatSuite = "server/src/__tests__/chat-channels.integration.test.ts";
@@ -92,10 +93,9 @@ const nativeRunnerSuites = [
// In the PR workflow (pr.yml, the caller of pr-trusted.yml — reusable
// workflows inherit the caller's GITHUB_WORKFLOW), the last Verify Paperclip
// Runner vitest shard runs the native-runner group instead, because those
// lanes restore the shared release-runner-v1 Rust cache (see
// lanes restore the shared release-runner-v2 Rust cache (see
// packages/paperclip-runner/scripts/run-pr-vitest-lane.mjs). Every other
// caller — local runs, release-verify.yml under the Release and Cloud
// readiness workflows — keeps the suite in the server shards, so a renamed or
// caller of the same group keeps the suite in the server shards, so a renamed or
// unknown workflow degrades to today's slower-but-covered behavior rather
// than dropping the suite.
const prWorkflowName = "PR";
@@ -103,6 +103,18 @@ const nativeRunnerSuiteRunsInRustCachedLane = process.env.GITHUB_WORKFLOW === pr
const withoutChatExcludedSuites = nativeRunnerSuiteRunsInRustCachedLane
? [chatSuite, ...nativeRunnerSuites]
: [chatSuite];
// Release verification selects this explicit group and runs the omitted suites
// in its cached Runner job. Local callers keep the complete default group.
const generalServerGroups = [
generalServerGroupName,
generalServerWithoutChatGroupName,
generalServerWithoutChatOrNativeRunnerGroupName,
];
function excludedServerSuites(groupName) {
if (groupName === generalServerWithoutChatOrNativeRunnerGroupName) return [chatSuite, ...nativeRunnerSuites];
if (groupName === generalServerWithoutChatGroupName) return withoutChatExcludedSuites;
return [];
}
const generalWorkspacesAGroupName = "general-workspaces-a";
const generalWorkspacesBGroupName = "general-workspaces-b";
const generalWorkspacesAProjects = ["@paperclipai/ui", "paperclipai"];
@@ -111,6 +123,7 @@ const generalGroupNames = [generalServerGroupName, generalWorkspacesAGroupName,
const allowedGeneralGroupNames = [
...generalGroupNames,
generalServerWithoutChatGroupName,
generalServerWithoutChatOrNativeRunnerGroupName,
generalChatGroupName,
generalServerNativeRunnerGroupName,
];
@@ -290,7 +303,7 @@ function parseCliOptions(argv) {
const shardAllowed =
mode === serializedModeName ||
(mode === generalModeName &&
([generalServerGroupName, generalServerWithoutChatGroupName, generalChatGroupName, generalWorkspacesAGroupName].includes(group)));
([...generalServerGroups, generalChatGroupName, generalWorkspacesAGroupName].includes(group)));
if (!shardAllowed && shardIndex !== null) {
fail(
"--shard-index/--shard-count are only valid with serialized mode or a shardable general server/chat/workspaces-a group.",
@@ -448,14 +461,9 @@ function runGeneralGroup(routeTests, groupName, shardIndex = null, shardCount =
);
return;
}
if (groupName === generalServerGroupName || groupName === generalServerWithoutChatGroupName) {
// In the PR workflow the without-chat group also leaves the native-runner
// suite to the Rust-cached vitest lane; the full general-server group
// (local runs) keeps both.
const withoutChat = groupName === generalServerWithoutChatGroupName;
const files = withoutChat
? generalServerTestFiles.filter((file) => !withoutChatExcludedSuites.includes(file))
: generalServerTestFiles;
if (generalServerGroups.includes(groupName)) {
const excludedSuites = excludedServerSuites(groupName);
const files = generalServerTestFiles.filter((file) => !excludedSuites.includes(file));
if (shardCount !== null && shardCount > 1) {
const shardFiles = selectGeneralServerShard(
files,
@@ -483,10 +491,8 @@ function runGeneralGroup(routeTests, groupName, shardIndex = null, shardCount =
}
const excludeRouteArgs = routeTests.flatMap((file) => ["--exclude", file.serverPath]);
if (withoutChat) {
for (const suite of withoutChatExcludedSuites) {
excludeRouteArgs.push("--exclude", suite.replace(/^server\//, ""));
}
for (const suite of excludedSuites) {
excludeRouteArgs.push("--exclude", suite.replace(/^server\//, ""));
}
runVitest(
[
@@ -584,12 +590,10 @@ if (options.dryRun) {
options.mode === generalModeName && options.group === generalServerNativeRunnerGroupName
? nativeRunnerSuites
: options.mode === generalModeName &&
[generalServerGroupName, generalServerWithoutChatGroupName].includes(options.group) &&
generalServerGroups.includes(options.group) &&
options.shardCount !== null
? selectGeneralServerShard(
options.group === generalServerWithoutChatGroupName
? generalServerTestFiles.filter((file) => !withoutChatExcludedSuites.includes(file))
: generalServerTestFiles,
generalServerTestFiles.filter((file) => !excludedServerSuites(options.group).includes(file)),
options.shardIndex,
options.shardCount,
generalServerShardDurations,