Skip to content

Commit 6876ea8

Browse files
committed
docs(release): generalize RELEASE.md to be version-agnostic + drop one-time scaffolding
Cleans up RELEASE.md after the v0.1.5/v0.1.6 release wave. Three structural fixes that together cut the file from 205 to 114 lines: 1. Collapse the duplicate "Creating a Release" + "v0.1.1 Release Checklist" sections into one canonical "Release Checklist" using an X.Y.Z placeholder. Maintainers replace X.Y.Z with the version they are releasing. 2. Replace hardcoded versions (0.1.1, 0.1.2) and `<owner>` template URLs with X.Y.Z placeholders and the actual repo URL. The two surviving numeric references (0.1.7 as the example version; v0.1.5 → v0.1.6 as historical context for the mcp-publisher-validate step) are intentional. 3. Drop the "Post-PyPI Launch Pack Cleanup" section entirely. That work (PRE-PYPI fence strip, docs/launch/ submission paths, manual MCP Registry submission) was a one-time scaffolding for the PyPI debut. PRE-PYPI fences are gone from README; MCP Registry publish is now automated by the release workflow; docs/launch/ is not tracked. Preserves from earlier work: - The mcp-publisher validate check added in PR #35. - The Trusted Publishing one-time setup steps. - Coverage notes (Python 3.13 release matrix; docs 3.10–3.14). Adds: - Lockstep version check across all four files (pyproject.toml + server.json:11 + server.json:17 + uv.lock). - Cache-bust step in fresh-install verification (lesson from v0.1.6 where uvx returned stale 0.1.5 until --refresh-package). - MCP Registry isLatest check via JSON API.
1 parent 2532244 commit 6876ea8

1 file changed

Lines changed: 51 additions & 141 deletions

File tree

.github/RELEASE.md

Lines changed: 51 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -2,203 +2,113 @@
22

33
## One-Time Setup: PyPI Trusted Publishing
44

5-
Before the first release, configure PyPI Trusted Publishing:
5+
Already configured for this project — these steps are kept for reference when forking or recovering the publisher state.
66

77
1. Go to https://pypi.org/manage/account/publishing/
8-
2. Add a new pending publisher:
8+
2. Add a publisher (pending or active):
99
- **PyPI project name**: `python-docs-mcp-server`
10-
- **Owner**: your GitHub username or org
10+
- **Owner**: your GitHub username or org (this repo: `ayhammouda`)
1111
- **Repository**: `python-docs-mcp-server`
1212
- **Workflow name**: `release.yml`
1313
- **Environment name**: `pypi`
1414
3. In the GitHub repo, go to Settings > Environments
1515
4. Create an environment named `pypi`
1616
5. (Optional) Add environment protection rules:
17-
- Required reviewers (recommended for first release)
17+
- Required reviewers (recommended)
1818
- Deployment branches: only `main` tags
1919

20-
## Notes
20+
## Coverage notes
2121

22-
**Runtime coverage:** The release workflow builds and tests against Python 3.13 only.
23-
Python 3.12 is covered by the CI workflow (`ci.yml`) which runs a 2x2 matrix
24-
(3.12/3.13 x ubuntu/macos) on every push to `main`. Since tags are created
25-
from commits that have already passed CI, 3.12 compatibility is verified before
26-
the release workflow runs. This is an accepted trade-off to keep the release
27-
artifact pipeline simple (single Python version produces the wheel).
22+
**Runtime coverage:** the release workflow builds and tests against Python 3.13 only. Python 3.12 is covered by the CI workflow (`ci.yml`), which runs a 2×2 matrix (3.12/3.13 × ubuntu/macos) on every push to `main`. Since tags are created from commits that have already passed CI, 3.12 compatibility is verified before the release workflow runs. This is an accepted trade-off to keep the release artifact pipeline simple (single Python version produces the wheel).
2823

29-
**Documentation coverage:** The full docs index target is Python documentation
30-
versions 3.10 through 3.14.
24+
**Documentation coverage:** the full docs index target is Python documentation versions 3.10 through 3.14.
3125

