Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions bin/utils/validate-publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const { execSync, execFileSync } = require('child_process');
const PROJECT_ROOT = path.join(__dirname, '..', '..');
const MIN_FILE_COUNT = 50;
const PRO_PATH_PATTERN = /^pro(?:\/|$)/;
const REQUIRED_PUBLIC_FILES = [
'.aiox-core/quality/metrics-collector.js',
'.aiox-core/quality/seed-metrics.js',
'.aiox-core/quality/schemas/quality-metrics.schema.json',
];
const DEFAULT_PACK_TIMEOUT_MS = 300000;
const parsedPackTimeoutMs = Number.parseInt(
process.env.AIOX_VALIDATE_PUBLISH_PACK_TIMEOUT_MS || '',
Expand Down Expand Up @@ -105,6 +110,22 @@ try {
} else {
console.log('PASS: Public package excludes pro/ content');
}

const missingRequiredFiles = REQUIRED_PUBLIC_FILES.filter(
(filePath) => !packedFiles.includes(filePath),
);
if (missingRequiredFiles.length > 0) {
console.error(
`FAIL: Public package is missing ${missingRequiredFiles.length} required runtime file(s).`,
);
console.error(' Metrics CLI commands require these files at boot.');
for (const filePath of missingRequiredFiles) {
console.error(` - ${filePath}`);
}
passed = false;
} else {
console.log('PASS: Public package includes metrics runtime files');
}
} catch (err) {
console.error(`FAIL: npm pack --dry-run failed: ${err.message}`);
passed = false;
Expand Down
8 changes: 8 additions & 0 deletions tests/cli/validate-publish.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ describe('Publish Safety Gate (Story INS-4.10 / PRO-13.5)', () => {
expect(scriptSource).toContain('Public package excludes pro/ content');
});

test('script requires metrics runtime files in npm pack output', () => {
expect(scriptSource).toContain('REQUIRED_PUBLIC_FILES');
expect(scriptSource).toContain('.aiox-core/quality/metrics-collector.js');
expect(scriptSource).toContain('.aiox-core/quality/seed-metrics.js');
expect(scriptSource).toContain('Public package includes metrics runtime files');
});

test('legacy npm notice parser strips size prefixes before path checks', () => {
expect(scriptSource).toContain('npm notice\\s+[\\d.]+[kMG]?B?\\s+(.+)');
});
Expand Down Expand Up @@ -116,6 +123,7 @@ describe('Publish Safety Gate (Story INS-4.10 / PRO-13.5)', () => {
});
expect(result).toContain('PUBLISH SAFETY GATE: PASS');
expect(result).toContain('PASS: Public package excludes pro/ content');
expect(result).toContain('PASS: Public package includes metrics runtime files');
});

test('script produces human-readable output with pass/fail indicators', () => {
Expand Down