From 6838cf6dbe102041dc0432422ea086376652d18b Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Mon, 10 Aug 2026 17:11:37 -0700 Subject: [PATCH] fix: bump local MCP version during releases --- .github/workflows/test.yml | 3 + .release-it.json | 3 + RELEASE.md | 17 +- package-lock.json | 424 ++++++++++++++++++++++++++++- package.json | 4 +- scripts/check-release-version.mjs | 29 ++ scripts/sync-plugin-changelogs.mjs | 17 ++ scripts/sync-release-metadata.mjs | 40 --- shared/glean/mcp/src/version.ts | 2 +- 9 files changed, 486 insertions(+), 53 deletions(-) create mode 100644 scripts/check-release-version.mjs create mode 100644 scripts/sync-plugin-changelogs.mjs delete mode 100644 scripts/sync-release-metadata.mjs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index af8e64a..04e2c73 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,9 @@ jobs: - name: Guard against shell scripts (Windows cross-platform) run: npm run check:no-shell + - name: Check release version targets + run: npm run check:release-version + - name: Typecheck server bundle run: npm run typecheck:bundle diff --git a/.release-it.json b/.release-it.json index 5082412..4cff254 100644 --- a/.release-it.json +++ b/.release-it.json @@ -14,6 +14,9 @@ "after:bump": "npm run build" }, "plugins": { + "@release-it/bumper": { + "out": "shared/glean/mcp/package.json" + }, "@release-it/conventional-changelog": { "preset": { "name": "conventionalcommits", diff --git a/RELEASE.md b/RELEASE.md index 5617ba3..eec5b71 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -20,14 +20,14 @@ release is what triggers the actual plugin distribution (below). `feat`/`fix` vs `docs` map to skill changes vs repo-only docs). Everything else (`chore:`, `refactor:`, `ci:`, `build:`, `test:`, ...) is fine to merge but is intentionally left out of `CHANGELOG.md`. -- This repo currently allows merge commits, squash merges, *and* rebase +- This repo currently allows merge commits, squash merges, _and_ rebase merges on PRs, so watch how a PR lands: - **Regular merge** — every individual commit is preserved, and conventional-changelog reads them straight from `git log`. The merge commit itself doesn't need a type prefix. - **Squash merge** — the PR collapses into one commit, using the squash commit message (GitHub defaults this to the PR title). That message is - now the *only* thing conventional-changelog sees for the whole PR, so the + now the _only_ thing conventional-changelog sees for the whole PR, so the PR title itself must be a valid Conventional Commit message. - Make sure you're releasing from an up-to-date `main` with a clean working tree and dependencies installed: @@ -57,11 +57,12 @@ release is what triggers the actual plugin distribution (below). 1. Determine the next version from commits since the last tag (`feat` → minor, `fix` → patch, a `BREAKING CHANGE` footer → major). - 2. Regenerate `CHANGELOG.md`. Its `after:bump` hook then runs `npm run - build`, which syncs that changelog into `shared/glean` and - `shared/glean-dev-docs`, then rebuilds the - generated plugin output — all of which is included in the release - commit. + 2. Bump both the root `package.json` and + `shared/glean/mcp/package.json` to the same version. Regenerate + `CHANGELOG.md`. Its `after:bump` hook then runs `npm run build`, which + syncs that changelog into `shared/glean` and `shared/glean-dev-docs`, then + rebuilds the generated plugin output — all of which is included in the + release commit. 3. Commit as `chore: release v${version}`, tag `v${version}`, and push both to `main`. 4. Create a GitHub Release from that tag. @@ -84,7 +85,7 @@ Those PRs are regenerated and force-pushed on every sync — **don't push to them by hand or hand-edit their content**. Review and merge each one in its own repo once it looks right. -If you need those PRs to pick up a fix made on `main` *without* cutting a new +If you need those PRs to pick up a fix made on `main` _without_ cutting a new release, dispatch the workflow directly instead of running `release-it` again: diff --git a/package-lock.json b/package-lock.json index 5f8763b..fb30203 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@gleanwork/pluginpack": "^0.11.0", + "@release-it/bumper": "^8.0.0", "@release-it/conventional-changelog": "^11.0.1", "@types/node": "^22.0.0", "esbuild": "^0.28.1", @@ -53,6 +54,16 @@ } } }, + "node_modules/@decimalturn/toml-patch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@decimalturn/toml-patch/-/toml-patch-2.1.0.tgz", + "integrity": "sha512-IICXlX7hcD9lGN7k+vDXcVnOfcbOEqMpeQHRnrhnmm7tZ8HluFrSgBKLNC72fQpNXynbJTC7pjtfNCaKrKlGyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", @@ -528,6 +539,13 @@ "hono": "^4" } }, + "node_modules/@iarna/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==", + "dev": true, + "license": "ISC" + }, "node_modules/@inquirer/ansi": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", @@ -1147,6 +1165,60 @@ "url": "https://github.com/phun-ky/typeof?sponsor=1" } }, + "node_modules/@release-it/bumper": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@release-it/bumper/-/bumper-8.0.0.tgz", + "integrity": "sha512-qTDTcSJzwvycZx9oMFdiiV1a7rR0Qdw0j/USSDA+ly6JyiTPSaJ+wpZ+cS8x8jTDeQuObZKf7TN9eYOxDn+JwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@decimalturn/toml-patch": "^2.1.0", + "@iarna/toml": "^3.0.0", + "cheerio": "^1.2.0", + "detect-indent": "7.0.2", + "fast-glob": "^3.3.3", + "ini": "^6.0.0", + "js-yaml": "^5.2.2", + "lodash-es": "^4.18.1", + "semver": "^7.8.5" + }, + "engines": { + "node": "^22.21.0 || >=24.0.0" + }, + "peerDependencies": { + "release-it": "^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0" + } + }, + "node_modules/@release-it/bumper/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@release-it/bumper/node_modules/js-yaml": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.3.tgz", + "integrity": "sha512-n+mUVyUX5bVv7G/G2zyIHOhdxfuU1dY2NOFzTQUWiMUbFss8b57NFlgCCaggU78wSw5KVS9cllzeLyzyR+n5nw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, "node_modules/@release-it/conventional-changelog": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-11.0.1.tgz", @@ -1885,6 +1957,13 @@ "url": "https://opencollective.com/express" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -2045,6 +2124,50 @@ "node": ">= 16" } }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/chokidar": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", @@ -2382,6 +2505,36 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/data-uri-to-buffer": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-7.0.0.tgz", @@ -2503,6 +2656,78 @@ "dev": true, "license": "MIT" }, + "node_modules/detect-indent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", + "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -2558,6 +2783,46 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3228,6 +3493,39 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -3298,6 +3596,16 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/ip-address": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", @@ -3567,6 +3875,13 @@ "node": ">=0.10.0" } }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -3891,6 +4206,19 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/nypm": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.6.tgz", @@ -4103,6 +4431,59 @@ "node": ">=14.13.0" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4655,9 +5036,9 @@ } }, "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -5548,6 +5929,43 @@ "node": "20 || >=22" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index a4fca05..9e38225 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,13 @@ "build:bundle": "node shared/glean/mcp/build.mjs", "clean": "pluginpack clean", "check:no-shell": "node scripts/check-no-shell-scripts.mjs", + "check:release-version": "node scripts/check-release-version.mjs", "prune": "pluginpack prune", "typecheck:bundle": "tsc --noEmit -p shared/glean/mcp/tsconfig.json", "test:bundle": "vitest run --root shared/glean/mcp", "validate": "pluginpack validate --target claude --dir dist/claude && pluginpack validate --target cursor --dir dist/cursor && pluginpack validate --target codex --dir dist/codex", "test": "npm run build && npm run validate", - "prebuild": "node scripts/sync-release-metadata.mjs && npm run build:bundle", + "prebuild": "node scripts/sync-plugin-changelogs.mjs && npm run build:bundle", "release": "release-it" }, "dependencies": { @@ -28,6 +29,7 @@ }, "devDependencies": { "@gleanwork/pluginpack": "^0.11.0", + "@release-it/bumper": "^8.0.0", "@release-it/conventional-changelog": "^11.0.1", "@types/node": "^22.0.0", "esbuild": "^0.28.1", diff --git a/scripts/check-release-version.mjs b/scripts/check-release-version.mjs new file mode 100644 index 0000000..4d54fed --- /dev/null +++ b/scripts/check-release-version.mjs @@ -0,0 +1,29 @@ +#!/usr/bin/env node +import { readFileSync } from "node:fs"; + +function readJson(path) { + return JSON.parse( + readFileSync(new URL(`../${path}`, import.meta.url), "utf8"), + ); +} + +const rootPackage = readJson("package.json"); +const mcpPackage = readJson("shared/glean/mcp/package.json"); +const releaseConfig = readJson(".release-it.json"); +const bumperOutput = releaseConfig.plugins?.["@release-it/bumper"]?.out; + +if (bumperOutput !== "shared/glean/mcp/package.json") { + throw new Error( + "release-it must explicitly bump shared/glean/mcp/package.json via @release-it/bumper.", + ); +} + +if (rootPackage.version !== mcpPackage.version) { + throw new Error( + `Release versions differ: root=${rootPackage.version}, MCP=${mcpPackage.version}.`, + ); +} + +console.log( + `Release version ${rootPackage.version} targets the root and local MCP packages.`, +); diff --git a/scripts/sync-plugin-changelogs.mjs b/scripts/sync-plugin-changelogs.mjs new file mode 100644 index 0000000..5c84810 --- /dev/null +++ b/scripts/sync-plugin-changelogs.mjs @@ -0,0 +1,17 @@ +#!/usr/bin/env node +// Propagate the canonical root changelog into each shared plugin. Runs +// automatically via the `prebuild` npm script. Version files are owned by +// release-it and @release-it/bumper instead of being rewritten during builds. +import { copyFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); + +const changelog = join(root, "CHANGELOG.md"); +const buckets = ["shared/glean", "shared/glean-dev-docs"]; + +for (const bucket of buckets) { + copyFileSync(changelog, join(root, bucket, "CHANGELOG.md")); + console.log(`synced CHANGELOG.md -> ${bucket}`); +} diff --git a/scripts/sync-release-metadata.mjs b/scripts/sync-release-metadata.mjs deleted file mode 100644 index e4391c4..0000000 --- a/scripts/sync-release-metadata.mjs +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env node -// Propagate canonical root release metadata into each shared plugin so every -// built plugin ships the same values. Runs automatically via the `prebuild` -// npm script. The root CHANGELOG.md and package.json are the single sources of -// truth (managed by release-it); the copies below are derived and should not be -// hand-edited. -import { copyFileSync, readFileSync, writeFileSync } from "node:fs"; -import { fileURLToPath } from "node:url"; -import { dirname, join } from "node:path"; - -const root = join(dirname(fileURLToPath(import.meta.url)), ".."); -const { version } = JSON.parse( - readFileSync(join(root, "package.json"), "utf8"), -); - -const changelog = join(root, "CHANGELOG.md"); -const buckets = [ - "shared/glean", - "shared/glean-dev-docs", -]; - -for (const bucket of buckets) { - copyFileSync(changelog, join(root, bucket, "CHANGELOG.md")); - console.log(`synced CHANGELOG.md -> ${bucket}`); -} - -// Textual replace, not a JSON round-trip, to keep the release diff to one line. -const manifestPath = join(root, "shared/glean/mcp/package.json"); -const before = readFileSync(manifestPath, "utf8"); -if (!/"version":\s*"[^"]*"/.test(before)) { - throw new Error( - `No "version" field in ${manifestPath} to sync. Add one — the local MCP ` + - `server reads it at runtime to report its own version.`, - ); -} -writeFileSync( - manifestPath, - before.replace(/("version":\s*")[^"]*"/, `$1${version}"`), -); -console.log(`synced version ${version} -> shared/glean/mcp`); diff --git a/shared/glean/mcp/src/version.ts b/shared/glean/mcp/src/version.ts index 9dea273..9546e73 100644 --- a/shared/glean/mcp/src/version.ts +++ b/shared/glean/mcp/src/version.ts @@ -1,7 +1,7 @@ // Read at runtime rather than injected at build time: `../package.json` hits the // shipped manifest from both src/ and dist/, and that file has to exist anyway // for Node to load the bundle as ESM. Kept in step with the root manifest by -// scripts/sync-release-metadata.mjs. +// @release-it/bumper via the root release-it configuration. import { readFileSync } from "node:fs"; export const PLUGIN_VERSION: string = JSON.parse(