# Opens the PR that stamps today's CalVer date (e.g. 2026.8.1) onto each Python # server that changed since its last version bump (#4472). Dispatched by a # maintainer when preparing a release; the logic, and why Python stays on # CalVer, is in `scripts/prepare-python-release.mjs`. # # It is the Python counterpart of the changesets "Version Packages" PR: the # version changes in a reviewed PR on the develop branch, and nothing is # published until a maintainer publishes a GitHub Release (`release.yml`). # # The PR targets the branch the workflow was dispatched on, which is `v2/main` # in the normal flow. It is one of a release's preparation PRs, so it follows # the same rules as any other PR here: its body opens with `Closes #N` for the # milestone's release issue (the `issue` input), its branch is named for that # issue, and it is labeled `v2`. The link is only a cross-reference on # `v2/main`; the release issue stays open until the Release is published. name: Prepare Python Release on: workflow_dispatch: inputs: issue: description: "The release issue this PR belongs to (its number, e.g. 4930)" required: true type: string jobs: prepare: timeout-minutes: 10 if: github.repository_owner == 'modelcontextprotocol' runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: # The ref this was dispatched on becomes the PR's base, and every PR # targets `v2/main`. A run from `main` would open a version PR straight # against the release branch, around the milestone merge. - name: Refuse a dispatch from any branch but v2/main run: | if [ "$GITHUB_REF" != "refs/heads/v2/main" ]; then echo "::error::Dispatch this workflow on v2/main, not $GITHUB_REF." exit 1 fi # Full history: the script finds each package's last version bump with # `git log`, and a shallow clone would make every package look new. - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-node@v7 with: node-version: 22 # The script runs `uv lock` in each package it stamps. - name: Install uv uses: astral-sh/setup-uv@v7 - name: Stamp CalVer versions run: node scripts/prepare-python-release.mjs > "$RUNNER_TEMP/stamped.txt" - name: Check for changes id: changes run: | if git diff --quiet; then echo "No Python package needs a version stamp" echo "changed=false" >> "$GITHUB_OUTPUT" else echo "changed=true" >> "$GITHUB_OUTPUT" fi - name: Create pull request if: steps.changes.outputs.changed == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BASE: ${{ github.ref_name }} ISSUE: ${{ inputs.issue }} run: | # The input is free text; only a bare issue number may reach the # branch name and the PR body. case "$ISSUE" in '' | *[!0-9]*) echo "issue must be a number, got: '$ISSUE'" >&2; exit 1 ;; esac DATE=$(date -u +%Y.%-m.%-d) BRANCH="v2/chore/$ISSUE-python-calver-$DATE" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git checkout -b "$BRANCH" git add -u git commit -m "chore: stamp Python CalVer versions for $DATE" git push --force origin "$BRANCH" { echo "Closes #$ISSUE" echo echo "Stamps today's CalVer date onto the Python packages that changed since their last version bump:" echo sed 's/^/- /' "$RUNNER_TEMP/stamped.txt" echo echo "Generated by the **Prepare Python Release** workflow. Nothing is published until a maintainer publishes a GitHub Release." echo echo "> [!NOTE]" echo "> A PR opened with the workflow token does not trigger CI. Close and reopen this PR to run it." } > "$RUNNER_TEMP/pr-body.md" # A second run on the same day force-updates the branch, and may # stamp a different set of packages; the open PR's body is rewritten # to match what the branch now holds. EXISTING=$(gh pr list --head "$BRANCH" --state open --json number --jq '.[0].number // empty') if [ -n "$EXISTING" ]; then gh pr edit "$EXISTING" --body-file "$RUNNER_TEMP/pr-body.md" echo "PR #$EXISTING for $BRANCH was already open; its branch and body were updated" else gh pr create \ --base "$BASE" \ --head "$BRANCH" \ --label v2 \ --title "chore: stamp Python CalVer versions for $DATE" \ --body-file "$RUNNER_TEMP/pr-body.md" fi