mkrelease is a no-frills Python package releaser. It is designed to take the cumber out of building and distributing Python packages. The releaser supports source distributions, eggs, and wheels.
After preparing a package for release (update version strings, dates) we typically have to:
- Commit modified files.
- Tag the release.
- Build a source distribution and wheel.
- Distribute the results via scp or upload them to an index server.
If we are doing this a lot, the need for automation becomes obvious.
- Installation
- Usage
- Options
- Arguments
- Configuration
- Upload with SCP
- Upload to Index Servers
- Using GnuPG
- Requirements
- Footnotes
- Related
- Changelog_
mkrelease works with Python >= 3.7 and all recent versions of setuptools.
Use pip install jarn.mkrelease
to install the mkrelease
script.
Since version 4.4 mkrelease requires twine for register and upload operations. Twine may be installed as a global utility on the system PATH or into the same environment as jarn.mkrelease. [1]
Use pip install jarn.mkrelease[twine]
to install mkrelease + twine.
Since version 5.0 file-finder extensions are no longer installed by default.
If you still want to use file-finders specify the filefinder
extra.
Use pip install jarn.mkrelease[filefinder]
to install mkrelease + file-finder
extensions.
Use pip uninstall setuptools-subversion setuptools-hg setuptools-git
to
uninstall file-finder extensions.
mkrelease [options] [scm-sandbox|scm-url [rev]]
-C, --no-commit
- Do not commit modified files from the sandbox.
-T, --no-tag
- Do not tag the release in SCM.
-P, --no-push
- Do not push commits and tags upstream.
-R, --no-register
- Do not register the release with dist-location.
-S, --no-upload
- Do not upload the release to dist-location.
-n, --dry-run
- Dry-run; equivalent to
-CTPRS
. This flag turns mkrelease into a simple package builder. --svn, --hg, --git
- Select the SCM type. Only required if the SCM type cannot be guessed from the argument.
-d dist-location, --dist-location=dist-location
- An scp destination specification, an index
server configured in
~/.pypirc
, or an alias name for either. This option may be specified more than once. -s, --sign
- Sign the release with GnuPG.
-i identity, --identity=identity
- The GnuPG identity to sign with. Implies
-s
. -z, --zip
- Release a zip archive.
-g, --gztar
- Release a tar.gz archive (default).
-b, --egg
- Release a binary egg.
-w, --wheel
- Release a wheel file (default).
-m, --manifest-only
- Ignore setuptools file-finder extensions and collect files via
MANIFEST.in
only. -e, --develop
- Allow setuptools build tags. Implies
-T
. -q, --quiet
- Suppress output of setuptools commands.
-t twine, --twine=twine
- Override the twine executable used.
-c config-file, --config-file=config-file
- Use config-file instead of the default
~/.mkrelease
. -l, --list-locations
- List known dist-locations and exit.
-h, --help
- Print the help message and exit.
-v, --version
- Print the version string and exit.
--no-color
- Disable output colors.
--non-interactive
- Do not prompt for username and password if the required credentials are missing.
scm-sandbox
- A local SCM sandbox. Defaults to the current working directory.
scm-url [rev]
- The URL of a remote SCM repository. The optional
rev
argument specifies a branch or tag to check out.
mkrelease reads available index servers from the distutils configuration
file ~/.pypirc
. This file should contain your PyPI account information: [2]
[distutils]
index-servers =
pypi
[pypi]
repository = https://upload.pypi.org/legacy/
username = fred
password = secret
Next, mkrelease reads its own configuration file ~/.mkrelease
.
It may be used to change defaults and to define location
aliases:
[mkrelease]
# Release steps
commit = yes
tag = yes
push = yes
register = no
upload = yes
# One or more of: zip gztar egg wheel
formats = gztar wheel
# Setuptools options
manifest-only = yes
develop = no
quiet = no
# Sign with GnuPG
sign = no
identity =
# Default dist-location
dist-location =
[aliases]
# Map name to one or more dist-locations
customerA =
jarn.com:/var/dist/customerA/
public =
jarn.com:/var/dist/public/
world =
pypi
public
The simplest distribution location is a server directory reachable by ssh. Releasing a package means scp-ing it to the appropriate place on the server:
$ mkrelease -d customerA $ mkrelease -d jarn.com:/var/dist/customerB/ $ mkrelease -d scp://jarn.com/var/dist/customerC/ $ mkrelease -d [email protected]:eggs -C -e -q
To upload via sftp instead of scp, use the sftp
URL scheme:
$ mkrelease -d sftp://jarn.com/var/dist/customerD/
Note: Unlike scp, the sftp client does not prompt for login credentials. This means that non-interactive login must be configured on the destination server or the upload will fail.
Another way of publishing a Python package is by uploading it to a dedicated
index server like PyPI.
Given the ~/.pypirc
file from above, we can release to PyPI simply by typing:
$ mkrelease -d pypi
Index servers are not limited to PyPI though.
There is TestPyPI, and there are alternative index servers like
devpi.
We extend our ~/.pypirc
: [2]
[distutils]
index-servers =
pypi
testpypi
[pypi]
repository = https://upload.pypi.org/legacy/
username = fred
password = secret
[testpypi]
repository = https://test.pypi.org/legacy/
username = fred
password = secret
We can now release to TestPyPI with:
$ mkrelease -d testpypi -C -e
Release a package and sign the distributions with GnuPG:
$ mkrelease -d pypi -s -i [email protected]
The -i
flag is optional and GnuPG will pick your default
key if not given.
The following commands must be available on the system PATH (you only need what you plan to use):
- svn
- hg
- git
- scp
- sftp
- gpg
- twine [1]
[1] | (1, 2) The twine executable is determined by trying in order:
|
[2] | (1, 2) There are more secure ways to handle login credentials:
|
Also see our Python documentation viewer jarn.viewdoc.