Python Semantic Release¶
Automatic Semantic Versioning for Python projects. This is a Python implementation of semantic-release for JS by Stephan Bönnemann. If you find this topic interesting you should check out his talk from JSConf Budapest.
The general idea is to be able to detect what the next version of the project should be based on the commits. This tool will use that to automate the whole release, upload to an artifact repository and post changelogs to GitHub. You can run the tool on a CI service, or just run it locally.
Installation¶
python3 -m pip install python-semantic-release
semantic-release --help
Python Semantic Release is also available from conda-forge or as a GitHub Action. Read more about the setup and configuration in our getting started guide.
Getting Started¶
If you haven’t done so already, install Python Semantic Release following the instructions above.
There is no strict requirement to have it installed locally if you intend on
using a CI service, however running with --noop
can be
useful to test your configuration.
Setting up version numbering¶
Create a variable set to the current version number. This could be anywhere in
your project, for example setup.py
:
from setuptools import setup
__version__ = "0.0.0"
setup(
name="my-package",
version=__version__,
# And so on...
)
Python Semantic Release is configured using setup.cfg
or pyproject.toml
.
Set version_variable to the location of your version variable inside any Python file:
setup.cfg
:
[semantic_release]
version_variable = setup.py:__version__
pyproject.toml
:
[tool.semantic_release]
version_variable = "setup.py:__version__"
See also
- version_toml - use tomlkit to read and update the version number in a TOML file.
- version_pattern - use regular expressions to keep the version number in a different format.
- version_source - store the version using Git tags.
Setting up commit parsing¶
We rely on commit messages to detect when a version bump is needed. By default, Python Semantic Release uses the Angular style. You can find out more about this on Parsing of commit logs.
See also
- branch - change the default branch.
- commit_parser - use a different parser for commit messages. For example, there is an emoji parser.
- upload_to_repository - disable uploading the package to an artifact repository.
- hvcs - change this if you are using GitLab.
Setting up the changelog¶
If you already have a CHANGELOG.md, you will need to insert a placeholder tag so we know where to write new versions:
<!--next-version-placeholder-->
If you don’t have a changelog file then one will be set up like this automatically.
See also
- changelog_file - use a file other than CHANGELOG.md.
- config-changelog_placeholder - use a different placeholder.
Releasing on GitHub / GitLab¶
Some options and environment variables need to be set in order to push release notes and new versions to GitHub / GitLab:
- hvcs - change this if you are using GitLab.
- GH_TOKEN - GitHub personal access token.
- GL_TOKEN - GitLab personal access token.
- GITEA_TOKEN - Gitea personal access token.
Distributing release on PyPI or custom repository¶
Unless you disable upload_to_repository (or upload_to_pypi),
Python Semantic Release will publish new versions to Pypi. Customization is supported using a
~/.pypirc
file or config setting and environment variables for username and password/token or a
combination of both.
Publishing is done using twine.
- repository - use repository and/or credentials from
~/.pypirc
file - repository_url - set custom repository url
- Artifact Repository - provide credentials using environment variables
- Configuring distribution upload - configuring CI distribution upload
Commands¶
semantic-release changelog
¶
Print the changelog to stdout.
If the option --post
is used and there is an authentication token configured
for your vcs provider (GH_TOKEN for GitHub, GL_TOKEN for
GitLab, GITEA_TOKEN for
Gitea), the changelog will be posted there too.
semantic-release version
¶
Figure out the new version number, update and commit it, and create a tag.
This will not push anything to any remote. All changes are local.
semantic-release print-version
¶
Print to standard output the new version number.
If the option --current
is used, it will display the current version number.
It can be used to retrieve the next version number in a shell script during the build, before running the effective release, ie. to rename a distribution binary with the effective version:
VERSION=$(semantic-release print-version)
semantic-release publish
¶
Publish will do a sequence of things:
- Update changelog file.
- Run semantic-release version.
- Push changes to git.
- Run build_command and upload the distribution file to your repository.
- Run semantic-release changelog and post to your vcs provider.
- Attach the files created by build_command to GitHub releases.
Some of these steps may be disabled based on your configuration.
Common Options¶
Every command understands these flags:
--patch
¶
Force a patch release, ignoring the version bump determined from commit messages.
--minor
¶
Force a minor release, ignoring the version bump determined from commit messages.
--major
¶
Force a major release, ignoring the version bump determined from commit messages.
--prerelease
¶
Makes the next release a prerelease, version bumps are still determined or can be forced, but the prerelease_tag (see prerelease_tag) will be appended to version number.
--noop
¶
No operations mode. Do not take any actions, only print what will be done.
--retry
¶
Retry the same release, do not bump.
--define
¶
Override a configuration value. Takes an argument of the format
setting="value"
.
--verbosity
¶
Change the verbosity of Python Semantic Release’s logging. See Showing debug output.
Running from setup.py¶
Add the following hook to your setup.py
and you will be able to run
python setup.py <command>
as you would semantic-release <command>
:
try:
from semantic_release import setup_hook
setup_hook(sys.argv)
except ImportError:
pass
Running on CI¶
Getting a fully automated setup with releases from CI can be helpful for some projects. See Automatic releases.