32-
## Creating a Release
26+
---
3327

34-
1. Ensure all tests pass on main:
35-
```bash
36-
uv run pytest --tb=short -q
37-
uv run ruff check src/ tests/
38-
uv run pyright src/
39-
```
28+
## Release Checklist
4029

41-
2. Verify the version in `pyproject.toml` is correct:
42-
```bash
43-
grep '^version' pyproject.toml
44-
# Should show: version = "0.1.2"
45-
```
46-
47-
3. Create and push the tag:
48-
```bash
49-
git tag -a v0.1.2 -m "Release v0.1.2"
50-
git push origin v0.1.2
51-
```
52-
53-
4. Monitor the release workflow at:
54-
https://github.com/<owner>/python-docs-mcp-server/actions/workflows/release.yml
55-
56-
5. Verify the package on PyPI:
57-
https://pypi.org/project/python-docs-mcp-server/0.1.2/
58-
59-
## Post-Release Verification
60-
61-
After the package is published:
62-
63-
```bash
64-
# In a fresh environment:
65-
uvx python-docs-mcp-server --version
66-
# Should print: 0.1.1
67-
68-
# Or via pipx:
69-
pipx run python-docs-mcp-server --version
70-
# Should print: 0.1.1
71-
```
72-
73-
## v0.1.1 Release Checklist
74-
75-
Complete these steps in order. Each step has a checkbox -- do not skip ahead.
30+
Replace `X.Y.Z` below with the version you are releasing (e.g. `0.1.7`). Complete each step in order; do not skip ahead. The release workflow at `.github/workflows/release.yml` runs four jobs in sequence on every `v*` tag push: `build``publish` (PyPI) → `publish-mcp-registry``github-release`.
7631

7732
### Pre-Release Verification
7833

