v2 release pipeline, Phase 2: semver via changesets (TS), GitHub-Release-triggered publishing - #4604
v2 release pipeline, Phase 2: semver via changesets (TS), GitHub-Release-triggered publishing#4604olaservo wants to merge 7 commits into
Conversation
One-time semver reset ahead of changesets adoption (#4472). None of the four servers has ever carried a true semver value: the CalVer era was date-stamping, and everything's staged 2.0.0 was never published. 1.0.0 is unpublished on npm for all four. Hardcoded MCP serverInfo versions are aligned to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds @changesets/cli with GitHub-flavored changelogs, a Version Packages workflow that maintains the rolling version-bump PR on every push to main, and contributor docs covering when a changeset is needed and the semver policy (#4472). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reworks release.yml from workflow_dispatch to release:[published]. No job computes, stamps, or tags a version anymore: every package runs as an independent matrix job and publishes only if its manifest version is missing from the registry. The npm guard skips (not fails) an existing version and treats a never-published package (E404) as publish it; PyPI keeps skip-existing. Test gates stay as defense in depth, and the release environment binding for OIDC trusted publishing is unchanged (#4472). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces scripts/release.py with a focused script that stamps today's CalVer date onto Python packages changed since their last version bump (refreshing uv.lock), and a workflow_dispatch workflow that opens the resulting PR. The rest of release.py (version computation, matrix and notes generation) retires with the old release flow (#4472). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documents the merged state of the Phase 2 pipeline: changesets/semver for TypeScript, CalVer prepare-release for Python, publishing triggered by manually-created GitHub Releases, and the registry-diff self-healing behavior (#4472). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates the monorepo’s release pipeline to use Changesets-managed semver for the TypeScript servers, retain CalVer for Python servers, and publish packages from release.yml when a maintainer publishes a GitHub Release.
Changes:
- Reset TS workspace package versions (and MCP
serverInfoversions) to1.0.0across the four TypeScript servers. - Add Changesets tooling/config/docs and a rolling “Version Packages” PR workflow for semver bumps and CHANGELOG generation.
- Rework publishing to be GitHub-Release-triggered, with idempotent “registry-diff” guards and a new Python CalVer “prepare release” stamping workflow/script.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sequentialthinking/package.json | Reset TS package version to 1.0.0. |
| src/sequentialthinking/index.ts | Align MCP server version to 1.0.0. |
| src/memory/package.json | Reset TS package version to 1.0.0. |
| src/memory/index.ts | Align MCP server version to 1.0.0. |
| src/filesystem/package.json | Reset TS package version to 1.0.0. |
| src/filesystem/index.ts | Align MCP server version to 1.0.0. |
| src/everything/server/index.ts | Align server metadata version to 1.0.0. |
| src/everything/package.json | Reset TS package version to 1.0.0. |
| scripts/release.py | Remove old release-time version stamping/notes/matrix script. |
| scripts/prepare_python_release.py | Add Python CalVer stamping script that refreshes uv.lock. |
| RELEASING.md | Rewrite docs to describe the new versioning + GitHub-Release-triggered publish flow. |
| package.json | Add Changesets CLI scripts and devDependencies. |
| package-lock.json | Lockfile updates for Changesets dependencies. |
| CONTRIBUTING.md | Document when/how to add a changeset for TS servers. |
| .github/workflows/version-packages.yml | Add rolling “Version Packages” PR maintenance workflow. |
| .github/workflows/release.yml | Trigger on GitHub Release publish; publish per-package with registry guards. |
| .github/workflows/prepare-release.yml | Add workflow_dispatch Python CalVer stamping PR workflow. |
| .changeset/README.md | Add repo-local Changesets usage guidance. |
| .changeset/config.json | Add Changesets configuration (GitHub changelog integration). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
With --json, npm writes errors as JSON to stdout, so capturing stderr into the payload (2>&1) was unnecessary and risked stray npm warnings corrupting the JSON that jq parses — which would misread an already-published version as new. Capture stdout only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 19 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
.github/workflows/release.yml:76
- The npm registry guard redirects
npm viewstderr to/dev/null, so non-E404 failures can lose their most useful diagnostics (network/auth errors often go to stderr), leaving the logs with little/no actionable output. Capturing stderr separately keeps the JSON payload clean forjqwhile preserving troubleshooting info.
# stdout only: with --json, npm writes errors as JSON to stdout, and
# stray stderr warnings must not corrupt the payload we parse
set +e
PUBLISHED=$(npm view "$NAME" versions --json 2>/dev/null)
EXIT_CODE=$?
| @@ -0,0 +1,69 @@ | |||
| name: Prepare Python Release | |||
There was a problem hiding this comment.
Is prepare-release.yml the best name for this, since it specifically is for python files? maybe prepare-python-release.yml
There was a problem hiding this comment.
Agreed — renamed to prepare-python-release.yml (matching its display name and scripts/prepare_python_release.py), RELEASING.md links updated. Unlike release.yml, nothing binds to this filename, so the rename is free.
🦉 — Claude, via Claude Code
The workflow is Python-specific (TypeScript versioning goes through version-packages.yml), so the filename should say so — matching its display name and the script it runs. Suggested in review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Description
Implements Phase 2 of the release-pipeline rebuild (#4472): semver via changesets for the TypeScript servers, CalVer retained for Python, and publishing triggered by manually-created GitHub Releases instead of
workflow_dispatch.What's in this PR
1.0.0(everythingcomes down from its never-published staged2.0.0). Hardcoded MCPserverInfoversions in the fourindex.tsfiles are aligned to1.0.0as well (they had drifted:0.2.0/0.6.3/2.0.0).@changesets/cli+@changesets/changelog-githubat the workspace root,.changeset/config.json, a newversion-packages.ymlworkflow that maintains the rolling "Version Packages" PR on every push tomain, and CONTRIBUTING/.changeset/READMEdocs covering when a changeset is needed and the semver policy.release.ymlrework:release: [published]trigger, all-packages matrix, and a registry-diff guard that skips (not fails) an already-published version and treats a never-published package (npmE404) as "publish it". No job computes, stamps, or tags a version. Test gates stay as defense in depth. Thereleaseenvironment and workflow filename are unchanged, preserving the OIDC trusted-publisher bindings on both registries.prepare-python-release.yml(workflow_dispatch): stamps today's CalVer date onto Python packages changed since their last version bump (refreshinguv.lock) and opens a normal PR.scripts/release.pyis replaced by the focusedscripts/prepare_python_release.py; the rest of it (version computation, matrix/notes generation) retires with the old flow.RELEASING.mdrewritten to describe the merged state.How this was tested
changeset versionrun locally against a throwaway changeset: correctly bumped the target workspace package and generated a GitHub-flavored CHANGELOG (artifacts reverted).scripts/prepare_python_release.pyrun locally: correctly detected that all three Python packages have changes since their last version bump onmainand stamped them to2026.8.1withuv.lockrefresh (reverted — the real stamp happens via the dispatch after merge).release.ymlwas run verbatim against the live registry: all four packages at unpublished1.0.0→ publish; published semver (server-memory@0.6.2) and CalVer (server-everything@2025.4.8) versions → skip; a never-published package name (E404) → publish; jq normalization verified for both the bare-string (single published version) and array shapes ofnpm view versions --json.1.0.0; rootpackage-lock.jsonrefreshed; workflow YAML parse-validated. No tests assert the old version strings.Not in this PR (out-of-repo follow-ups)
npm deprecatethe CalVer ranges (>=2025.0.0 <2027.0.0) on the four TS packages with a pointer to the resumed semver linemcp-server-fetch,mcp-server-git,mcp-server-time) are bound torelease.ymlworkflow_calltest definitions to prevent CI/release driftNotes for reviewers
version-packages.ymlandprepare-python-release.ymluseGITHUB_TOKEN, so they don't trigger CI — close/reopen runs it. This is documented in RELEASING.md. If we want CI to run automatically on those PRs, a GitHub App token or PAT would be needed (out of scope here).pyproject.tomlversions onmainstill read0.6.xbecause the old flow only pushed version bumps as tags, never back tomain. The firstprepare-releasedispatch after this merges will stamp all three to the current date, which is correct —mainbecomes the source of truth from then on.Types of changes
Checklist
🤖 Generated with Claude Code