Skip to content

Commit d062de9

Browse files
committed
docs: add release process to contributing guide
1 parent 2689398 commit d062de9

1 file changed

Lines changed: 130 additions & 0 deletions

File tree

docs/contributing.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,133 @@ Before you submit a pull request, check that it meets these guidelines:
159159
feature to the list in the next release notes.
160160
3. Consider adding yourself to the contributor's list.
161161
4. The pull request should work for all supported Python versions.
162+
163+
## Releasing a New Version
164+
165+
This project uses [git-flow](https://github.com/nvie/gitflow) for release management and
166+
publishes to PyPI automatically via GitHub Actions when a version tag is pushed.
167+
168+
### Prerequisites
169+
170+
- You must be on the `develop` branch with a clean working tree.
171+
- `git-flow` must be installed and initialized:
172+
173+
```shell
174+
brew install git-flow # macOS
175+
git flow init # use main for production, develop for next release
176+
```
177+
178+
- All changes intended for the release must already be merged into `develop`.
179+
180+
### Step-by-step release process
181+
182+
The following steps use version `X.Y.Z` as a placeholder. Replace it with the actual version
183+
number (e.g., `2.6.0`).
184+
185+
#### 1. Start the release branch
186+
187+
```shell
188+
git checkout develop
189+
git pull origin develop
190+
git flow release start X.Y.Z
191+
```
192+
193+
This creates and switches to a `release/X.Y.Z` branch based on `develop`.
194+
195+
#### 2. Bump the version number
196+
197+
Update the version string in **both** files:
198+
199+
- `pyproject.toml` — the `version` field under `[project]`
200+
- `statemachine/__init__.py` — the `__version__` variable
201+
202+
#### 3. Update translations
203+
204+
Extract new translatable strings, merge them into all existing `.po` files, translate the
205+
new entries, and compile:
206+
207+
```shell
208+
uv run pybabel extract statemachine -o statemachine/locale/statemachine.pot
209+
uv run pybabel update -i statemachine/locale/statemachine.pot -d statemachine/locale/ -D statemachine
210+
# Edit each .po file to translate new empty msgstr entries
211+
uv run pybabel compile -d statemachine/locale/ -D statemachine
212+
```
213+
214+
```{note}
215+
The `.pot` and `.mo` files are git-ignored. Only the `.po` source files are committed.
216+
The compiled `.mo` files may cause test failures if your system locale matches a translated
217+
language (error messages will appear translated instead of in English). Delete them after
218+
verifying translations work: `rm -f statemachine/locale/*/LC_MESSAGES/statemachine.mo`
219+
```
220+
221+
#### 4. Write release notes
222+
223+
Create `docs/releases/X.Y.Z.md` documenting all changes since the previous release. Include
224+
sections for new features, bugfixes, performance improvements, and miscellaneous changes.
225+
Reference GitHub issues/PRs where applicable.
226+
227+
Add the new file to the toctree in `docs/releases/index.md` (at the top of the appropriate
228+
major version section).
229+
230+
Update any related documentation pages (e.g., if a bugfix adds a new behavior that users
231+
should know about).
232+
233+
#### 5. Run linters and tests
234+
235+
```shell
236+
uv run ruff check .
237+
uv run ruff format --check .
238+
uv run mypy statemachine/
239+
uv run pytest -n auto
240+
```
241+
242+
All checks must pass before committing.
243+
244+
#### 6. Commit
245+
246+
Stage all changed files and commit. The pre-commit hooks will run ruff, mypy, and pytest
247+
automatically.
248+
249+
```shell
250+
git add <files>
251+
git commit -m "chore: prepare release X.Y.Z"
252+
```
253+
254+
#### 7. Finish the release
255+
256+
```shell
257+
git flow release finish X.Y.Z -m "vX.Y.Z"
258+
```
259+
260+
This will:
261+
- Merge `release/X.Y.Z` into `main`
262+
- Create an annotated tag `X.Y.Z` on `main`
263+
- Merge `main` back into `develop`
264+
- Delete the `release/X.Y.Z` branch
265+
266+
```{note}
267+
If tagging fails (e.g., GPG or editor issues), create the tag manually and re-run:
268+
`git tag -a X.Y.Z -m "vX.Y.Z"` then `git flow release finish X.Y.Z -m "vX.Y.Z"`.
269+
```
270+
271+
#### 8. Update the `latest` tag and push
272+
273+
```shell
274+
git tag latest -f
275+
git push origin main develop --tags -f
276+
```
277+
278+
Force-pushing tags is needed to move the `latest` tag.
279+
280+
#### 9. Verify the release
281+
282+
The tag push triggers the `release` GitHub Actions workflow (`.github/workflows/release.yml`),
283+
which will:
284+
285+
1. Check out the tag
286+
2. Run the full test suite
287+
3. Build the sdist and wheel with `uv build`
288+
4. Publish to PyPI using trusted publishing
289+
290+
Monitor the workflow run at `https://github.com/fgmacedo/python-statemachine/actions` to
291+
confirm the release was published successfully.

0 commit comments

Comments
 (0)