Some checks are pending
Actionlint / actionlint (push) Waiting to run
Skills Registry CI / pr-policy (push) Waiting to run
Skills Registry CI / source-validation (push) Blocked by required conditions
Skills Registry CI / artifact-preview (push) Blocked by required conditions
Skills Registry CI / main-validation-and-sync (push) Waiting to run
CodeQL / Analyze (go) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (c-cpp) (push) Waiting to run
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Deploy Web App to GitHub Pages / build (push) Waiting to run
Deploy Web App to GitHub Pages / deploy (push) Blocked by required conditions
Force GitHub Pages workflows onto Node 24 while the pages actions still emit Node 20 deprecation warnings. Relax the workflow guard test so it validates fetch-depth on checkout without pinning a specific checkout major version.
285 lines
9.7 KiB
JavaScript
285 lines
9.7 KiB
JavaScript
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const repoRoot = path.resolve(__dirname, "..", "..", "..");
|
|
|
|
function readText(relativePath) {
|
|
return fs.readFileSync(path.join(repoRoot, relativePath), "utf8");
|
|
}
|
|
|
|
const packageJson = JSON.parse(readText("package.json"));
|
|
const generatedFiles = JSON.parse(readText("tools/config/generated-files.json"));
|
|
const ciWorkflow = readText(".github/workflows/ci.yml");
|
|
const publishWorkflow = readText(".github/workflows/publish-npm.yml");
|
|
const releaseWorkflowScript = readText("tools/scripts/release_workflow.js");
|
|
const hygieneWorkflowPath = path.join(repoRoot, ".github", "workflows", "repo-hygiene.yml");
|
|
|
|
assert.ok(
|
|
packageJson.scripts["sync:release-state"],
|
|
"package.json should expose a deterministic release-state sync command",
|
|
);
|
|
assert.ok(
|
|
packageJson.scripts["check:warning-budget"],
|
|
"package.json should expose a warning-budget guardrail command",
|
|
);
|
|
assert.ok(
|
|
packageJson.scripts["check:readme-credits"],
|
|
"package.json should expose a README credit validation command",
|
|
);
|
|
assert.ok(
|
|
packageJson.scripts["merge:batch"],
|
|
"package.json should expose a maintainer merge-batch command",
|
|
);
|
|
assert.ok(
|
|
packageJson.scripts["audit:maintainer"],
|
|
"package.json should expose a maintainer audit command",
|
|
);
|
|
assert.ok(
|
|
packageJson.scripts["sync:web-assets"],
|
|
"package.json should expose a web-asset sync command for tracked web artifacts",
|
|
);
|
|
assert.match(
|
|
packageJson.scripts["sync:release-state"],
|
|
/sync:web-assets/,
|
|
"sync:release-state should refresh tracked web assets before auditing release drift",
|
|
);
|
|
assert.match(
|
|
packageJson.scripts["sync:release-state"],
|
|
/check:warning-budget/,
|
|
"sync:release-state should enforce the frozen validation warning budget",
|
|
);
|
|
assert.match(
|
|
packageJson.scripts["sync:repo-state"],
|
|
/sync:web-assets/,
|
|
"sync:repo-state should refresh tracked web assets before maintainer audits",
|
|
);
|
|
assert.match(
|
|
packageJson.scripts["sync:repo-state"],
|
|
/check:warning-budget/,
|
|
"sync:repo-state should enforce the frozen validation warning budget",
|
|
);
|
|
assert.strictEqual(
|
|
packageJson.scripts["app:install"],
|
|
"cd apps/web-app && npm ci",
|
|
"app:install should use npm ci for deterministic web-app installs",
|
|
);
|
|
|
|
for (const filePath of [
|
|
"apps/web-app/public/sitemap.xml",
|
|
"apps/web-app/public/skills.json.backup",
|
|
"data/plugin-compatibility.json",
|
|
".agents/plugins/",
|
|
".claude-plugin/plugin.json",
|
|
".claude-plugin/marketplace.json",
|
|
"plugins/",
|
|
]) {
|
|
assert.ok(
|
|
generatedFiles.derivedFiles.includes(filePath),
|
|
`generated-files derivedFiles should include ${filePath}`,
|
|
);
|
|
}
|
|
|
|
const webAppGitignore = readText("apps/web-app/.gitignore");
|
|
assert.match(
|
|
webAppGitignore,
|
|
/^coverage$/m,
|
|
"web-app coverage output should be ignored so maintainer sync jobs stay clean",
|
|
);
|
|
|
|
for (const filePath of [
|
|
"README.md",
|
|
"package.json",
|
|
"docs/users/getting-started.md",
|
|
"docs/users/bundles.md",
|
|
"docs/users/claude-code-skills.md",
|
|
"docs/users/gemini-cli-skills.md",
|
|
"docs/users/usage.md",
|
|
"docs/users/visual-guide.md",
|
|
"docs/users/kiro-integration.md",
|
|
"docs/maintainers/repo-growth-seo.md",
|
|
"docs/maintainers/skills-update-guide.md",
|
|
"docs/integrations/jetski-cortex.md",
|
|
"docs/integrations/jetski-gemini-loader/README.md",
|
|
]) {
|
|
assert.ok(
|
|
generatedFiles.mixedFiles.includes(filePath),
|
|
`generated-files mixedFiles should include ${filePath}`,
|
|
);
|
|
}
|
|
|
|
assert.match(
|
|
ciWorkflow,
|
|
/- name: Run repo-state sync[\s\S]*?run: npm run sync:repo-state/,
|
|
"main CI should use the unified repo-state sync command",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/GH_TOKEN: \$\{\{ github\.token \}\}/,
|
|
"main CI should provide GH_TOKEN for contributor synchronization",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/main-validation-and-sync:[\s\S]*?concurrency:[\s\S]*?group: canonical-main-sync[\s\S]*?cancel-in-progress: false/,
|
|
"main validation should serialize canonical sync writers",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/pip install -r tools\/requirements\.txt/g,
|
|
"CI workflows should install Python dependencies from tools/requirements.txt",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/- name: Audit npm dependencies[\s\S]*?run: npm audit --audit-level=high/,
|
|
"CI should run npm audit at high severity",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/source-validation:[\s\S]*?- uses: actions\/checkout@v\d+[\s\S]*?with:[\s\S]*?fetch-depth: 0/,
|
|
"source-validation should use an unshallowed checkout so base-branch diffs have a merge base",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/source-validation:[\s\S]*?- name: Fetch base branch[\s\S]*?run: git fetch origin "\$\{\{ github\.base_ref \}\}"/,
|
|
"source-validation should fetch the PR base branch before changed-skill README credit checks",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/- name: Verify README source credits for changed skills[\s\S]*?run: npm run check:readme-credits -- --base "origin\/\$\{\{ github\.base_ref \}\}" --head HEAD/,
|
|
"PR CI should verify README source credits for changed skills",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/source-validation:[\s\S]*?- name: Fetch base branch[\s\S]*?- name: Install npm dependencies[\s\S]*?- name: Verify README source credits for changed skills/,
|
|
"source-validation should fetch the base branch before running the changed-skill README credit check",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/main-validation-and-sync:[\s\S]*?- name: Audit npm dependencies[\s\S]*?run: npm audit --audit-level=high/,
|
|
"main validation should enforce npm audit before syncing canonical state",
|
|
);
|
|
assert.doesNotMatch(
|
|
ciWorkflow,
|
|
/main-validation-and-sync:[\s\S]*?continue-on-error: true/,
|
|
"main validation should not treat high-severity npm audit findings as non-blocking",
|
|
);
|
|
assert.doesNotMatch(
|
|
ciWorkflow,
|
|
/^ - name: Generate index$/m,
|
|
"main CI should not keep the old standalone Generate index step",
|
|
);
|
|
assert.doesNotMatch(
|
|
ciWorkflow,
|
|
/^ - name: Update README$/m,
|
|
"main CI should not keep the old standalone Update README step",
|
|
);
|
|
assert.doesNotMatch(
|
|
ciWorkflow,
|
|
/^ - name: Build catalog$/m,
|
|
"main CI should not keep the old standalone Build catalog step",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/git commit -m "chore: sync repo state \[ci skip\]"/,
|
|
"main CI should keep bot-generated canonical sync commits out of the normal CI loop",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/git ls-files --others --exclude-standard/,
|
|
"main CI should fail if canonical sync leaves unmanaged untracked drift",
|
|
);
|
|
assert.match(
|
|
ciWorkflow,
|
|
/git diff --name-only/,
|
|
"main CI should fail if canonical sync leaves unmanaged tracked drift",
|
|
);
|
|
|
|
assert.ok(fs.existsSync(hygieneWorkflowPath), "repo hygiene workflow should exist");
|
|
|
|
const hygieneWorkflow = readText(".github/workflows/repo-hygiene.yml");
|
|
assert.match(hygieneWorkflow, /^on:\n workflow_dispatch:\n schedule:/m, "repo hygiene workflow should support schedule and manual runs");
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/concurrency:\n\s+group: canonical-main-sync\n\s+cancel-in-progress: false/,
|
|
"repo hygiene workflow should serialize canonical sync writers with main CI",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/GH_TOKEN: \$\{\{ github\.token \}\}/,
|
|
"repo hygiene workflow should provide GH_TOKEN for gh-based contributor sync",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/pip install -r tools\/requirements\.txt/,
|
|
"repo hygiene workflow should install Python dependencies from tools/requirements.txt",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/run: npm audit --audit-level=high/,
|
|
"repo hygiene workflow should block on high-severity npm audit findings before syncing",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/run: npm run sync:repo-state/,
|
|
"repo hygiene workflow should run the unified repo-state sync command",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/generated_files\.js --include-mixed/,
|
|
"repo hygiene workflow should resolve and stage the mixed generated files contract",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/git commit -m "chore: scheduled repo hygiene sync \[ci skip\]"/,
|
|
"repo hygiene workflow should keep bot-generated sync commits out of the normal CI loop",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/git ls-files --others --exclude-standard/,
|
|
"repo hygiene workflow should fail if canonical sync leaves unmanaged untracked drift",
|
|
);
|
|
assert.match(
|
|
hygieneWorkflow,
|
|
/git diff --name-only/,
|
|
"repo hygiene workflow should fail if canonical sync leaves unmanaged tracked drift",
|
|
);
|
|
|
|
assert.match(publishWorkflow, /run: npm ci/, "npm publish workflow should install dependencies");
|
|
assert.match(
|
|
publishWorkflow,
|
|
/pip install -r tools\/requirements\.txt/,
|
|
"npm publish workflow should install Python dependencies from tools/requirements.txt",
|
|
);
|
|
assert.match(
|
|
publishWorkflow,
|
|
/run: npm audit --audit-level=high/,
|
|
"npm publish workflow should block on high-severity npm audit findings",
|
|
);
|
|
assert.match(
|
|
publishWorkflow,
|
|
/run: npm run app:install/,
|
|
"npm publish workflow should install web-app dependencies before building",
|
|
);
|
|
assert.match(
|
|
publishWorkflow,
|
|
/run: npm run sync:release-state/,
|
|
"npm publish workflow should verify canonical release artifacts",
|
|
);
|
|
assert.match(
|
|
publishWorkflow,
|
|
/run: git diff --exit-code/,
|
|
"npm publish workflow should fail if canonical sync would leave release drift",
|
|
);
|
|
assert.match(publishWorkflow, /run: npm run test/, "npm publish workflow should run tests before publish");
|
|
assert.match(publishWorkflow, /run: npm run app:build/, "npm publish workflow should build the app before publish");
|
|
assert.match(
|
|
releaseWorkflowScript,
|
|
/runCommand\("npm", \["run", "app:install"\], projectRoot\);[\s\S]*runCommand\("npm", \["run", "app:build"\], projectRoot\);/,
|
|
"release workflow should install web-app dependencies before building the app",
|
|
);
|
|
assert.match(
|
|
publishWorkflow,
|
|
/npm pack --dry-run --json/,
|
|
"npm publish workflow should dry-run package creation before publishing",
|
|
);
|