Skip to content

v2 release pipeline, Phase 2: semver via changesets (TS), GitHub-Release-triggered publishing - #4604

Open
olaservo wants to merge 7 commits into
mainfrom
release-pipeline-phase-2
Open

v2 release pipeline, Phase 2: semver via changesets (TS), GitHub-Release-triggered publishing#4604
olaservo wants to merge 7 commits into
mainfrom
release-pipeline-phase-2

Conversation

@olaservo

@olaservo olaservo commented Aug 2, 2026

Copy link
Copy Markdown
Member

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

  • One-time version reset: all four TS servers → 1.0.0 (everything comes down from its never-published staged 2.0.0). Hardcoded MCP serverInfo versions in the four index.ts files are aligned to 1.0.0 as well (they had drifted: 0.2.0/0.6.3/2.0.0).
  • Changesets adoption: @changesets/cli + @changesets/changelog-github at the workspace root, .changeset/config.json, a new version-packages.yml workflow that maintains the rolling "Version Packages" PR on every push to main, and CONTRIBUTING/.changeset/README docs covering when a changeset is needed and the semver policy.
  • release.yml rework: 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 (npm E404) as "publish it". No job computes, stamps, or tags a version. Test gates stay as defense in depth. The release environment 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 (refreshing uv.lock) and opens a normal PR. scripts/release.py is replaced by the focused scripts/prepare_python_release.py; the rest of it (version computation, matrix/notes generation) retires with the old flow.
  • RELEASING.md rewritten to describe the merged state.

How this was tested

  • changeset version run locally against a throwaway changeset: correctly bumped the target workspace package and generated a GitHub-flavored CHANGELOG (artifacts reverted).
  • scripts/prepare_python_release.py run locally: correctly detected that all three Python packages have changes since their last version bump on main and stamped them to 2026.8.1 with uv.lock refresh (reverted — the real stamp happens via the dispatch after merge).
  • The npm registry-diff guard logic from release.yml was run verbatim against the live registry: all four packages at unpublished 1.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 of npm view versions --json.
  • All four TS workspaces build at 1.0.0; root package-lock.json refreshed; workflow YAML parse-validated. No tests assert the old version strings.

Not in this PR (out-of-repo follow-ups)

  • npm deprecate the CalVer ranges (>=2025.0.0 <2027.0.0) on the four TS packages with a pointer to the resumed semver line
  • Install the changeset-bot GitHub App so PRs missing a changeset get flagged
  • Verify PyPI trusted-publisher registrations (mcp-server-fetch, mcp-server-git, mcp-server-time) are bound to release.yml
  • Optional: reusable workflow_call test definitions to prevent CI/release drift

Notes for reviewers

  • PRs opened by version-packages.yml and prepare-python-release.yml use GITHUB_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).
  • The Python packages' pyproject.toml versions on main still read 0.6.x because the old flow only pushed version bumps as tags, never back to main. The first prepare-release dispatch after this merges will stamp all three to the current date, which is correct — main becomes the source of truth from then on.

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Documentation update

Checklist

  • I have read the MCP Protocol Documentation
  • My changes follows MCP security best practices
  • My code follows the repository's style guidelines
  • New and existing tests pass locally

🤖 Generated with Claude Code

olaservo and others added 5 commits August 1, 2026 18:52
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 serverInfo versions) to 1.0.0 across 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.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/prepare-python-release.yml
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 view stderr 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 for jq while 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=$?

Comment thread .github/workflows/release.yml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

a-akimov
a-akimov previously approved these changes Aug 3, 2026
@@ -0,0 +1,69 @@
name: Prepare Python Release

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is prepare-release.yml the best name for this, since it specifically is for python files? maybe prepare-python-release.yml

@olaservo olaservo Aug 3, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@cliffhall cliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants