Python Semantic Release

Test Status PyPI Version conda-forge Version Read the Docs Status

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

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.

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:

  1. Update changelog file.
  2. Run semantic-release version.
  3. Push changes to git.
  4. Run build_command and upload the distribution file to your repository.
  5. Run semantic-release changelog and post to your vcs provider.
  6. 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.