79-
- [ ] All CI tests green on main: check https://github.com/<owner>/python-docs-mcp-server/actions/workflows/ci.yml
34+
- [ ] All CI tests green on `main`: https://github.com/ayhammouda/python-docs-mcp-server/actions/workflows/ci.yml
8035
- [ ] Local test suite passes:
8136
```bash
8237
uv run pytest --tb=short -q
38+
uv run ruff check src/ tests/
39+
uv run pyright src/
8340
```
84-
- [ ] Version in `pyproject.toml` is `0.1.1`:
41+
- [ ] All four version-bearing files agree on `X.Y.Z` (the release workflow's `Verify tag matches package version` step enforces this; matching here saves a CI round-trip):
8542
```bash
8643
grep '^version' pyproject.toml
44+
python3 -c 'import json; d = json.load(open("server.json")); print("server.json:", d["version"], "/ packages[0]:", d["packages"][0]["version"])'
45+
grep '^name = "python-docs-mcp-server"' -A1 uv.lock | head -2
8746
```
8847
- [ ] `server.json` validates against the live MCP Registry schema. MCP Registry enforces stricter limits than PyPI (e.g. `description ≤ 100 chars`); validating before the tag prevents a half-published release (PyPI succeeds while MCP Registry rejects, as happened on v0.1.5 → recovered in v0.1.6):
8948
```bash
9049
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
9150
./mcp-publisher validate server.json
9251
```
93-
Must report `✅ server.json is valid`. If validation fails, shorten the `server.json` `description` on `main` before tagging (the `pyproject.toml` description is unbounded by this constraint and can stay longer).
52+
Must report `✅ server.json is valid`. If validation fails, shorten `server.json` `description` on `main` before tagging (the `pyproject.toml` description is unbounded by this constraint and can stay longer).
9453
- [ ] Integration tests from `.github/INTEGRATION-TEST.md` are complete and signed off
95-
- [ ] Doctor subcommand passes:
54+
- [ ] `Doctor` subcommand passes:
9655
```bash
9756
uv run python-docs-mcp-server doctor
9857
```
99-
100-
### PyPI Trusted Publishing Setup (one-time)
101-
102-
- [ ] PyPI pending publisher configured at https://pypi.org/manage/account/publishing/:
103-
- PyPI project name: `python-docs-mcp-server`
104-
- Owner: `<your-github-username>`
105-
- Repository: `python-docs-mcp-server`
106-
- Workflow name: `release.yml`
107-
- Environment name: `pypi`
108-
- [ ] GitHub environment `pypi` created in repo Settings > Environments
58+
- [ ] `CHANGELOG.md` has a dated entry for `[X.Y.Z]`
10959

11060
### Tag and Release
11161

112-
- [ ] Create the annotated tag:
62+
- [ ] Create the annotated tag (replace `X.Y.Z` everywhere):
11363
```bash
114-
git tag -a v0.1.1 -m "Release v0.1.1
115-
116-
First public release of python-docs-mcp-server.
64+
git tag -a vX.Y.Z -m "Release vX.Y.Z
11765
118-
A read-only, version-aware MCP retrieval server over Python
119-
standard library documentation (3.10 through 3.14).
66+
<one-line summary of what shipped>
12067
121-
Installable via: uvx python-docs-mcp-server"
68+
See CHANGELOG.md for the full entry."
12269
```
12370
- [ ] Push the tag to trigger the release workflow:
12471
```bash
125-
git push origin v0.1.1
72+
git push origin vX.Y.Z
73+
```
74+
- [ ] Watch the workflow run to completion:
75+
```bash
76+
gh run watch $(gh run list --workflow=release.yml --limit 1 --json databaseId -q '.[0].databaseId') --exit-status
12677
```
127-
- [ ] Monitor the workflow run: https://github.com/<owner>/python-docs-mcp-server/actions/workflows/release.yml
128-
- [ ] Verify all three jobs pass: `build` -> `publish` -> `github-release`
78+
- [ ] All four jobs green: `build``publish``publish-mcp-registry``github-release`
12979

130-
### Post-Release Verification (SHIP-06)
80+
### Post-Release Verification
13181

132-
- [ ] Package visible on PyPI: https://pypi.org/project/python-docs-mcp-server/0.1.2/
133-
- [ ] Attestation visible on PyPI package page (look for "Provenance" badge)
134-
- [ ] Fresh install test:
82+
- [ ] PyPI listing exists with attestation badge: `https://pypi.org/project/python-docs-mcp-server/X.Y.Z/`
83+
- [ ] Fresh install test from a clean shell (cache-busted so the new version actually resolves):
13584
```bash
136-
# Clear any cached version
13785
uv cache clean python-docs-mcp-server 2>/dev/null || true
138-
139-
# Install and verify version
140-
uvx python-docs-mcp-server --version
141-
# Expected output: 0.1.1
86+
uvx --refresh python-docs-mcp-server@X.Y.Z --version
87+
# Expected: python-docs-mcp-server X.Y.Z
14288
```
143-
- [ ] Full README flow test (from a clean environment):
89+
- [ ] Full install flow:
14490
```bash
145-
# Step 1: Install
146-
uvx python-docs-mcp-server --version
147-
# Should print 0.1.1
148-
149-
# Step 2: Build index
15091
uvx python-docs-mcp-server build-index --versions 3.10,3.11,3.12,3.13,3.14
151-
# Should complete successfully
152-
153-
# Step 3: Doctor check
15492
uvx python-docs-mcp-server doctor
155-
# All checks should PASS
15693
```
157-
- [ ] Slow E2E workflow passes:
158-
- Run GitHub Actions workflow `Slow E2E`
159-
- Confirm Python 3.13 and Python 3.14 jobs both pass
160-
- Confirm each job installs the built wheel, runs
161-
`build-index --versions 3.10,3.11,3.12,3.13,3.14`, `doctor`, and
162-
`validate-corpus`
163-
164-
### Post-PyPI Launch Pack Cleanup
165-
166-
- [ ] Remove every temporary PyPI pre-release block from `README.md`:
167-
- Mechanical pass: delete every region from `<!-- PRE-PYPI:` to `<!-- /PRE-PYPI -->` (inclusive). Each block now encloses its surrounding heading + lead-in sentence + code, so a single pass produces a clean README.
168-
- Reference command:
169-
`perl -0777 -i -pe 's/<!-- PRE-PYPI:.*?<!-- \/PRE-PYPI -->\n*//gs' README.md`
170-
- Make the published package commands (`uvx python-docs-mcp-server ...`) the
171-
primary install, build-index, MCP client, `doctor`, and `validate-corpus`
172-
examples
173-
- [ ] Verify `README.md` has no temporary pre-release install artifacts:
94+
Both must complete successfully.
95+
- [ ] MCP Registry shows `X.Y.Z` as the `isLatest` entry:
17496
```bash
175-
rg -n 'PRE[-]PYPI|Before PyPI publishing|Until the first PyPI|After PyPI publishing|git\\+https://github.com/.*/python-docs-mcp-server' README.md
97+
curl -s 'https://registry.modelcontextprotocol.io/v0.1/servers?search=python-docs-mcp-server' | \
98+
python3 -c "import json,sys; d=json.load(sys.stdin); print(next((e['server']['version'] for e in d['servers'] if e['_meta']['io.modelcontextprotocol.registry/official']['isLatest']), 'no latest'))"
17699
```
177-
The command should return no output.
178-
- [ ] Review `docs/launch/` so no public launch copy still asks users to install
179-
from GitHub source after the PyPI package is available. Intentional historical
180-
pre-release drafts may remain, but they must stay clearly labeled as
181-
pre-PyPI-only.
182-
- [ ] Submit `server.json` to https://registry.modelcontextprotocol.io/ via the
183-
`mcp-publisher` CLI after the PyPI smoke test passes; verify the registry
184-
listing appears and points at version 0.1.1
185-
- [ ] Use the post-PyPI draft in `docs/launch/show-hn.md` for the HN submission
186-
- [ ] Use `docs/launch/reddit-posts.md` for the r/Python and r/LocalLLaMA
187-
submissions after the PyPI release smoke test passes
188-
- [ ] Commit and push the README cleanup before public launch posts go out
189-
190-
- [ ] Claude Desktop test with published package:
191-
Configure `mcpServers` with `uvx python-docs-mcp-server` and verify
192-
"what is asyncio.TaskGroup" returns a correct hit
100+
- [ ] GitHub Release exists at `https://github.com/ayhammouda/python-docs-mcp-server/releases/tag/vX.Y.Z` with wheel + sdist attached and auto-generated notes
101+
- [ ] **Slow E2E workflow** passes (manually triggered after publish):
102+
- Run GitHub Actions workflow `Slow E2E` (`.github/workflows/e2e.yml`)
103+
- Python 3.13 and 3.14 jobs both pass
104+
- Each job installs the built wheel and runs `build-index --versions 3.10,3.11,3.12,3.13,3.14`, `doctor`, and `validate-corpus`
105+
- [ ] Claude Desktop manual smoke test:
106+
Configure `mcpServers` with `uvx python-docs-mcp-server` and verify a known query (e.g. "what is asyncio.TaskGroup") returns a correct hit.
193107

194108
### Release Complete
195109

196-
- [ ] GitHub Release exists with attached artifacts
197-
- [ ] PyPI page shows 0.1.1 with attestation
198-
- [ ] README install instructions verified end-to-end
199-
- [ ] README no longer contains temporary pre-PyPI GitHub-source install blocks
200-
- [ ] Slow E2E workflow passed for the release candidate
201-
- [ ] Tag v0.1.1 exists in git
202-
203-
**Release date**: _______________
204-
**Released by**: _______________
110+
- [ ] All four `release.yml` jobs green for `vX.Y.Z`
111+
- [ ] PyPI page shows `X.Y.Z` with the "Provenance" attestation badge
112+
- [ ] MCP Registry `isLatest` entry points at `X.Y.Z`
113+
- [ ] GitHub Release `vX.Y.Z` exists with both dist artifacts attached
114+
- [ ] `CHANGELOG.md` `[X.Y.Z]` entry is committed on `main`

0 commit comments

Comments
 (0)