Files
antigravity-skills-reference/tools/scripts/tests/automation_workflows.test.js
sickn33 747a4eab04 fix(release): Restore web-app install for npm publish
Install apps/web-app dependencies in the publish workflow before the\nfrontend build so CI matches the working Pages pipeline.\n\nHarden the maintainer release suite by adding the same install step\nbefore app:build, and switch the shared app:install helper to npm ci\nfor deterministic installs.\n\nDocument the follow-up patch release in the changelog so 8.7.1 can\npublish the 8.7.x line to npm after the 8.7.0 release failed before\nreaching the registry.
2026-03-23 19:13:30 +01:00

165 lines
5.4 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["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",
]) {
assert.ok(
generatedFiles.derivedFiles.includes(filePath),
`generated-files derivedFiles should include ${filePath}`,
);
}
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.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.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,
/GH_TOKEN: \$\{\{ github\.token \}\}/,
"repo hygiene workflow should provide GH_TOKEN for gh-based contributor sync",
);
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 --shell --include-mixed/,
"repo hygiene workflow should stage the mixed generated files contract",
);
assert.match(publishWorkflow, /run: npm ci/, "npm publish workflow should install dependencies");
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",
);