📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -3,7 +3,9 @@ const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const {
|
||||
classifyChangeRecords,
|
||||
classifyChangedFiles,
|
||||
classifyPathPolicy,
|
||||
extractChangelogSection,
|
||||
getDirectDerivedChanges,
|
||||
hasIssueLink,
|
||||
@@ -11,6 +13,39 @@ const {
|
||||
requiresReferencesValidation,
|
||||
} = require("../../lib/workflow-contract");
|
||||
|
||||
const ZERO_OID = "0".repeat(40);
|
||||
const OLD_OID = "1".repeat(40);
|
||||
const NEW_OID = "2".repeat(40);
|
||||
|
||||
function addedRecord(filePath, overrides = {}) {
|
||||
return {
|
||||
status: "A",
|
||||
old_path: null,
|
||||
new_path: filePath,
|
||||
old_mode: "000000",
|
||||
new_mode: "100644",
|
||||
old_oid: ZERO_OID,
|
||||
new_oid: NEW_OID,
|
||||
new_size: 128,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function modifiedRecord(filePath, overrides = {}) {
|
||||
return {
|
||||
status: "M",
|
||||
old_path: filePath,
|
||||
new_path: filePath,
|
||||
old_mode: "100644",
|
||||
new_mode: "100644",
|
||||
old_oid: OLD_OID,
|
||||
new_oid: NEW_OID,
|
||||
old_size: 128,
|
||||
new_size: 256,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const contract = {
|
||||
derivedFiles: [
|
||||
"CATALOG.md",
|
||||
@@ -41,6 +76,8 @@ const pagesWorkflow = fs.readFileSync(
|
||||
path.resolve(__dirname, "..", "..", "..", ".github", "workflows", "pages.yml"),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(pagesWorkflow, /^on:\s*\n\s+workflow_dispatch:/m);
|
||||
assert.doesNotMatch(pagesWorkflow, /^\s+push:/m);
|
||||
for (const command of [
|
||||
"npm run validate:strict",
|
||||
"npm run validate:glossary",
|
||||
@@ -65,6 +102,62 @@ assert.doesNotMatch(
|
||||
/ENABLE_NETWORK_TESTS:\s*["']1["']/,
|
||||
"PR and push CI must not depend on mutable upstream network clones",
|
||||
);
|
||||
assert.match(ciWorkflow, /^permissions:\n contents: read$/m);
|
||||
assert.match(
|
||||
ciWorkflow,
|
||||
/source-validation:[\s\S]*?- name: Refresh ephemeral derived sources for tests\n\s+run: npm run plugin-compat:sync && npm run index && npm run bundles:sync\n[\s\S]*?- name: Run tests\n\s+run: npm run test/,
|
||||
"source-only skill PRs must refresh uncommitted mirrors and indexes before tests read them",
|
||||
);
|
||||
assert.match(ciWorkflow, /name: pr-evidence-/);
|
||||
assert.doesNotMatch(ciWorkflow, /pull_request_target:/);
|
||||
assert.doesNotMatch(ciWorkflow, /actions\/download-artifact/);
|
||||
const prEvidenceJob = ciWorkflow.match(/^ pr-evidence:\n([\s\S]*?)(?=^ artifact-preview:)/m)?.[0] || "";
|
||||
assert.ok(prEvidenceJob, "pr-evidence job must exist");
|
||||
assert.doesNotMatch(prEvidenceJob, /(?:contents|pull-requests|actions): write/);
|
||||
assert.doesNotMatch(prEvidenceJob, /secrets\./);
|
||||
|
||||
const decisionModule = fs.readFileSync(
|
||||
path.resolve(__dirname, "..", "..", "lib", "pr-decision.js"),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(decisionModule, /untrusted_advisory: true/);
|
||||
|
||||
const skillReviewWorkflow = fs.readFileSync(
|
||||
path.resolve(__dirname, "..", "..", "..", ".github", "workflows", "skill-review.yml"),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(skillReviewWorkflow, /^permissions:\n contents: read$/m);
|
||||
assert.match(skillReviewWorkflow, /^ review-attempt:$/m);
|
||||
assert.match(skillReviewWorkflow, /^ review:$/m);
|
||||
assert.match(skillReviewWorkflow, /^ manual-review-required:$/m);
|
||||
assert.match(skillReviewWorkflow, /^ missing-review-credentials:$/m);
|
||||
assert.match(
|
||||
skillReviewWorkflow,
|
||||
/needs\.review-attempt\.outputs\.outcome == 'quota'/,
|
||||
"quota exhaustion must route to exact-head manual review",
|
||||
);
|
||||
assert.match(
|
||||
skillReviewWorkflow,
|
||||
/github\.event\.pull_request\.head\.repo\.full_name != github\.repository/,
|
||||
);
|
||||
assert.match(
|
||||
skillReviewWorkflow,
|
||||
/github\.event\.pull_request\.head\.repo\.full_name == github\.repository/,
|
||||
);
|
||||
assert.match(skillReviewWorkflow, /ref: \$\{\{ github\.event\.pull_request\.base\.sha \}\}/);
|
||||
assert.match(skillReviewWorkflow, /review_changed_skills\.cjs --plan/);
|
||||
assert.match(skillReviewWorkflow, /actions\/cache\/restore@[0-9a-f]{40}/);
|
||||
assert.match(skillReviewWorkflow, /actions\/cache\/save@[0-9a-f]{40}/);
|
||||
assert.match(skillReviewWorkflow, /tessl-review-v1-\$\{\{ steps\.plan\.outputs\.fingerprint \}\}/);
|
||||
assert.match(skillReviewWorkflow, /steps\.review-cache\.outputs\.cache-hit != 'true'/);
|
||||
assert.match(skillReviewWorkflow, /needs\.review-attempt\.outputs\.outcome == 'reviewed'/);
|
||||
assert.ok(
|
||||
skillReviewWorkflow.indexOf("- name: Checkout pull request content") <
|
||||
skillReviewWorkflow.indexOf("- name: Checkout trusted base scripts"),
|
||||
"trusted-base checkout must happen after the root checkout so it cannot be cleaned away",
|
||||
);
|
||||
assert.doesNotMatch(skillReviewWorkflow, /pull_request_target:/);
|
||||
assert.doesNotMatch(skillReviewWorkflow, /(?:contents|pull-requests|actions): write/);
|
||||
|
||||
const skillOnly = classifyChangedFiles(["skills/example/SKILL.md"], contract);
|
||||
assert.deepStrictEqual(skillOnly.categories, ["skill"]);
|
||||
@@ -124,3 +217,157 @@ assert.strictEqual(hasQualityChecklist("## Quality Bar Checklist\n- [x] Standard
|
||||
assert.strictEqual(hasQualityChecklist("No template here"), false);
|
||||
assert.strictEqual(hasIssueLink("Fixes #123"), true);
|
||||
assert.strictEqual(hasIssueLink("Related to #123"), false);
|
||||
|
||||
for (const [filePath, expectedKind] of [
|
||||
["skills/example/SKILL.md", "canonical_skill"],
|
||||
["skills/design-it/glassmorphism/SKILL.md", "canonical_skill"],
|
||||
["skills/example/references/guide.md", "skill_support"],
|
||||
["skills/design-it/glassmorphism/references/guide.md", "skill_support"],
|
||||
["skills/example/assets/screenshot.png", "skill_support"],
|
||||
["README.md", "documentation"],
|
||||
["docs/users/faq.md", "documentation"],
|
||||
]) {
|
||||
const policy = classifyPathPolicy(filePath);
|
||||
assert.strictEqual(policy.approvalSafe, true, filePath);
|
||||
assert.strictEqual(policy.kind, expectedKind, filePath);
|
||||
}
|
||||
|
||||
for (const [filePath, reason] of [
|
||||
[".github/workflows/ci.yml", "unapproved_path"],
|
||||
["tools/scripts/check.js", "unapproved_path"],
|
||||
["skills/example/references/run.py", "unknown_extension"],
|
||||
["skills/example\\references\\guide.md", "backslash_path"],
|
||||
["skills/example/references/../SKILL.md", "noncanonical_path"],
|
||||
["skills/design-it/glassmorphism/references/../../escape.md", "noncanonical_path"],
|
||||
["/skills/example/SKILL.md", "absolute_path"],
|
||||
["skills/example/references/guide\n.md", "control_character_path"],
|
||||
]) {
|
||||
const policy = classifyPathPolicy(filePath);
|
||||
assert.strictEqual(policy.approvalSafe, false, filePath);
|
||||
assert.ok(policy.reasons.includes(reason), `${filePath}: ${policy.reasons.join(",")}`);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([addedRecord("skills/example/SKILL.md")]);
|
||||
assert.strictEqual(policy.approvalSafe, true);
|
||||
assert.strictEqual(policy.requiresHumanReview, true);
|
||||
assert.deepStrictEqual(policy.canonicalSkillChanges, ["skills/example/SKILL.md"]);
|
||||
}
|
||||
|
||||
{
|
||||
const record = addedRecord("docs/users/no-size.md");
|
||||
delete record.new_size;
|
||||
assert.strictEqual(classifyChangeRecords([record]).approvalSafe, false);
|
||||
assert.strictEqual(
|
||||
classifyChangeRecords([record], { requireBlobSizes: false }).approvalSafe,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([
|
||||
modifiedRecord("skills/example/references/guide.md"),
|
||||
]);
|
||||
assert.strictEqual(policy.approvalSafe, true);
|
||||
assert.strictEqual(policy.requiresHumanReview, true);
|
||||
assert.deepStrictEqual(policy.canonicalSkillChanges, []);
|
||||
assert.deepStrictEqual(policy.skillContentChanges, ["skills/example/references/guide.md"]);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([
|
||||
{
|
||||
status: "R",
|
||||
old_path: "skills/example/references/old.md",
|
||||
new_path: "skills/example/references/new.md",
|
||||
old_mode: "100644",
|
||||
new_mode: "100644",
|
||||
old_oid: OLD_OID,
|
||||
new_oid: NEW_OID,
|
||||
old_size: 100,
|
||||
new_size: 100,
|
||||
},
|
||||
{
|
||||
status: "C",
|
||||
old_path: "docs/users/faq.md",
|
||||
new_path: "docs/users/faq-copy.md",
|
||||
old_mode: "100644",
|
||||
new_mode: "100644",
|
||||
old_oid: OLD_OID,
|
||||
new_oid: NEW_OID,
|
||||
old_size: 100,
|
||||
new_size: 100,
|
||||
},
|
||||
]);
|
||||
assert.strictEqual(policy.approvalSafe, true);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([{
|
||||
status: "R",
|
||||
old_path: "skills/design-it/old-style/SKILL.md",
|
||||
new_path: "skills/design-it/new-style/SKILL.md",
|
||||
old_mode: "100644",
|
||||
new_mode: "100644",
|
||||
old_oid: OLD_OID,
|
||||
new_oid: NEW_OID,
|
||||
old_size: 100,
|
||||
new_size: 100,
|
||||
}]);
|
||||
assert.strictEqual(policy.approvalSafe, true);
|
||||
assert.strictEqual(policy.requiresHumanReview, true);
|
||||
assert.deepStrictEqual(policy.canonicalSkillChanges, [
|
||||
"skills/design-it/new-style/SKILL.md",
|
||||
"skills/design-it/old-style/SKILL.md",
|
||||
]);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([{
|
||||
status: "D",
|
||||
old_path: "docs/users/obsolete.md",
|
||||
new_path: null,
|
||||
old_mode: "100644",
|
||||
new_mode: "000000",
|
||||
old_oid: OLD_OID,
|
||||
new_oid: ZERO_OID,
|
||||
old_size: 42,
|
||||
}]);
|
||||
assert.strictEqual(policy.approvalSafe, true);
|
||||
}
|
||||
|
||||
for (const [label, record, reason] of [
|
||||
["executable", modifiedRecord("skills/example/references/guide.md", { new_mode: "100755" }), "new_executable_mode"],
|
||||
["symlink", addedRecord("skills/example/references/link.md", { new_mode: "120000" }), "new_symlink_mode"],
|
||||
["gitlink", addedRecord("skills/example/references/vendor.md", { new_mode: "160000" }), "new_gitlink_mode"],
|
||||
["unknown mode", addedRecord("skills/example/references/guide.md", { new_mode: "100664" }), "new_unknown_mode"],
|
||||
["oversized", addedRecord("skills/example/assets/large.pdf", { new_size: 1024 * 1024 + 1 }), "new_oversized_blob"],
|
||||
["unknown extension", addedRecord("skills/example/references/run.sh"), "new_unknown_extension"],
|
||||
["sensitive path", addedRecord("tools/scripts/check.md"), "new_unapproved_path"],
|
||||
["mode only", modifiedRecord("skills/example/references/guide.md", { new_mode: "100755", new_oid: OLD_OID }), "new_executable_mode"],
|
||||
["unknown status", modifiedRecord("skills/example/SKILL.md", { status: "X" }), "unknown_status"],
|
||||
]) {
|
||||
const policy = classifyChangeRecords([record]);
|
||||
assert.strictEqual(policy.approvalSafe, false, label);
|
||||
assert.ok(policy.reasons.some((entry) => entry.includes(reason)), `${label}: ${policy.reasons.join(",")}`);
|
||||
}
|
||||
|
||||
{
|
||||
const policy = classifyChangeRecords([
|
||||
modifiedRecord("skills/example/references/guide.md"),
|
||||
addedRecord(".github/workflows/steal.yml"),
|
||||
]);
|
||||
assert.strictEqual(policy.approvalSafe, false);
|
||||
assert.strictEqual(policy.sensitive, true);
|
||||
}
|
||||
|
||||
{
|
||||
const records = [
|
||||
modifiedRecord("docs/users/one.md"),
|
||||
modifiedRecord("docs/users/two.md"),
|
||||
];
|
||||
const tooMany = classifyChangeRecords(records, { maxChangeRecords: 1 });
|
||||
assert.ok(tooMany.reasons.includes("too_many_change_records"));
|
||||
const tooLarge = classifyChangeRecords(records, { maxTotalBlobBytes: 700 });
|
||||
assert.ok(tooLarge.reasons.includes("oversized_total_diff"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user