From 667adf1c3a5ce4d2e41d741fb0502265212646a5 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Fri, 19 Dec 2025 10:40:57 -0500 Subject: [PATCH 1/3] feat(comparators): compare more generators --- .github/workflows/generate.yml | 24 +++++++++++++---- docs/comparators.md | 27 +++++++++---------- npm-shrinkwrap.json | 18 ++++++------- scripts/comparators/constants.mjs | 10 +++++++ .../web.mjs => comparators/file-size.mjs} | 6 ++--- .../object-assertion.mjs} | 6 ++--- scripts/compare-builds/utils.mjs | 4 --- src/generators/legacy-html/template.html | 13 +++------ 8 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 scripts/comparators/constants.mjs rename scripts/{compare-builds/web.mjs => comparators/file-size.mjs} (94%) rename scripts/{compare-builds/legacy-json.mjs => comparators/object-assertion.mjs} (86%) delete mode 100644 scripts/compare-builds/utils.mjs diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 2c9aae59..51874818 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -74,30 +74,42 @@ jobs: runs-on: ubuntu-latest needs: prepare strategy: + fail-fast: false matrix: include: - target: man-page input: './node/doc/api/cli.md' + - target: addon-verify input: './node/doc/api/addons.md' + - target: api-links input: './node/lib/*.js' + compare: object-assertion + - target: orama-db input: './node/doc/api/*.md' + compare: file-size + - target: json-simple input: './node/doc/api/*.md' + compare: object-assertion + - target: legacy-json input: './node/doc/api/*.md' - compare: true + compare: object-assertion + - target: legacy-html input: './node/doc/api/*.md' + compare: file-size + - target: web input: './node/doc/api/*.md' - compare: true + compare: file-size + - target: llms-txt input: './node/doc/api/*.md' - fail-fast: false - + compare: file-size steps: - name: Harden Runner uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 @@ -154,8 +166,10 @@ jobs: - name: Compare to base branch if: ${{ matrix.compare && needs.prepare.outputs.base-run }} + env: + GENERATOR: ${{ matrix.target }} run: | - node scripts/compare-builds/${{ matrix.target }}.mjs > out/comparison.txt + node scripts/comparators/${{ matrix.compare }}.mjs > out/comparison.txt - name: Upload ${{ matrix.target }} artifacts uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 diff --git a/docs/comparators.md b/docs/comparators.md index d74c4b83..c830a6b6 100644 --- a/docs/comparators.md +++ b/docs/comparators.md @@ -20,23 +20,23 @@ Comparators are scripts that: ## Comparator Structure -Comparators are standalone ESM scripts located in `scripts/compare-builds/`: +Comparators are standalone ESM scripts located in `scripts/comparators/`: ``` -scripts/compare-builds/ -├── utils.mjs # Shared utilities (BASE, HEAD paths) -├── legacy-json.mjs # Compare legacy JSON output -├── web.mjs # Compare web bundle sizes -└── your-comparator.mjs # Your new comparator +scripts/comparators/ +├── constants.mjs # Shared constants (BASE, HEAD, TITLE paths) +├── file-size.mjs # Compare file sizes between builds +├── object-assertion.mjs # Deep equality assertion for JSON objects +└── your-comparator.mjs # Your new comparator ``` ### Naming Convention -**Each comparator must have the same name as the generator it compares.** For example: +Comparators can be reused across multiple generators. You specify which comparator to use in the workflow file using the `compare` field. For example: -- `web.mjs` compares output from the `web` generator -- `legacy-json.mjs` compares output from the `legacy-json` generator -- `my-format.mjs` would compare output from a `my-format` generator +- `file-size.mjs` can compare output from `web`, `legacy-html`, or any generator +- `object-assertion.mjs` can compare JSON output from `legacy-json`, `json-simple`, etc. +- `my-comparator.mjs` would be a custom comparator for specific needs ## Creating a Comparator @@ -48,7 +48,7 @@ Create a new file in `scripts/compare-builds/` with the same name as your genera // scripts/compare-builds/my-format.mjs import { readdir, readFile } from 'node:fs/promises'; import { join } from 'node:path'; -import { BASE, HEAD } from './utils.mjs'; +import { BASE, HEAD, TITLE } from './utils.mjs'; // Fetch files from both directories const [baseFiles, headFiles] = await Promise.all([BASE, HEAD].map(() => await readdir(dir))); @@ -105,7 +105,7 @@ const differences = results.filter(Boolean); // Output markdown results if (differences.length > 0) { - console.log('## `my-format` Generator'); + console.log(TITLE); console.log(''); console.log(`Found ${differences.length} difference(s):`); console.log(''); @@ -161,5 +161,4 @@ node scripts/compare-builds/my-format.mjs The comparator will automatically run in GitHub Actions when: -1. Your generator is configured with `compare: true` in the workflow -2. The comparator filename matches the generator name +1. Your generator is configured with `compare: ` in the workflow, which tells the system which comparator script to run diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index aa327fb6..415bf6dc 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1068,7 +1068,6 @@ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", - "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -1169,7 +1168,6 @@ "resolved": "https://registry.npmjs.org/@orama/cuid2/-/cuid2-2.2.3.tgz", "integrity": "sha512-Lcak3chblMejdlSHgYU2lS2cdOhDpU6vkfIJH4m+YKvqQyLqs1bB8+w6NT1MG5bO12NUK2GFc34Mn2xshMIQ1g==", "license": "MIT", - "peer": true, "dependencies": { "@noble/hashes": "^1.1.5" } @@ -1187,8 +1185,7 @@ "version": "0.0.5", "resolved": "https://registry.npmjs.org/@orama/oramacore-events-parser/-/oramacore-events-parser-0.0.5.tgz", "integrity": "sha512-yAuSwog+HQBAXgZ60TNKEwu04y81/09mpbYBCmz1RCxnr4ObNY2JnPZI7HmALbjAhLJ8t5p+wc2JHRK93ubO4w==", - "license": "AGPL-3.0", - "peer": true + "license": "AGPL-3.0" }, "node_modules/@orama/stopwords": { "version": "3.1.16", @@ -3495,6 +3492,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4030,8 +4028,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/debug": { "version": "4.4.3", @@ -4231,6 +4228,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -7133,6 +7131,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7182,6 +7181,7 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-11.0.0-beta.0.tgz", "integrity": "sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -7681,8 +7681,7 @@ "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/semver": { "version": "7.7.3", @@ -8271,6 +8270,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -8636,6 +8636,7 @@ "integrity": "sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==", "dev": true, "hasInstallScript": true, + "peer": true, "dependencies": { "napi-postinstall": "^0.2.4" }, @@ -9062,7 +9063,6 @@ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", "license": "ISC", - "peer": true, "peerDependencies": { "zod": "^3.24.1" } diff --git a/scripts/comparators/constants.mjs b/scripts/comparators/constants.mjs new file mode 100644 index 00000000..b593f588 --- /dev/null +++ b/scripts/comparators/constants.mjs @@ -0,0 +1,10 @@ +import { fileURLToPath } from 'node:url'; + +export const BASE = + process.env.BASE || fileURLToPath(import.meta.resolve('../../base')); + +export const HEAD = + process.env.HEAD || fileURLToPath(import.meta.resolve('../../out')); + +export const TITLE = + process.env.TITLE || `## \`${process.env.GENERATOR ?? '...'}\` Generator`; diff --git a/scripts/compare-builds/web.mjs b/scripts/comparators/file-size.mjs similarity index 94% rename from scripts/compare-builds/web.mjs rename to scripts/comparators/file-size.mjs index 9081d7b9..016de2fa 100644 --- a/scripts/compare-builds/web.mjs +++ b/scripts/comparators/file-size.mjs @@ -1,7 +1,7 @@ import { stat, readdir } from 'node:fs/promises'; import path from 'node:path'; -import { BASE, HEAD } from './utils.mjs'; +import { BASE, HEAD, TITLE } from './constants.mjs'; const UNITS = ['B', 'KB', 'MB', 'GB']; @@ -63,8 +63,8 @@ if (changed.length) { return `| \`${file}\` | ${formatBytes(base)} | ${formatBytes(head)} | ${diffFormatted} |`; }); - console.log('## Web Generator'); + console.log(TITLE); console.log('| File | Base | Head | Diff |'); console.log('|-|-|-|-|'); - console.log(rows.join('\n')); + console.log(rows.join('\n') + '\n'); } diff --git a/scripts/compare-builds/legacy-json.mjs b/scripts/comparators/object-assertion.mjs similarity index 86% rename from scripts/compare-builds/legacy-json.mjs rename to scripts/comparators/object-assertion.mjs index f221e814..b13205a2 100644 --- a/scripts/compare-builds/legacy-json.mjs +++ b/scripts/comparators/object-assertion.mjs @@ -2,7 +2,7 @@ import assert from 'node:assert'; import { readdir, readFile } from 'node:fs/promises'; import { join } from 'node:path'; -import { BASE, HEAD } from './utils.mjs'; +import { BASE, HEAD, TITLE } from './constants.mjs'; const files = await readdir(BASE); @@ -29,6 +29,6 @@ const results = await Promise.all(files.map(getFileDiff)); const filteredResults = results.filter(Boolean); if (filteredResults.length) { - console.log('## `legacy-json` generator'); - console.log(filteredResults.join('\n')); + console.log(TITLE); + console.log(filteredResults.join('\n') + '\n'); } diff --git a/scripts/compare-builds/utils.mjs b/scripts/compare-builds/utils.mjs deleted file mode 100644 index 5c1d4079..00000000 --- a/scripts/compare-builds/utils.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import { fileURLToPath } from 'node:url'; - -export const BASE = fileURLToPath(import.meta.resolve('../../base')); -export const HEAD = fileURLToPath(import.meta.resolve('../../out')); diff --git a/src/generators/legacy-html/template.html b/src/generators/legacy-html/template.html index 210506c3..0142fde1 100644 --- a/src/generators/legacy-html/template.html +++ b/src/generators/legacy-html/template.html @@ -14,17 +14,10 @@ From 0c1209505225a003acb6e6ed7241acfacc53f2c5 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Fri, 19 Dec 2025 10:52:47 -0500 Subject: [PATCH 2/3] remove comparator too large --- .github/workflows/generate.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 51874818..f0a539dc 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -93,7 +93,6 @@ jobs: - target: json-simple input: './node/doc/api/*.md' - compare: object-assertion - target: legacy-json input: './node/doc/api/*.md' From bf5279ac89f3047cea29ee60afc4b988a2948019 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Fri, 19 Dec 2025 17:52:21 -0500 Subject: [PATCH 3/3] Update object-assertion.mjs --- scripts/comparators/object-assertion.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/comparators/object-assertion.mjs b/scripts/comparators/object-assertion.mjs index b13205a2..fe9e21c1 100644 --- a/scripts/comparators/object-assertion.mjs +++ b/scripts/comparators/object-assertion.mjs @@ -17,7 +17,7 @@ const getFileDiff = async file => { const headContent = JSON.parse(await readFile(headPath, 'utf-8')); try { - assert.deepStrictEqual(baseContent, headContent); + assert.deepStrictEqual(headContent, baseContent); return null; } catch ({ message }) { return details(file, message);