Skip to content

Commit 113863b

Browse files
Replace release target with PR-based release flow (#553)
* Replace release target with prepare-release and create-github-release - prepare-release: validates version, bumps files, runs pre-release-check, commits to release/X.Y.Z branch, pushes, and opens a PR via gh pr create - create-github-release: creates GitHub Release with auto-generated notes (--generate-notes) which triggers the PyPI publish workflow - Avoids direct pushes to master Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Document new PR-based release process in DEVELOPMENT.rst Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Run pre-release-check before bumping version files in prepare-release If pre-release-check fails, the working tree remains clean and no manual rollback is needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Use Unreleased section in CHANGES.rst for development workflow - CHANGES.rst: add empty Unreleased section at the top - Makefile: prepare-release checks for Unreleased section and renames it to the release version; no need to know the version during development - DEVELOPMENT.rst: document that PRs should add entries under Unreleased Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 30d4f4a commit 113863b

3 files changed

Lines changed: 74 additions & 12 deletions

File tree

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
Changelog
22
=========
33

4+
Unreleased
5+
----------
6+
47
0.14.1
58
------
69

DEVELOPMENT.rst

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,46 @@ Makefile targets
2020
* ``make run-coverage`` - run code coverage (pytest-cov)
2121
* ``make pypi-html`` - generates single HTML documentation into ``pypi-doc.html``
2222
* ``make html`` - generates HTML documentation similar to RTFD into folder ``_build/html/``
23-
* ``make release`` - creates new release as well as git tag
23+
* ``make prepare-release VERSION='1.2.3'`` - bumps version files, runs full pre-release checks, and opens a PR from a ``release/1.2.3`` branch
24+
* ``make create-github-release VERSION='1.2.3'`` - after the PR is merged, creates a GitHub Release with auto-generated notes, triggering PyPI publish
25+
26+
Releasing a New Version
27+
-----------------------
28+
29+
**During development** — as each PR is merged, add a bullet point describing the
30+
change under the ``Unreleased`` section at the top of ``CHANGES.rst``::
31+
32+
Unreleased
33+
----------
34+
35+
* Add support for foo - `PR 123`_
36+
37+
.. _PR 123: https://github.com/martin-majlis/Wikipedia-API/pull/123
38+
39+
**When ready to release:**
40+
41+
1. From a clean ``master`` branch, run::
42+
43+
make prepare-release VERSION='1.2.3'
44+
45+
This will:
46+
47+
* Validate the version format and that it is greater than the current version
48+
* Check that ``CHANGES.rst`` has an ``Unreleased`` section
49+
* Run the full pre-release check suite (tests, type checks, linting, examples)
50+
* Create a ``release/1.2.3`` branch
51+
* Rename ``Unreleased`` → ``1.2.3`` in ``CHANGES.rst`` and bump all version files
52+
* Commit, push the branch, and open a pull request
53+
54+
2. Review and merge the pull request.
55+
56+
3. After the PR is merged, create the GitHub Release::
57+
58+
make create-github-release VERSION='1.2.3'
59+
60+
This creates a ``v1.2.3`` tag and GitHub Release with auto-generated release
61+
notes (based on merged PRs since the last release), which triggers the
62+
``release.yml`` workflow to publish the package to PyPI.
2463

2564
Usage Statistics
2665
----------------

Makefile

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ BUILDDIR = _build
1212
help:
1313
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
1414

15-
.PHONY: help Makefile run-type-check run-tests extract-vcr-json
15+
.PHONY: help Makefile prepare-release create-github-release run-type-check run-tests extract-vcr-json
1616

1717
process-readme:
1818
awk '/^.. PYPI-BEGIN$$/,/^.. PYPI-END$$/ {next} {print}' README.rst > README_processed.rst
@@ -102,9 +102,18 @@ update-pre-commit:
102102
pre-release-check: run-pre-commit run-type-check run-ruff run-coverage run-tox run-example-sync run-example-async run-validate-attributes-mappping
103103
echo "Pre-release check was successful"
104104

105-
release: requirements-build process-readme pre-release-check
106-
if [ "x$(MSG)" = "x" -o "x$(VERSION)" = "x" ]; then \
107-
echo "Use make release MSG='some msg' VERSION='1.2.3'"; \
105+
prepare-release:
106+
@if [ "x$(VERSION)" = "x" ]; then \
107+
echo "Use make prepare-release VERSION='1.2.3' [MSG='optional PR context']"; \
108+
exit 1; \
109+
fi; \
110+
current_branch=`git rev-parse --abbrev-ref HEAD`; \
111+
if [ "x$$current_branch" != "xmaster" ]; then \
112+
echo "prepare-release must be run from master (currently on $$current_branch)"; \
113+
exit 1; \
114+
fi; \
115+
if [ -n "`git status --porcelain`" ]; then \
116+
echo "Working tree is not clean. Commit or stash your changes first."; \
108117
exit 1; \
109118
fi; \
110119
version=`grep '^__version__ = ' wikipediaapi/_version.py | sed -E 's/.*= \( *(.*), *(.*), *(.*)\)/\1.\2.\3/'`; \
@@ -136,23 +145,34 @@ release: requirements-build process-readme pre-release-check
136145
echo "New version has to be greater"; \
137146
exit 2; \
138147
fi; \
139-
has_documentation=`grep -c "^$(VERSION)\\$$" CHANGES.rst`; \
140-
if [ $$has_documentation -eq 0 ]; then \
141-
echo "There is no information about $(VERSION) in CHANGES.rst"; \
148+
has_unreleased=`grep -c "^Unreleased\\$$" CHANGES.rst`; \
149+
if [ $$has_unreleased -eq 0 ]; then \
150+
echo "No 'Unreleased' section found in CHANGES.rst"; \
142151
exit 3; \
143152
fi; \
153+
make pre-release-check; \
144154
short_VERSION=`echo $(VERSION) | cut -f1-2 -d.`; \
145155
commas_VERSION=`echo $(VERSION) | sed -E 's/\./, /g'`; \
146156
echo "Short version: $$short_VERSION"; \
157+
git checkout -b release/$(VERSION); \
158+
sed -i.bak 's/^Unreleased$$/$(VERSION)/' CHANGES.rst && rm CHANGES.rst.bak && \
147159
sed -i.bak -E 's/^version =.*/version = "'$(VERSION)'"/' pyproject.toml && rm pyproject.toml.bak && \
148160
sed -i.bak -E 's/^release = .*/release = "'$(VERSION)'"/' conf.py && rm conf.py.bak && \
149161
sed -i.bak -E 's/^version = .*/version = "'$$short_VERSION'"/' conf.py && rm conf.py.bak && \
150162
sed -i.bak -E 's/^__version__ = .*/__version__ = ('"$$commas_VERSION"')/' wikipediaapi/_version.py && rm wikipediaapi/_version.py.bak; \
151163
make build-package check-package && \
152-
git commit .github CHANGES.rst pyproject.toml uv.lock conf.py wikipediaapi/_version.py -m "Update version to $(VERSION) for new release." && \
153-
git push && \
154-
git tag v$(VERSION) -m "$(MSG)" && \
155-
git push --tags origin master
164+
git commit CHANGES.rst pyproject.toml uv.lock conf.py wikipediaapi/_version.py -m "Update version to $(VERSION) for new release." && \
165+
git push -u origin release/$(VERSION) && \
166+
pr_body="Release $(VERSION)"; \
167+
if [ -n "$(MSG)" ]; then pr_body="$$pr_body\n\n$(MSG)"; fi; \
168+
gh pr create --title "Release $(VERSION)" --body "$$pr_body"
169+
170+
create-github-release:
171+
@if [ "x$(VERSION)" = "x" ]; then \
172+
echo "Use make create-github-release VERSION='1.2.3'"; \
173+
exit 1; \
174+
fi
175+
gh release create v$(VERSION) --title "v$(VERSION)" --generate-notes
156176

157177

158178
build-package: process-readme

0 commit comments

Comments
 (0)