* ci: split fast and deep static checks Fast PRs run typecheck, lint, and format before provider admission. Knip, duplication, architecture guards, and Python stay on the full tier. Shared-boundary fallbacks keep the Linux x64 baseline, and Turbo jobs export remote-cache credentials when they are configured. Co-authored-by: morluto <morluto@users.noreply.github.com> * ci: keep pull requests from writing the remote cache Trusted default-branch runs still receive TURBO_TOKEN. Pull requests get an empty token and remote read-only mode. Knip saves a per-commit cache key so the next trusted full run can refresh the restored snapshot. Co-authored-by: morluto <morluto@users.noreply.github.com> * ci: forward the release cache token and upload deep static reports Release qualification now passes TURBO_TOKEN into the called workflow. Labeled pull requests still do not. The deep static job records its task context and uploads duplication reports after a failed gate. Co-authored-by: morluto <morluto@users.noreply.github.com> * style: format the turbo cache policy test Co-authored-by: morluto <morluto@users.noreply.github.com> * ci: keep fast checks exclusive and trusted cache writes explicit Declare the static artifact name and context script so typecheck matches the implementations. Lock check:ci:fast around dist, and publish the remote cache only for release qualification or default-branch push, schedule, and dispatch. Co-authored-by: morluto <morluto@users.noreply.github.com> * ci: record static task graphs without nesting the artifacts lock Keep check:ci:fast locked, and point graph recording at the unlocked check:ci:fast:tasks script so check:pr and check:test can record hashes while they already hold that lock. Co-authored-by: morluto <morluto@users.noreply.github.com> * ci: keep unauthenticated Turbo runs on the local cache Open pull requests do not receive TURBO_TOKEN, so a remote read mode cannot authenticate. Those runs now use the local cache. Trusted runs still publish. Co-authored-by: morluto <morluto@users.noreply.github.com> * test(ida): treat unchanged invalid requests as nonretryable Main already stopped marking invalid_request retryable. The pull request merge runs that projector, while the IDA lookup tests still expected retryable true. Match the merged behavior. Co-authored-by: morluto <morluto@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com>
66 lines
2.4 KiB
JavaScript
66 lines
2.4 KiB
JavaScript
import { CI_FLAGS } from "./scopes.mjs";
|
|
import { recordQualification } from "./qualification.mjs";
|
|
|
|
const jobs = JSON.parse(process.env.CI_JOBS);
|
|
const outputs = jobs?.changes?.outputs;
|
|
if (!["fast", "full", "reused"].includes(outputs?.tier))
|
|
throw new Error(
|
|
"CI classification requires a valid tier: fast, full, or reused",
|
|
);
|
|
const invalidFlags = CI_FLAGS.filter(
|
|
(flag) => outputs[flag] !== "true" && outputs[flag] !== "false",
|
|
);
|
|
if (invalidFlags.length)
|
|
throw new Error(
|
|
`CI classification requires explicit true/false scope outputs: ${invalidFlags.join(", ")}`,
|
|
);
|
|
const selectedScopes = CI_FLAGS.filter((flag) => outputs[flag] === "true");
|
|
const reused = outputs.tier === "reused";
|
|
if (
|
|
reused &&
|
|
(process.env.GITHUB_EVENT_NAME !== "schedule" ||
|
|
!/^[1-9]\d*$/.test(outputs.qualification_run_id ?? "") ||
|
|
!Number.isSafeInteger(Number(outputs.qualification_run_id)) ||
|
|
selectedScopes.length !== 0)
|
|
)
|
|
throw new Error(
|
|
"Reused qualification requires a scheduled admission receipt and no selected lanes",
|
|
);
|
|
if (outputs.tier === "full" && selectedScopes.length !== CI_FLAGS.length)
|
|
throw new Error("Full qualification requires every canonical CI scope");
|
|
const required = reused ? ["changes"] : ["changes", "static", "test"];
|
|
if (outputs.tier === "full") required.push("static-deep");
|
|
const lanes = {
|
|
code: [
|
|
"build",
|
|
"test-shard",
|
|
...(outputs.tier === "fast" ? ["test-source"] : []),
|
|
],
|
|
reverse_tools: ["reverse-tools-quality"],
|
|
runtime: ["windows-native-build", "package-e2e"],
|
|
package: ["windows-curated"],
|
|
sqlite: ["sqlite-runtime"],
|
|
apple: ["apple-artifacts"],
|
|
fixtures: ["conformance-fixtures"],
|
|
readiness: ["reconstruction-readiness"],
|
|
docs: ["docs"],
|
|
workflows: ["static"],
|
|
};
|
|
for (const scope of selectedScopes) required.push(...(lanes[scope] ?? [scope]));
|
|
const failed = [...new Set(required)].filter(
|
|
(name) => jobs[name]?.result !== "success",
|
|
);
|
|
for (const [name, job] of Object.entries(jobs)) {
|
|
if (["failure", "cancelled"].includes(job.result) && !failed.includes(name))
|
|
failed.push(name);
|
|
}
|
|
if (failed.length)
|
|
throw new Error(`CI lanes did not pass: ${failed.join(", ")}`);
|
|
console.log("Every selected CI lane passed");
|
|
if (reused)
|
|
console.log(
|
|
`Qualification reused from run ${outputs.qualification_run_id}; no fresh provider observation`,
|
|
);
|
|
if (outputs.tier === "full" && process.env.CI_QUALIFICATION_DIRECTORY)
|
|
recordQualification(process.env.CI_QUALIFICATION_DIRECTORY);
|