import fs from 'node:fs'; import path from 'node:path'; import { execFileSync } from 'node:child_process'; const ROOT = process.cwd(); const IGNORED_DIRS = new Set(['coverage', 'dist', 'node_modules']); const checks = []; function addCheck(name, run) { checks.push({ name, run }); } function listFiles(dir, predicate = () => true) { if (!fs.existsSync(dir)) { return []; } const entries = fs.readdirSync(dir, { withFileTypes: true }); return entries.flatMap((entry) => { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { if (IGNORED_DIRS.has(entry.name)) { return []; } return listFiles(fullPath, predicate); } return predicate(fullPath) ? [fullPath] : []; }); } addCheck('No CSS !important usage', () => { const cssFiles = listFiles(path.join(ROOT, 'packages'), (file) => file.endsWith('.css')); const violations = cssFiles.flatMap((file) => { const content = fs.readFileSync(file, 'utf8'); return content .split('\n') .map((line, index) => ({ file, line, lineNumber: index + 1 })) .filter(({ line }) => line.includes('!important')); }); if (violations.length === 0) { return; } const details = violations .map(({ file, lineNumber }) => `${path.relative(ROOT, file)}:${lineNumber}`) .join('\n'); throw new Error(`Avoid !important in plugin CSS:\n${details}`); }); addCheck('Committed npm lockfile exists', () => { const lockfile = path.join(ROOT, 'package-lock.json'); if (!fs.existsSync(lockfile)) { throw new Error('package-lock.json is required for reproducible dependency resolution'); } try { execFileSync('git', ['ls-files', '--error-unmatch', 'package-lock.json'], { cwd: ROOT, stdio: 'ignore', }); } catch { throw new Error('package-lock.json must be tracked by Git'); } }); addCheck('Release workflow includes artifact attestation', () => { const workflowDir = path.join(ROOT, '.github', 'workflows'); const workflowFiles = listFiles(workflowDir, (file) => /\.(ya?ml)$/.test(file)); const hasAttestation = workflowFiles.some((file) => { const content = fs.readFileSync(file, 'utf8'); return content.includes('actions/attest-build-provenance'); }); if (!hasAttestation) { throw new Error( 'release workflow should attest release assets with actions/attest-build-provenance' ); } }); const failures = []; for (const check of checks) { try { check.run(); console.log(`PASS ${check.name}`); } catch (error) { failures.push({ name: check.name, error }); console.error(`FAIL ${check.name}`); console.error(error instanceof Error ? error.message : String(error)); } } if (failures.length > 0) { process.exitCode = 1; }