| name | release |
| description | Release a new djoser version - review the diff since the last release, write the changelog entry, bump the version, verify everything locally, and prepare the tag for the user to push |
Release a new djoser version
Prepare and verify a release end-to-end. The user's git push origin X.Y.Z
is the only action that triggers anything external: the tag push starts the
Release workflow (validate → test matrix → build → PyPI → GitHub release).
Never push the tag yourself. Never run uv publish or gh release create
manually — CI does that.
Work through the stages in order. Do not skip a verification because it
"probably passes"; the whole point of this skill is that the release is
checked before the tag exists.
1. Establish scope
git fetch origin and make sure the local master matches
origin/master with a clean working tree.
- Find the last release:
LAST_TAG=$(git describe --tags --abbrev=0 origin/master).
- Review everything since then:
git log --oneline $LAST_TAG..origin/master
and the full git diff $LAST_TAG..origin/master. Read the diff, not just
the commit subjects — changelog entries must describe user-facing behavior,
and commit messages sometimes undersell or oversell what changed.
- Summarize the user-facing changes for the user and agree on the new
version number:
- patch = bug fixes, minor = backwards-compatible features,
major = breaking changes
- a PEP 440 pre-release suffix (
a1, b1, rc1) publishes to PyPI like
any other version, but pip/uv never resolve to it without --pre or an
exact pin; suggest one first when the diff is large or risky. Write the
changelog entry under the final X.Y.Z heading — CI falls back to it for
the pre-release, and the changelog carries no pre-release sections.
- If there is nothing user-facing to release, say so and stop.
2. Prepare the release branch
git checkout -b release/X.Y.Z origin/master
- Set the version in
pyproject.toml ([project] version), then run
uv lock — the lockfile records the project's own version and the CI
lock-file check fails if it is stale.
- Update
CHANGELOG.rst:
- new section at the top, matching the existing format exactly:
overline/underline dashes,
`X.Y.Z`_ (YYYY-MM-DD) heading, *
bullets with issue/PR links
- a
.. _X.Y.Z: https://github.com/sunscrapers/djoser/compare/PREV...X.Y.Z
link definition at the bottom
- every notable change found in stage 1 must be reflected; nothing in the
entry may be missing from the diff
- the CI extracts this section verbatim as the GitHub release notes, and
fails a stable release if the section is missing
docs/source/changelog.rst includes this file, so the entry is also
published on Read the Docs — there is no second place to edit, but the
entry must be valid RST (escape **kwargs -style markup) or the
docs build warns and renders it wrong
- Show the changelog entry to the user and get approval before continuing.
3. Verify locally
Run all of these; all must pass:
make test — full suite
make run-hooks — pre-commit checks (needs .venv/bin on PATH)
make build — translations compile and the package builds
uv lock --check — lockfile consistent with pyproject.toml
make docs — the docs build, including the rendered changelog entry;
it must not add new warnings
Report the results honestly; a failure here aborts the release until fixed.
4. Land the bump on master
- Commit
pyproject.toml, uv.lock and CHANGELOG.rst as
Bump version to X.Y.Z.
- Push the branch and open a PR against
master; wait for the user to
merge it (the repo squash-merges).
- After the merge:
git fetch origin and confirm origin/master now
carries the bump (uv version --short on that commit equals X.Y.Z).
5. Tag and hand over
- Tag the merged commit:
git tag X.Y.Z origin/master — tags are bare
X.Y.Z, no v prefix, matching every historical djoser tag (stable tags
must point at a commit on master — CI enforces this).
- Do NOT push the tag. Tell the user to run:
git push origin X.Y.Z
- Point them at the Actions tab to watch the
Release workflow. If it
fails, the fix path is: correct the problem, git push --delete origin X.Y.Z, delete the local tag, and re-run this skill's relevant stages.