Skip to content

Commit bee0e16

Browse files
MNT: add Claude Code skill for cutting RocketPy releases
Documents the streamlined single-PR-to-master release flow so version bumps and changelog updates follow the established REL: pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 642d920 commit bee0e16

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
---
2+
name: rocketpy-release
3+
description: >-
4+
Cut a new RocketPy release: prepare the version-bump branch, update the
5+
changelog and all version references, and guide the PR-to-master + PyPI flow.
6+
Use when the user wants to release a new version (e.g. "release v1.13",
7+
"fazer um release", "bump version and cut a release", "REL PR").
8+
---
9+
10+
# RocketPy Release
11+
12+
Prepare and guide a RocketPy version release following the team's established
13+
`REL:` pattern. This skill prepares the branch and the version-bump commit; the
14+
human opens the PR and publishes the GitHub Release themselves.
15+
16+
## Branching model
17+
18+
RocketPy uses **`develop`** (integration) and **`master`** (released). All
19+
feature/fix work lands on `develop`. A release promotes `develop``master`.
20+
21+
Since **v1.12.0** the team uses a **single streamlined PR** (see PR #935):
22+
one `rel/vX.Y.Z` branch — created off `develop`, with the version already
23+
bumped — opened **straight to `master`**. (Older releases used three PRs; do
24+
NOT revive that.)
25+
26+
PyPI is published automatically by `.github/workflows/publish-to-pypi.yml` when
27+
a **GitHub Release is published** (`on: release: [published]`). Creating the
28+
release/tag in the GitHub UI is the final manual trigger.
29+
30+
## Before you start — gather state
31+
32+
Run these and confirm with the user:
33+
34+
```bash
35+
git fetch origin
36+
grep -m1 '^version' pyproject.toml # current version
37+
git show origin/master:pyproject.toml | grep -m1 '^version' # released version
38+
git rev-list --left-right --count origin/master...origin/develop # ahead/behind
39+
git tag --sort=-creatordate | head -5 # last tags
40+
```
41+
42+
Confirm the **target version** (semver: MAJOR.MINOR.PATCH) with the user before
43+
touching files. Never guess the number.
44+
45+
## Step 1 — Create the release branch
46+
47+
Branch off the latest `develop`:
48+
49+
```bash
50+
git checkout develop && git pull origin develop
51+
git checkout -b rel/vX.Y.Z
52+
```
53+
54+
## Step 2 — The version-bump commit
55+
56+
Update **every** version reference. These have been missed before (e.g.
57+
`installation.rst` sat stale at 1.11.0 through 1.12.x) — check all of them:
58+
59+
| File | What to change |
60+
|------|----------------|
61+
| `pyproject.toml` | `version = "X.Y.Z"` |
62+
| `docs/conf.py` | `release = "X.Y.Z"` and `copyright = "<year>, RocketPy Team"` |
63+
| `docs/user/installation.rst` | `pip install rocketpy==X.Y.Z` |
64+
| `CHANGELOG.md` | see below |
65+
66+
Sanity-sweep for any other stragglers (ignore `.venv`):
67+
68+
```bash
69+
grep -rn "<OLD_VERSION>" --include=*.py --include=*.toml --include=*.rst . \
70+
| grep -v '.venv'
71+
```
72+
73+
### CHANGELOG.md
74+
75+
The changelog `[Unreleased]` section is auto-populated on every merge to
76+
`develop` by `.github/workflows/changelog.yml`, so entries should already be
77+
present. To release:
78+
79+
1. Rename the current `## [Unreleased] - yyyy-mm-dd` header to
80+
`## [vX.Y.Z] - YYYY-MM-DD` (today's date).
81+
2. Insert a **fresh empty** `[Unreleased]` block above it, preserving the
82+
template comment and empty subsections:
83+
84+
```markdown
85+
## [Unreleased] - yyyy-mm-dd
86+
87+
<!-- These are the changes that were not released yet, please add them correctly.
88+
Attention: The newest changes should be on top -->
89+
90+
### Added
91+
92+
### Changed
93+
94+
### Fixed
95+
```
96+
3. Add a `Changed` entry to the released section for the bump itself:
97+
`- REL: bumps up rocketpy version to X.Y.Z [#PR](https://github.com/RocketPy-Team/RocketPy/pull/PR)`
98+
(fill the PR number after the PR is opened, or leave a placeholder to edit).
99+
4. Prune obvious noise if the maintainer wants (tests, CI, merge commits are
100+
not meant to be in the changelog per the file's own header comment).
101+
102+
### Commit
103+
104+
Match the historical message style (`REL: bump version to X.Y.Z`):
105+
106+
```bash
107+
git add pyproject.toml docs/conf.py docs/user/installation.rst CHANGELOG.md
108+
git commit -m "REL: bumps up rocketpy version to X.Y.Z"
109+
```
110+
111+
Keep it to **one** bump commit. Do not include unrelated changes.
112+
113+
## Step 3 — Push and hand off the PR
114+
115+
```bash
116+
git push -u origin rel/vX.Y.Z
117+
```
118+
119+
**Stop here and let the human open the PR** (team preference — they open it
120+
themselves). Give them the ready-to-use details:
121+
122+
- **Base:** `master`**Compare:** `rel/vX.Y.Z`
123+
- **Title:** `REL: vX.Y.Z` (or `Rel/vX.Y.Z`)
124+
- **Body:** summarize the highlights; note the single-PR-to-master approach.
125+
126+
## Step 4 — After the PR merges (guide the human)
127+
128+
1. **Sync `master` back into `develop`** so develop carries the new version and
129+
the merge history. Historically a PR titled like
130+
`MNT: update develop to release vX.Y.Z`, base `develop` ← compare `master`.
131+
2. **Create the GitHub Release** in the UI: new tag `vX.Y.Z` targeting
132+
`master`, title `vX.Y.Z`, paste the changelog section as notes, Publish.
133+
→ This triggers `publish-to-pypi.yml` and ships to PyPI.
134+
3. Verify the PyPI publish workflow succeeded and the new version is live.
135+
136+
## Guardrails
137+
138+
- Only prepare the branch + bump commit. **Do not open the PR or publish the
139+
release** unless the user explicitly asks — they do those steps themselves.
140+
- Confirm the target version with the user before editing.
141+
- Base the PR on **`master`**, not `develop`.
142+
- One clean `REL:` commit; no unrelated edits.

0 commit comments

Comments
 (0)