From 4227c3e5c20348af8d1a114f786bbdac8bb59ed8 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Thu, 29 Oct 2026 00:57:25 -0400 Subject: [PATCH] docs(release): link the Prepare Python Release PR with addCloseIssueReferences Step 2c of the release skill now links the workflow-opened PR to the release issue and reads the link back (the pr-flow step 6 recipe), and says the by-hand fallback does the same. RELEASING.md says so next to the Version Packages sentence. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- .claude/skills/release/SKILL.md | 24 ++++++++++++++++++++---- RELEASING.md | 4 ++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index 4f3fe0bc45..55f1017aa4 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -256,11 +256,25 @@ gh workflow run prepare-python-release.yml --repo modelcontextprotocol/servers \ It opens a PR that starts with `Closes #N`, on a branch named `v2/chore/-python-calver-`, labeled `v2`, and dispatches the TypeScript, Python and DCO workflows on that branch, as the Version Packages -workflow does (not the Everything diff, whose paths it never touches). Wait -for its three `(dispatched)` statuses to pass, check that each stamped package really -changed, and a maintainer merges it. +workflow does (not the Everything diff, whose paths it never touches). No PR means no Python server has a shipped change since its last stamp. +Then, on the PR: + +1. **Link it to the release issue.** Its `Closes #N` is only a + cross-reference on `v2/main`, and the workflow makes no API call, so link + it with the `addCloseIssueReferences` mutation from `/pr-flow` (step 6) + and read it back: `closingIssuesReferences` must list `#N`. On `v2/main` + it closes nothing at merge. Find the PR by its branch: + + ```sh + gh pr list --repo modelcontextprotocol/servers --base v2/main \ + --json number,headRefName,url \ + | jq --arg p "v2/chore/$N-python-calver-" '.[] | select(.headRefName | startswith($p))' + ``` +2. **Wait for its three `(dispatched)` statuses to pass**, check that each + stamped package really changed, and a maintainer merges it. + ⚠️ GitHub only dispatches a workflow that exists on the default branch. Until the first milestone merge carries this one to `main`, do it by hand, which is the same script: @@ -274,7 +288,9 @@ node scripts/prepare-python-release.mjs # prints "name: old -> new" per stam git commit -s -am "chore: stamp Python CalVer versions for $(date -u +%Y.%-m.%-d)" ``` -then open the PR through `/pr-flow`, body starting `Closes #N`. +then open the PR through `/pr-flow`, body starting `Closes #N`. Its step 6 +links the PR to the release issue and reads the link back, as step 1 above +does for the workflow's PR: do not skip it. ## 3. The merge PR: `v2/main` → `main` diff --git a/RELEASING.md b/RELEASING.md index c44cf95773..c1824afea2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -39,7 +39,7 @@ node scripts/prepare-python-release.mjs # prints one "name: old -> new" line ### PRs opened by these workflows > [!NOTE] -> Both workflows push their PR's branch with the workflow token, and a push made with that token starts no workflow, so each one then dispatches the TypeScript, Python and DCO workflows on that branch, and Version Packages the Everything diff too (`workflow_dispatch` is the one event the token can start; the Python stamps touch nothing the diff runs on). A PR does not list dispatched checks, so each dispatched run also reports itself on the PR's head commit as a status: `TypeScript (dispatched)`, `Python (dispatched)` and `DCO (dispatched)`, plus `Everything diff (dispatched)` on Version Packages; wait for them to pass before merging. Closing and reopening the PR does not start the CI workflows: that fires `pull_request`, and those run on `push`. The token's `pull_request` events do not run DCO or the diff either: GitHub holds those runs as `action_required` (#5173), so the PR may also list them as pending or failed with no jobs; the `(dispatched)` statuses are the results. To run one again by hand: `gh workflow run typescript.yml --ref ` (or `python.yml`, `dco.yml`, `everything-mcp-diff.yml`). The Version Packages PR's body is rewritten on every push to `v2/main`, so it is linked to the release issue with `addCloseIssueReferences` (which lives outside the body), carries a `Part of #N` comment as its textual record, and gets `Part of #N` as its body's first line only immediately before it is merged. The repository setting **Settings → Actions → General → Allow GitHub Actions to create and approve pull requests** must be on, or the workflows fail at the step that opens the PR. +> Both workflows push their PR's branch with the workflow token, and a push made with that token starts no workflow, so each one then dispatches the TypeScript, Python and DCO workflows on that branch, and Version Packages the Everything diff too (`workflow_dispatch` is the one event the token can start; the Python stamps touch nothing the diff runs on). A PR does not list dispatched checks, so each dispatched run also reports itself on the PR's head commit as a status: `TypeScript (dispatched)`, `Python (dispatched)` and `DCO (dispatched)`, plus `Everything diff (dispatched)` on Version Packages; wait for them to pass before merging. Closing and reopening the PR does not start the CI workflows: that fires `pull_request`, and those run on `push`. The token's `pull_request` events do not run DCO or the diff either: GitHub holds those runs as `action_required` (#5173), so the PR may also list them as pending or failed with no jobs; the `(dispatched)` statuses are the results. To run one again by hand: `gh workflow run typescript.yml --ref ` (or `python.yml`, `dco.yml`, `everything-mcp-diff.yml`). The Version Packages PR's body is rewritten on every push to `v2/main`, so it is linked to the release issue with `addCloseIssueReferences` (which lives outside the body), carries a `Part of #N` comment as its textual record, and gets `Part of #N` as its body's first line only immediately before it is merged. The Prepare Python Release PR keeps its `Closes #N` line and is linked to the release issue with `addCloseIssueReferences` too, as every PR into `v2/main` is. The repository setting **Settings → Actions → General → Allow GitHub Actions to create and approve pull requests** must be on, or the workflows fail at the step that opens the PR. ## How publishing works @@ -78,7 +78,7 @@ A release ships one **milestone**. The step-by-step procedure, with its commands 2. **Preparation PRs land on `v2/main`**, each starting with `Closes #`: - the **audit** (`npm audit`, and `pip-audit` over each Python server's locked requirements): the report goes on the release issue, and any fix it forces is its own commit in a PR; - the **Version Packages** PR (TypeScript), which is linked to the release issue with `addCloseIssueReferences` and a `Part of #N` comment, and gets `Part of #N` as its body's first line just before merging, because the changesets action rewrites its body on every push; - - the **Prepare Python Release** PR (Python). + - the **Prepare Python Release** PR (Python), which keeps its `Closes #N` line and is also linked to the release issue with `addCloseIssueReferences`, since on `v2/main` a closing keyword is only a cross-reference. A milestone that touches both languages and needs an audit fix has all three. They are merged before the next step starts. 3. **The merge PR** takes `v2/main` into `main`. It is a pure merge: its branch is `origin/v2/main` with no commits of its own, and the merged tree equals `origin/v2/main`'s. Its body starts with `Part of #`, not `Closes`, because `main` is the default branch and a closing keyword there would close the issue before anything is published. It is merged with a merge commit, never squashed.