Public source validation / validate (push) Failing after 3m8s
42 lines
1.7 KiB
JavaScript
42 lines
1.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
|
|
const root = process.cwd();
|
|
const required = ["README.md", "SECURITY.md", "CONTRIBUTING.md", "LICENSE", "go.mod", "package.json", "deploy/compose.yaml", ".gitea/workflows/public-validation.yml", "PUBLIC_SOURCE_EXPORT.md", "PUBLIC_SOURCE_MANIFEST.json"];
|
|
const missing = required.filter((entry) => !fs.existsSync(path.join(root, entry)));
|
|
if (missing.length) {
|
|
console.error(`Missing public source files: ${missing.join(", ")}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
for (const privatePath of [".agents", ".codex", "artifacts", "design", "planning", "prompts"]) {
|
|
if (fs.existsSync(path.join(root, privatePath))) {
|
|
console.error(`Private-only path present in public export: ${privatePath}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
const manifest = JSON.parse(fs.readFileSync(path.join(root, "PUBLIC_SOURCE_MANIFEST.json"), "utf8"));
|
|
if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
|
|
console.error("PUBLIC_SOURCE_MANIFEST.json contains no files.");
|
|
process.exit(1);
|
|
}
|
|
for (const entry of manifest.files) {
|
|
const target = path.join(root, ...entry.path.split("/"));
|
|
if (!fs.existsSync(target)) {
|
|
console.error(`Manifest file is missing: ${entry.path}`);
|
|
process.exit(1);
|
|
}
|
|
const bytes = fs.readFileSync(target);
|
|
const digest = crypto.createHash("sha256").update(bytes).digest("hex");
|
|
if (digest !== entry.sha256 || bytes.length !== entry.bytes) {
|
|
console.error(`Manifest mismatch: ${entry.path}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
console.log(`Public source structure and manifest passed (${manifest.files.length} allowlisted files).`);
|