Fix: the last entry in a mapping file swallowed the file's closing ta… #86
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Content Validation | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'llm-top10/**' | |
| - 'agentic-top10/**' | |
| - 'dsgai-2026/**' | |
| - 'ast-top10/**' | |
| - 'shared/**' | |
| - 'data/**' | |
| - 'CROSSREF.md' | |
| - 'README.md' | |
| - 'scripts/validate.js' | |
| - 'scripts/generate.js' | |
| - 'scripts/*.test.mjs' | |
| - 'package.json' | |
| - '.github/workflows/validate.yml' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'llm-top10/**' | |
| - 'agentic-top10/**' | |
| - 'dsgai-2026/**' | |
| - 'ast-top10/**' | |
| - 'shared/**' | |
| - 'data/**' | |
| - 'CROSSREF.md' | |
| - 'README.md' | |
| - 'scripts/validate.js' | |
| - 'scripts/generate.js' | |
| - 'scripts/*.test.mjs' | |
| - 'package.json' | |
| - '.github/workflows/validate.yml' | |
| # Both jobs only read the tree. Without this they inherit the repository | |
| # default, which is write. | |
| permissions: | |
| contents: read | |
| jobs: | |
| validate: | |
| name: Structural validation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Use Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '20' | |
| - name: Run content validator | |
| run: node scripts/validate.js | |
| - name: Validate JSON schema | |
| run: | | |
| node -e " | |
| const fs = require('fs'); | |
| const schema = JSON.parse(fs.readFileSync('data/schema.json', 'utf8')); | |
| console.log('schema.json is valid JSON'); | |
| console.log('Title:', schema.title); | |
| console.log('Required fields:', schema.required.join(', ')); | |
| " | |
| mapping-counts: | |
| name: Count consistency | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Use Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '20' | |
| # Replaces a single hand-maintained badge grep. Every headline number is | |
| # now derived from data/ by scripts/stats.js and rendered into README | |
| # marker regions, so this checks all of them at once: a stale count, a | |
| # hand-edited badge, or a data change that was not re-rendered all fail. | |
| - name: Check generated counts are current | |
| run: npm run stats:check | |
| # stats:check compares regenerated output against what is committed; | |
| # git must agree that nothing moved. | |
| - name: Assert no uncommitted drift | |
| run: git diff --exit-code -- README.md data/stats.json | |
| generator: | |
| name: Generator reproducibility | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Use Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '20' | |
| # generate.js sat broken on main for several commits: a migration script | |
| # was run more than once and left three `const AST_IDS` declarations, so | |
| # the file threw a SyntaxError on load. Nothing noticed, because no job | |
| # ran it. This one does. | |
| - name: Run the generator | |
| run: node scripts/generate.js | |
| # And its output must match what is committed, so a hand-edit to a | |
| # generated file, or a source change that was never regenerated, fails | |
| # here rather than shipping. | |
| # Every generated artefact is listed, and the generator is timestamp-free | |
| # by design (T-ENG03) — a run-date in any header would fail this on day two. | |
| - name: Assert generated output is current | |
| run: >- | |
| git diff --exit-code -- | |
| data/entries data/backlinks.json | |
| docs/data.js docs/backlinks.js docs/frameworks-registry.js docs/incidents.js | |
| unit-tests: | |
| name: Unit tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| persist-credentials: false | |
| - name: Use Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '20' | |
| cache: npm | |
| # ajv is the only runtime dependency the suite needs, and it is a | |
| # devDependency. --ignore-scripts because nothing here needs a postinstall. | |
| - name: Install dependencies | |
| run: npm ci --ignore-scripts | |
| # Covers stats.js, generate.js, the three report CLIs, the framework | |
| # ingest path, and schema validation of the OSCAL and STIX exports. | |
| - name: Run the test suite | |
| run: npm run test:scripts | |
| # The suite re-runs the generator to prove it is deterministic. If that | |
| # left anything behind, the tree must still be clean. | |
| - name: Assert the tests left no changes behind | |
| run: git diff --exit-code |