@slbdn/mcp-tester 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +8 -6
- package/docs/releases.md +97 -354
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.7.0] - 2026-10-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `npm run release -- <patch|minor|major|prerelease>` — a one-command release tool that runs a strict pre-flight (clean tree, origin sync, no dangling tags, `npm@10` lockfile check, `npm@10` audit, full local gates, version sanity, non-empty `[Unreleased]`) and then bumps the version, promotes the CHANGELOG, commits `chore: release <x.y.z>`, and creates a lightweight `v<x.y.z>` tag. `--dry-run` runs every gate and prints the plan without writing. Every gate maps to a real incident (1.5.0 audit, 1.5.1 / 1.6.0 emnapi lockfile trap, v1.5.5 fold); see `docs/plans/release-automation.md` and `docs/releases.md`. Zero new runtime deps; pure library in `scripts/release-lib.mjs`, orchestrator in `scripts/release.mjs`, 39 `node:test` cases in `scripts/release.test.mjs` run by `npm run test:release` (wired into CI). Replaces the old `npm version`-based `release:patch/minor/major/prerelease` scripts (the new aliases delegate to the script).
|
|
14
|
+
- The release tool's pre-flight is a strict superset of the gates `release.yml` runs, so a green pre-flight ≈ a green publish. Interrupted runs are detected and resumed safely — a re-run re-verifies the gates and completes only the missing tag, never re-applying the bump or changelog promotion — and any failure path rolls back every partial write (including staged content).
|
|
15
|
+
- `--dry-run` and exit codes (0 ok / 1 gate failed / 2 usage error) make the tool safe to call from scripts.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- The release workflow's post-publish verification no longer fails on npm registry propagation lag. `npm publish` is eventually consistent — a version published seconds earlier can still 404 via CDN negative caching — so the `verify` job now polls `npm view` until the version is visible (up to 10 minutes) and retries the install a few times instead of failing the run. Previously the job had to be manually re-run a few minutes later to go green.
|
|
19
|
+
- Running the CLI test suite no longer leaks the child process's deliberate error output (e.g. `❌ Framework must be "jest" or "vitest"` from the invalid-flag test) into the Jest log — every spawned CLI invocation now pipes its output. A passing suite printed as if it had errors; it did this twice per release run.
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
- `markdown-it` 14.3.2 → 14.3.3 (GHSA-vfgh-jcmw-g37q, GHSA-gfr2-rv44-r23c — quadratic-time DoS; dev-only, via TypeDoc) and `ip-address` 10.7.3 → 10.7.4 (GHSA-rxp7-6hxx-x8q5; dev-only, via the SDK's express-rate-limit). `npm audit` is now clean at the `high` threshold. Notably, the release tool's own P5 audit gate caught this locally before tagging — the same failure class that blocked the 1.5.0 release in CI.
|
|
23
|
+
|
|
10
24
|
## [1.6.0] - 2026-10-08
|
|
11
25
|
|
|
12
26
|
### Added
|
package/README.md
CHANGED
|
@@ -617,12 +617,14 @@ mcp-tester/
|
|
|
617
617
|
## Development
|
|
618
618
|
|
|
619
619
|
```bash
|
|
620
|
-
npm install
|
|
621
|
-
npm run build
|
|
622
|
-
npm run dev
|
|
623
|
-
npm test
|
|
624
|
-
npm run
|
|
625
|
-
npm run
|
|
620
|
+
npm install # Install dependencies
|
|
621
|
+
npm run build # Compile TypeScript
|
|
622
|
+
npm run dev # Watch mode — auto-rebuild on source changes
|
|
623
|
+
npm test # Run tests (auto-generates reports/test-report.html)
|
|
624
|
+
npm run test:browser # Smoke-test the browser bundle (esbuild, platform: 'browser')
|
|
625
|
+
npm run lint # Lint code
|
|
626
|
+
npm run format # Format with Prettier
|
|
627
|
+
npm run release -- patch # Cut a release (see docs/releases.md)
|
|
626
628
|
```
|
|
627
629
|
|
|
628
630
|
## Troubleshooting
|
package/docs/releases.md
CHANGED
|
@@ -1,413 +1,156 @@
|
|
|
1
1
|
# Release Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
How to create and publish a new release of `mcp-tester`. The release tool (`npm run release`) does the version bump, CHANGELOG promotion, commit, and tag in one command — and runs a strict pre-flight that catches every issue we've shipped broken before (audit failures, npm 11 lockfile traps, dangling local tags, empty `[Unreleased]`).
|
|
4
4
|
|
|
5
|
-
## Prerequisites
|
|
5
|
+
## Prerequisites (one-time)
|
|
6
6
|
|
|
7
|
-
1. **NPM Token
|
|
8
|
-
- Go to
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- Click "New repository secret"
|
|
13
|
-
- Name: `NPM_TOKEN`
|
|
14
|
-
- Value: Your npm automation token
|
|
7
|
+
1. **NPM Token**
|
|
8
|
+
- Go to <https://www.npmjs.com/settings/tokens> and create an **Automation** token.
|
|
9
|
+
- Add it to the repository as the secret `NPM_TOKEN` (Settings → Secrets and variables → Actions → New repository secret).
|
|
10
|
+
2. **GitHub Actions** — `GITHUB_TOKEN` is automatic; `release.yml` already has `contents: write` for releases and `id-token: write` for provenance (if enabled).
|
|
11
|
+
3. **Local git** — `git push` permission for `main` and tags. The release script never pushes; you do that after the script finishes.
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
- The `GITHUB_TOKEN` is automatically provided by GitHub Actions
|
|
18
|
-
- Ensure the workflow has permission to create releases (already configured)
|
|
19
|
-
|
|
20
|
-
## Release Process
|
|
21
|
-
|
|
22
|
-
### Option 1: Quick Release (Recommended)
|
|
23
|
-
|
|
24
|
-
Use this for routine releases (patch, minor, or major version bumps):
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# For patch release (1.0.0 → 1.0.1)
|
|
28
|
-
npm run release:patch
|
|
29
|
-
|
|
30
|
-
# For minor release (1.0.0 → 1.1.0)
|
|
31
|
-
npm run release:minor
|
|
32
|
-
|
|
33
|
-
# For major release (1.0.0 → 2.0.0)
|
|
34
|
-
npm run release:major
|
|
35
|
-
|
|
36
|
-
# For prerelease (1.0.0 → 1.0.1-beta.0)
|
|
37
|
-
npm run release:prerelease
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Then commit and create tag:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# Commit the version bump and CHANGELOG updates
|
|
44
|
-
npm run release:commit
|
|
45
|
-
|
|
46
|
-
# Create and push the tag
|
|
47
|
-
git tag v$(node -p "require('./package.json').version")
|
|
48
|
-
git push origin main --tags
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The release workflow will automatically:
|
|
52
|
-
- ✅ Verify version matches tag
|
|
53
|
-
- ✅ Run tests across Node.js versions (20, 22)
|
|
54
|
-
- ✅ Build the project
|
|
55
|
-
- ✅ Run security audits
|
|
56
|
-
- ✅ Publish to npm
|
|
57
|
-
- ✅ Create GitHub release with notes from CHANGELOG
|
|
58
|
-
- ✅ Upload coverage to Codecov
|
|
59
|
-
|
|
60
|
-
### Option 2: Manual Release
|
|
61
|
-
|
|
62
|
-
For full control over the release process:
|
|
13
|
+
## The release process
|
|
63
14
|
|
|
64
15
|
```bash
|
|
65
|
-
# 1.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
# - Move items from [Unreleased] to new version section
|
|
70
|
-
# - Add date to version header: ## [1.0.1] - 2025-01-20
|
|
71
|
-
# - Keep [Unreleased] section for next changes
|
|
72
|
-
|
|
73
|
-
# 3. Verify tests pass
|
|
74
|
-
npm test
|
|
16
|
+
# 1. Make sure your tree is ready:
|
|
17
|
+
# - the [Unreleased] section of CHANGELOG.md has the entries you want to ship
|
|
18
|
+
# - everything you want in the release is committed and pushed
|
|
19
|
+
git push origin main
|
|
75
20
|
|
|
76
|
-
#
|
|
77
|
-
npm run
|
|
21
|
+
# 2. Run the release script (add --dry-run first if you want a no-write preview)
|
|
22
|
+
npm run release -- minor
|
|
23
|
+
# alias scripts: release:patch, release:minor, release:major, release:prerelease
|
|
78
24
|
|
|
79
|
-
#
|
|
80
|
-
git
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# 6. Create and push tag
|
|
84
|
-
git tag v1.0.1
|
|
85
|
-
git push origin main --tags
|
|
25
|
+
# 3. The script prints the push command when it succeeds:
|
|
26
|
+
# git push origin main --tags
|
|
27
|
+
# Run that. release.yml takes over from there.
|
|
86
28
|
```
|
|
87
29
|
|
|
88
|
-
|
|
30
|
+
The script:
|
|
89
31
|
|
|
90
|
-
|
|
32
|
+
1. Runs a strict pre-flight (next section). If anything is off, it exits 1 with an actionable message and writes nothing.
|
|
33
|
+
2. Bumps the version in `package.json` and the two `version` lines in `package-lock.json` (direct JSON edit — **never** `npm version`, which has produced lockfile churn in the past).
|
|
34
|
+
3. Promotes `## [Unreleased]` to `## [<version>] - <today>` in `CHANGELOG.md`, byte-for-byte preserving the rest.
|
|
35
|
+
4. Verifies the resulting `git diff` is exactly the 3 expected files with the expected line counts.
|
|
36
|
+
5. Creates the commit `chore: release <version>` and a lightweight tag `v<version>`.
|
|
37
|
+
6. Prints the push handoff.
|
|
91
38
|
|
|
92
|
-
|
|
93
|
-
# Set specific version
|
|
94
|
-
npm version 1.2.3
|
|
95
|
-
|
|
96
|
-
# Update CHANGELOG.md manually
|
|
97
|
-
# ... edit CHANGELOG.md ...
|
|
98
|
-
|
|
99
|
-
# Commit
|
|
100
|
-
git add package.json CHANGELOG.md
|
|
101
|
-
git commit -m "chore: release v1.2.3"
|
|
102
|
-
|
|
103
|
-
# Create tag and push
|
|
104
|
-
git tag v1.2.3
|
|
105
|
-
git push origin main --tags
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Version Numbering
|
|
109
|
-
|
|
110
|
-
Follow [Semantic Versioning](https://semver.org/):
|
|
111
|
-
|
|
112
|
-
- **MAJOR** (X.0.0): Breaking changes or major features
|
|
113
|
-
- Example: 1.0.0 → 2.0.0
|
|
114
|
-
- Use when: API changes that break compatibility
|
|
115
|
-
|
|
116
|
-
- **MINOR** (0.X.0): New features, backward compatible
|
|
117
|
-
- Example: 1.0.0 → 1.1.0
|
|
118
|
-
- Use when: Adding new features without breaking changes
|
|
119
|
-
|
|
120
|
-
- **PATCH** (0.0.X): Bug fixes
|
|
121
|
-
- Example: 1.0.0 → 1.0.1
|
|
122
|
-
- Use when: Fixing bugs without adding features
|
|
123
|
-
|
|
124
|
-
- **PRERELEASE** (0.0.0-X): Pre-release versions
|
|
125
|
-
- Example: 1.0.0 → 1.1.0-alpha.1
|
|
126
|
-
- Use when: Testing unreleased features
|
|
127
|
-
|
|
128
|
-
## Pre-Release Checklist
|
|
129
|
-
|
|
130
|
-
Before creating a release:
|
|
131
|
-
|
|
132
|
-
### 1. Update CHANGELOG.md
|
|
133
|
-
```markdown
|
|
134
|
-
## [1.0.1] - 2025-01-20
|
|
135
|
-
|
|
136
|
-
### Added
|
|
137
|
-
- New feature X
|
|
138
|
-
|
|
139
|
-
### Fixed
|
|
140
|
-
- Bug Y fixed
|
|
141
|
-
|
|
142
|
-
### Changed
|
|
143
|
-
- Updated dependency Z
|
|
144
|
-
|
|
145
|
-
## [Unreleased]
|
|
146
|
-
|
|
147
|
-
### Added
|
|
148
|
-
- Next feature A (stays here)
|
|
149
|
-
```
|
|
39
|
+
Nothing is pushed, nothing is published. You can inspect the commit with `git show`, the diff with `git show v<version>`, and the tag with `git tag -l`. If anything looks wrong, abort the release with `git reset --hard HEAD~1 && git tag -d v<version>`.
|
|
150
40
|
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
npm test
|
|
154
|
-
npm run test:coverage
|
|
155
|
-
```
|
|
41
|
+
## The pre-flight gates (P1–P8)
|
|
156
42
|
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
npm run build
|
|
160
|
-
npm run lint
|
|
161
|
-
npm run format:check
|
|
162
|
-
```
|
|
43
|
+
Each gate maps to a real incident. If any fails, the script exits 1 with the failing gate, why it failed, and the manual command to re-run for the real error output.
|
|
163
44
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
45
|
+
| Gate | Checks | Incident it would have caught |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| **P1** | Working tree is clean | (always; you can't cut a release on dirty code) |
|
|
48
|
+
| **P2** | `HEAD` is at the tip of `origin/main` (no unpushed, no unpulled commits) | The 1.6.0 fold — release tag lived on unpushed commits |
|
|
49
|
+
| **P3** | Every local `v*` tag exists on `origin` (peeks `^{commit}` to match the remote's peeled entry) | Same — would have caught `v1.5.5` as dangling before publish |
|
|
50
|
+
| **P4** | Lockfile is installable by `npm@10` (run in a temp dir; CI's npm) | The 1.5.1 + 1.6.0 emnapi trap — `npm audit fix` under npm 11 has twice produced locks npm 10 cannot install |
|
|
51
|
+
| **P5** | `npm@10 audit --audit-level=high` exits 0 | 1.5.0 publish failure (SDK OAuth + proxy-addr) |
|
|
52
|
+
| **P6** | Full local gates: `build`, `lint`, `format:check`, `test:browser`, `test`, `test:coverage`, `test:package` | Surfaces anything `release.yml` will run, locally, in ~6 min |
|
|
53
|
+
| **P7** | New version `N` is strictly greater than published `P`; no local tag `v{N}`; not on the registry | Re-releasing the same version; double-tagging |
|
|
54
|
+
| **P8** | `## [Unreleased]` exists in `CHANGELOG.md` and contains at least one content line | The v1.5.5 fold — release with nothing in it |
|
|
169
55
|
|
|
170
|
-
|
|
171
|
-
- [ ] README.md is up to date
|
|
172
|
-
- [ ] CHANGELOG.md includes all changes
|
|
173
|
-
- [ ] Examples work correctly
|
|
174
|
-
- [ ] API documentation is accurate
|
|
56
|
+
Use `npm run release -- <bump> --dry-run` to run every gate and print the planned version / date / diff preview without writing anything.
|
|
175
57
|
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
npm version patch # This updates package.json
|
|
179
|
-
cat package.json | grep version
|
|
180
|
-
```
|
|
58
|
+
## How the CI publish works (so you know what to expect)
|
|
181
59
|
|
|
182
|
-
|
|
60
|
+
Pushing `main` + the new `v<x.y.z>` tag triggers `.github/workflows/release.yml`, which:
|
|
183
61
|
|
|
184
|
-
|
|
62
|
+
1. **Verifies** the tag version matches `package.json` (refuses to publish a misaligned tag).
|
|
63
|
+
2. **Runs gates on Node 20 / npm 10** — `npm ci`, `npm audit --audit-level=high` (hard gate), `build`, `lint`, `format:check`, `test`, `coverage`.
|
|
64
|
+
3. **Publishes** to npm with provenance, creates the GitHub release from the CHANGELOG section that was just promoted, uploads coverage to Codecov.
|
|
65
|
+
4. **Verifies** the install from the registry. This job now waits up to 10 minutes for the version to become visible (npm is eventually consistent) and retries the install (see commit `24fee8d`).
|
|
185
66
|
|
|
186
|
-
|
|
187
|
-
2. **Verify**: Confirms tag version matches package.json
|
|
188
|
-
3. **Test**: Runs all tests across Node.js 20, 22
|
|
189
|
-
4. **Build**: Compiles TypeScript to JavaScript
|
|
190
|
-
5. **Audit**: Runs security audits
|
|
191
|
-
6. **Lint**: Checks code quality
|
|
192
|
-
7. **Publish**: Publishes package to npm registry
|
|
193
|
-
8. **Release**: Creates GitHub release with CHANGELOG notes
|
|
194
|
-
9. **Verify**: Verifies package can be installed from npm
|
|
67
|
+
If step 2 fails after the tag is pushed, fix the issue and cut a **new** release with the script — do not rewrite the tag, do not re-run the workflow.
|
|
195
68
|
|
|
196
|
-
##
|
|
69
|
+
## Versioning
|
|
197
70
|
|
|
198
|
-
|
|
71
|
+
[Semantic Versioning](https://semver.org/):
|
|
199
72
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
73
|
+
- **MAJOR** — breaking API change. Use sparingly.
|
|
74
|
+
- **MINOR** — new capability, backward compatible (browser support, new transport, new matcher).
|
|
75
|
+
- **PATCH** — bug fix, no public surface change (workflow fix, lockfile bump, doc fix).
|
|
76
|
+
- **PRERELEASE** — opt-in / experimental. The script supports `npm run release -- prerelease` and follows npm's `npm version prerelease` rules: `1.6.0` → `1.6.1-0`, `1.6.1-0` → `1.6.1-1`, `1.6.1-beta.0` → `1.6.1-beta.1`.
|
|
203
77
|
|
|
204
|
-
|
|
78
|
+
## Manual fallback (discouraged)
|
|
205
79
|
|
|
206
|
-
|
|
80
|
+
If the release script can't run for some reason (e.g. you need to do a post-incident hotfix on a fresh clone with no network), the manual equivalent is:
|
|
207
81
|
|
|
208
|
-
### 1. Verify on npm
|
|
209
82
|
```bash
|
|
210
|
-
#
|
|
211
|
-
npm
|
|
212
|
-
|
|
213
|
-
#
|
|
214
|
-
|
|
83
|
+
# 1. Edit package.json "version" and the two version lines in package-lock.json
|
|
84
|
+
# (top-level + packages[""].version). Do NOT run `npm version` — it rewrites
|
|
85
|
+
# the lockfile through npm's own machinery and has produced churn before.
|
|
86
|
+
# 2. Promote CHANGELOG.md by hand: `## [Unreleased]` → `## [N] - YYYY-MM-DD`.
|
|
87
|
+
# 3. Commit and tag.
|
|
88
|
+
git add package.json package-lock.json CHANGELOG.md
|
|
89
|
+
git commit -m "chore: release N"
|
|
90
|
+
git tag vN
|
|
91
|
+
git push origin main --tags
|
|
215
92
|
```
|
|
216
93
|
|
|
217
|
-
|
|
218
|
-
- Go to: `https://github.com/islobodan/mcp-tester/releases`
|
|
219
|
-
- Check release notes are correct
|
|
220
|
-
- Verify release assets are attached
|
|
221
|
-
|
|
222
|
-
### 3. Update Documentation
|
|
223
|
-
- Update README.md if needed
|
|
224
|
-
- Update examples if API changed
|
|
225
|
-
- Update AGENTS.md with new features
|
|
226
|
-
|
|
227
|
-
### 4. Announce Release
|
|
228
|
-
- Create GitHub Discussion
|
|
229
|
-
- Post issue about the release
|
|
230
|
-
- Update project documentation
|
|
94
|
+
If the script's pre-flight then fails on the *next* release, it's usually P4 (lockfile) — fix with `npx -y npm@10 install` (not `npm audit fix` under npm 11).
|
|
231
95
|
|
|
232
96
|
## Troubleshooting
|
|
233
97
|
|
|
234
|
-
###
|
|
98
|
+
### Pre-flight says "tree is not clean"
|
|
235
99
|
|
|
236
|
-
|
|
237
|
-
1. Version tag format (must be `vX.Y.Z`)
|
|
238
|
-
2. Version matches package.json exactly
|
|
239
|
-
3. Tests are passing locally
|
|
240
|
-
4. NPM_TOKEN is set correctly
|
|
100
|
+
Commit, stash, or unstage the listed files. The script refuses to operate on a dirty tree because the `git diff --numstat` self-check needs a stable baseline.
|
|
241
101
|
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
# Delete and recreate tag
|
|
245
|
-
git tag -d v1.0.1
|
|
246
|
-
git push origin :refs/tags/v1.0.1
|
|
102
|
+
### Pre-flight says "HEAD is N commit(s) ahead of origin/main"
|
|
247
103
|
|
|
248
|
-
|
|
249
|
-
git tag v1.0.1
|
|
250
|
-
git push origin v1.0.1
|
|
251
|
-
```
|
|
104
|
+
You have local commits that aren't pushed. Either push them (`git push origin main`) and re-run, or reset them if you don't want them. The 1.5.5 fold was exactly this scenario.
|
|
252
105
|
|
|
253
|
-
###
|
|
106
|
+
### Pre-flight P4 fails ("lockfile not installable by npm 10")
|
|
254
107
|
|
|
255
|
-
|
|
256
|
-
1. NPM_TOKEN has publish permissions
|
|
257
|
-
2. Package name is not already taken
|
|
258
|
-
3. Version doesn't already exist on npm
|
|
108
|
+
`npm@10 ci --dry-run` returned non-zero in the temp dir. The most common cause is `npm audit fix` having been run under npm 11. Fix:
|
|
259
109
|
|
|
260
|
-
**Fix:**
|
|
261
110
|
```bash
|
|
262
|
-
#
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
# Check if version exists
|
|
266
|
-
npm view @slbdn/mcp-tester@1.0.1
|
|
267
|
-
|
|
268
|
-
# If version exists, increment it
|
|
269
|
-
npm version patch
|
|
270
|
-
git commit package.json -m "chore: increment version"
|
|
271
|
-
git tag v1.0.2
|
|
272
|
-
git push origin v1.0.2
|
|
111
|
+
npx -y npm@10 install # regenerate lock under npm 10
|
|
112
|
+
# OR (if you actually want audit fixes)
|
|
113
|
+
npx -y npm@10 audit fix
|
|
273
114
|
```
|
|
274
115
|
|
|
275
|
-
|
|
116
|
+
Then re-run the release script. See `docs/troubleshooting.md` for the full emnapi history.
|
|
276
117
|
|
|
277
|
-
|
|
278
|
-
1. GITHUB_TOKEN has write permissions
|
|
279
|
-
2. Workflow has permission to create releases
|
|
280
|
-
3. Tag format is correct
|
|
118
|
+
### Pre-flight P5 fails (audit)
|
|
281
119
|
|
|
282
|
-
|
|
283
|
-
- Manually create release from GitHub UI
|
|
284
|
-
- Or delete tag and push again
|
|
120
|
+
Same command `release.yml` will run. Run `npx -y npm@10 audit` to see what; bump or replace the offending dependency. If the advisory is in a transitive dep behind a dev-only package, the right fix is to bump the parent (e.g. `ts-jest` was the path that brought in `handlebars` for 1.6.0).
|
|
285
121
|
|
|
286
|
-
###
|
|
122
|
+
### Pre-flight P8 fails ("nothing to release — [Unreleased] is empty")
|
|
287
123
|
|
|
288
|
-
|
|
289
|
-
1. All tests pass locally
|
|
290
|
-
2. Node.js version compatibility
|
|
291
|
-
3. Dependencies are installed correctly
|
|
124
|
+
Add entries to `CHANGELOG.md` under `## [Unreleased]`, or skip this release. The script refuses to cut a release with an empty changelog because that's exactly the shape of the v1.5.5 fold.
|
|
292
125
|
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
# Clean and reinstall
|
|
296
|
-
rm -rf node_modules package-lock.json
|
|
297
|
-
npm install
|
|
126
|
+
### Resume after an interrupted run
|
|
298
127
|
|
|
299
|
-
|
|
300
|
-
npm test
|
|
301
|
-
```
|
|
128
|
+
If the script died between the commit and the tag (e.g. lost connection), the next run detects the state — `package.json` is bumped, `CHANGELOG.md` has the new section, HEAD is `chore: release <N>`, but the tag is missing — and just creates the missing tag. Resume detection itself is a cheap local shape check (no network); the full pre-flight still runs in resume mode, with two deliberate exceptions: P2 (HEAD is necessarily ahead of `origin/main` — the release commit is about to be pushed) and P8 (the changelog is already promoted — that is the resume signal). `N > published P` is still verified in P7, and the release steps never re-run the bump/promotion (which is not idempotent).
|
|
302
129
|
|
|
303
|
-
|
|
130
|
+
### `release.yml` verify job fails
|
|
304
131
|
|
|
305
|
-
|
|
132
|
+
`release.yml`'s verify job now waits up to 10 minutes for npm to propagate and retries the install (commit `24fee8d`). If it still fails, the package genuinely is not installable — check the workflow logs and treat as a real failure.
|
|
306
133
|
|
|
307
|
-
###
|
|
308
|
-
```bash
|
|
309
|
-
npm deprecate @slbdn/mcp-tester@1.0.1 "Release rollback due to bug"
|
|
310
|
-
```
|
|
134
|
+
### Tag exists locally but you want to redo the release
|
|
311
135
|
|
|
312
|
-
### 2. Delete GitHub Release
|
|
313
|
-
1. Go to repository releases page
|
|
314
|
-
2. Edit or delete the release
|
|
315
|
-
3. Delete the tag if needed
|
|
316
|
-
|
|
317
|
-
### 3. Create Hotfix
|
|
318
136
|
```bash
|
|
319
|
-
|
|
320
|
-
git
|
|
321
|
-
|
|
322
|
-
# Fix issue
|
|
323
|
-
git commit -am "fix: critical bug"
|
|
324
|
-
|
|
325
|
-
# Bump version
|
|
326
|
-
npm version patch
|
|
327
|
-
|
|
328
|
-
# Release
|
|
329
|
-
git tag v1.0.2
|
|
330
|
-
git push origin v1.0.2
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## Best Practices
|
|
334
|
-
|
|
335
|
-
1. **Update CHANGELOG First**
|
|
336
|
-
- Always update CHANGELOG.md before version bump
|
|
337
|
-
- Include all changes in the release
|
|
338
|
-
- Reference issues/PRs if helpful
|
|
339
|
-
|
|
340
|
-
2. **Test Before Release**
|
|
341
|
-
- Run all tests locally
|
|
342
|
-
- Build the project
|
|
343
|
-
- Install and test locally
|
|
344
|
-
|
|
345
|
-
3. **Use Semantic Versioning**
|
|
346
|
-
- MAJOR: Breaking changes
|
|
347
|
-
- MINOR: New features
|
|
348
|
-
- PATCH: Bug fixes
|
|
349
|
-
|
|
350
|
-
4. **Tag Naming**
|
|
351
|
-
- Always use `v` prefix: `v1.0.1`
|
|
352
|
-
- Follow semver format: `vX.Y.Z`
|
|
353
|
-
|
|
354
|
-
5. **Review Before Pushing**
|
|
355
|
-
- Check CHANGELOG is complete
|
|
356
|
-
- Verify version is correct
|
|
357
|
-
- Confirm tests pass
|
|
358
|
-
|
|
359
|
-
6. **Monitor Release**
|
|
360
|
-
- Watch GitHub Actions workflow
|
|
361
|
-
- Check npm publication
|
|
362
|
-
- Verify GitHub release creation
|
|
363
|
-
|
|
364
|
-
7. **Document Breaking Changes**
|
|
365
|
-
- Clearly document breaking changes in CHANGELOG
|
|
366
|
-
- Add migration guide if needed
|
|
367
|
-
- Update examples to use new API
|
|
368
|
-
|
|
369
|
-
## Example: Complete Release Workflow
|
|
370
|
-
|
|
371
|
-
```bash
|
|
372
|
-
# 1. Update CHANGELOG.md
|
|
373
|
-
# Edit CHANGELOG.md, move items from [Unreleased] to new version
|
|
374
|
-
|
|
375
|
-
# 2. Bump version (patch release)
|
|
376
|
-
npm run release:patch
|
|
377
|
-
|
|
378
|
-
# 3. Verify tests pass
|
|
379
|
-
npm test
|
|
380
|
-
|
|
381
|
-
# 4. Build project
|
|
382
|
-
npm run build
|
|
383
|
-
|
|
384
|
-
# 5. Commit changes
|
|
385
|
-
npm run release:commit
|
|
386
|
-
|
|
387
|
-
# 6. Create and push tag
|
|
388
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
389
|
-
git tag v$VERSION
|
|
390
|
-
git push origin main --tags
|
|
391
|
-
|
|
392
|
-
# 7. Monitor release at:
|
|
393
|
-
# https://github.com/islobodan/mcp-tester/actions
|
|
137
|
+
git tag -d vX.Y.Z
|
|
138
|
+
git reset --hard HEAD~1 # undo the release commit
|
|
139
|
+
# re-run: npm run release -- patch
|
|
394
140
|
```
|
|
395
141
|
|
|
396
|
-
|
|
142
|
+
Never push a deletion of a published tag without first unpublishing or deprecating that version on npm.
|
|
397
143
|
|
|
398
|
-
|
|
399
|
-
- [npm Publishing](https://docs.npmjs.com/cli/publish)
|
|
400
|
-
- [GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)
|
|
401
|
-
- [GitHub Actions](https://docs.github.com/en/actions)
|
|
144
|
+
## Best practices
|
|
402
145
|
|
|
403
|
-
|
|
146
|
+
1. **Keep `[Unreleased]` flowing.** Add changelog entries with the code change, not in a separate prep step. The script's P8 gate makes this a hard requirement.
|
|
147
|
+
2. **Push before you release.** The script's P2 + P3 gates enforce this; respect them.
|
|
148
|
+
3. **One tag per push.** Two tag pushes launch two concurrent `release.yml` runs that both `npm publish`; npm `latest` will land on whichever finishes last (potentially the older one). If you accidentally cut two, see [docs/troubleshooting.md](./troubleshooting.md).
|
|
149
|
+
4. **Use `--dry-run` on the first cut of a new release line** to sanity-check what would happen without writing anything.
|
|
150
|
+
5. **Never run `npm version` against this repo's lockfile.** Use the script (which does direct JSON edits + a diff self-check) or the manual fallback.
|
|
404
151
|
|
|
405
|
-
|
|
152
|
+
## See also
|
|
406
153
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
- Version being released
|
|
411
|
-
- Error messages
|
|
412
|
-
- Steps taken
|
|
413
|
-
- Expected vs actual behavior
|
|
154
|
+
- [`docs/plans/release-automation.md`](./plans/release-automation.md) — the implementation spec, including the incident log that justifies every gate.
|
|
155
|
+
- [`docs/troubleshooting.md`](./troubleshooting.md) — common failures and how to fix them.
|
|
156
|
+
- [`CHANGELOG.md`](../CHANGELOG.md) — the changelog the script promotes.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slbdn/mcp-tester",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Minimal MCP client implementation for CI/CD testing of MCP servers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"browser": {
|
|
@@ -36,11 +36,12 @@
|
|
|
36
36
|
"audit": "npm audit",
|
|
37
37
|
"audit:fix": "npm audit fix",
|
|
38
38
|
"prepublishOnly": "npm run build && npm run docs",
|
|
39
|
-
"release
|
|
40
|
-
"release:
|
|
41
|
-
"release:
|
|
42
|
-
"release:
|
|
43
|
-
"release:
|
|
39
|
+
"release": "node scripts/release.mjs",
|
|
40
|
+
"release:patch": "node scripts/release.mjs patch",
|
|
41
|
+
"release:minor": "node scripts/release.mjs minor",
|
|
42
|
+
"release:major": "node scripts/release.mjs major",
|
|
43
|
+
"release:prerelease": "node scripts/release.mjs prerelease",
|
|
44
|
+
"test:release": "node --test scripts/release.test.mjs",
|
|
44
45
|
"prepare": "husky || true"
|
|
45
46
|
},
|
|
46
47
|
"bin": {
|