zest.releaser 4.0: major update
zest.releaser has a fresh 4.0 release, with some nice improvements. So, what's new?
zest.releaser 4.0 has various improvements. We have better errors and warnings, did some cleanup, added little tricks, and have a recommended list of extra packages to use in combination with zest.releaser: check-manifest, pyroma, wheel, and twine.
Main improvements
Errors and warnings
We are better at showing errors. This is especially true for errors when uploading to PyPI. They were unintentionally swallowed before, so you did not notice when an upload failed. Oops, sorry about that.
Errors and warnings are more noticeable, because we colorize them. Errors are red, warnings are magenta. We use the colorama package for this.
We not only do this for lines that are printed explicitly by zest.releaser itself, but try to do this also for output from programs that we call, like check-manifest and python setup.py. This is a bit tricky though. Program should print standard messages to the standard output file and errors and warnings to the standard error file. Not all do that. So we might be missing some colors.
We allow retrying some commands when there is an error. Currently this is only done for commands that talk to PyPI or another package index. We ask the user if she wants to retry: Yes, no, quit. If for example PyPI upload fails because you have the wrong credentials in your ~/.pypirc, you can edit this file and tell zest.releaser to retry the command.
Cleanup
Python 2.6 is not officially supported anymore. It will probably still work, but we are no longer testing against it, so issues may start creeping in. This says nothing about the packages that are created: zest.releaser on Python 2.7 is still perfectly capable of creating distributions for older Python versions. Or for Python 3.
Sorry, zest.releaser itself does not run on Python 3. At least I have not tried it, and certainly the tests will be a pain to fix for both 2 and 3.
We have removed code for support of collective.sdist. That package was a backport from distutils for Python 2.5 and earlier, which we do not support.
Little tricks
We do not accept y or n as answer for a new version. I saw that with a few packages, which seems an obvious mistake.
When doing a postrelease, we add a always edit the changelog file to get a new version section with the text '- Nothing changed yet'. Now, when you do a prerelease and no real changelog entry has been added, so the text is still there, we warn and ask if you really want a new release. Probably you want to stop, check your version control history, and add one or more proper changelog entries.
zest.releaser makes commits in the prerelease and postrelease phase. Something like Preparing release 1.0 and Back to development: 1.1. You can add extra text to these messages by configuration in your setup.cfg or global ~/.pypirc.
One nice use case for this is telling Travis or Jenkins to skip Continuous Integration builds, like this:
[zest.releaser] extra-message = [ci skip]
This depends on how your testing server is setup. It might not have this enabled, or it might be looking for a different message.
Of course, you can also add your favorite geeky quotes there:
[zest.releaser] extra-message = No one expects the Spanish inquisition! So long and thanks for all the fish.
recommended extra
We have a list of recommended extra packages that we think are helpful for most users of zest.releaser. This is in the zest.releaser[recommended] extra. So if you use pip, you can install those like this:
pip install zest.releaser[recommended]
With buildout, you would use a section like this:
[script] recipe = zc.recipe.egg dependent-scripts = true eggs = zest.releaser[recommended]
What is currently in this list? We have check-manifest, pyroma, wheel, and twine.
check-manifest
This checks if the distribution that zest.releaser will create of your package contains all the files that you expect to be there. In some cases your setup.py will contain enough information for Python to include the correct files. Or you rely on a helper like setuptools-git, but then you miss files when someone else who does not have this helper package makes the next release. So in a lot of cases you will want to use a MANIFEST.in file. As an example, zest.releaser itself currently has this:
recursive-include zest * recursive-include doc * include * exclude .installed.cfg global-exclude *.pyc
You can run check-manifest as a standalone command. When used in combination with zest.releaser, the prerelease part calls the check-manifest command for you. That may look like this:
$ fullrelease INFO: Starting prerelease. Do you want to run check-manifest? (Y/n)? listing source files under version control: 6 files and directories building an sdist: mauritstestpackage-0.2.dev0.tar.gz: 6 files and directories copying source files to a temporary directory building a clean sdist: mauritstestpackage-0.2.dev0.tar.gz: 5 files and directories files in version control do not match the sdist! missing from sdist: CHANGES.rst suggested MANIFEST.in rules: include *.rst MANIFEST.in is not in order. Do you want to continue despite that? (y/N)?
check-manifest may report some files as missing from the source distribution where you know this is fine. You can tell check-manifest to ignore those by adding a setup.cfg file next to your setup.py. ``zest.releaser`` itself currently has this:
[check-manifest] ignore = doc/build doc/build/*
We could add some more there, like bootstrap.py, buildout.cfg, and .travis.yml.
For more info on check-manifest, see its PyPI page: https://pypi.python.org/pypi/check-manifest
pyroma
This does various checks on your package. Most of them are about your setup.py. This results in a rating between zero (bad) and ten (good). The rating is also given with the name of a cheese. If your package 'smells' good, you get a better cheese. Where does the name of the package come from? It checks the aroma of your package: Python + aroma = pyroma.
You can run pyroma as a standalone command. When used in combination with zest.releaser, the prerelease part calls the pyroma command for you. That may look like this:
$ fullrelease INFO: Starting prerelease. Do you want to run check-manifest? (Y/n)? n Run pyroma on the package before tagging? (Y/n)? INFO: ------------------------------ INFO: Checking /Users/mauritsvanrees/own/mauritstestpackage INFO: Found mauritstestpackage INFO: ------------------------------ INFO: Your package does not have classifiers data. INFO: You should specify what Python versions you support. INFO: Your package does not have keywords data. INFO: Your package does not have author_email data. INFO: Setuptools and Distribute support running tests. By specifying a test suite, it's easy to find and run tests both for automated tools and humans. INFO: ------------------------------ INFO: Final rating: 6/10 INFO: Compté INFO: ------------------------------ Continue? (Y/n)? n
For more info on pyroma, see its PyPI page: https://pypi.python.org/pypi/pyroma
wheel
There are various package formats for Python. Until now, zest.releaser was only doing source distributions, by calling python setup.py sdist. We still do this. Note that we have never released binary eggs (bdist_egg).
wheels are the shiny new Python package distribution format. zest.releaser 4.0 supports creating them and pushing them to PyPI.
Should you want this? Maybe. See http://pythonwheels.com for deciding whether this is a good idea for your package. Briefly, if it is a pure Python 2 or pure Python 3 package: just do it.
Also, if you are using buildout: sorry, buildout currently (2.3.1) does not support wheels. It is fine to create them, but you should still create a source distribution as well. zest.releaser does that, like it always has.
Say you want zest.releaser to create a wheel. How do you do this? You add a setup.cfg file in the top level directory of your package, so next to setup.py:
[zest.releaser] create-wheel = yes
Or if you know you want this for all your packages, you can also do this globally by adding the same text in your ~/.pypirc.
zest.releaser then takes care of the rest: when releasing, it creates a plain old source distribution and a shiny new wheel and uploads them to the package index.
For more info on wheel, see its PyPI page: https://pypi.python.org/pypi/wheel
twine
Since version 4.0, we prefer twine for uploading to the Python Package Index, because it is safer: it uses https for uploading. If the twine command is available, it is used for uploading to PyPI.
Note that we call the twine command directly. If the twine command is not available, you may need to change your system PATH. In the case of buildout, you may need to say dependent-scripts = true in the section where you add the zest.releaser[recommended] egg.
How does it look? When I used zest.releaser to release itself, it looked like this:
INFO: This package is registered on PyPI. Register and upload to pypi (Y/n)? INFO: Running: twine upload dist/* -r pypi Uploading distributions to https://pypi.python.org/pypi Uploading zest.releaser-4.0-py2-none-any.whl Uploading zest.releaser-4.0.tar.gz
When your package is not registered yet on PyPI, twine will currently fail. So you have to register the package manually. Use your browser to login at PyPI and then use the package registration form.
We could consider letting zest.releaser call the old-style python setup.py register instead, or ask the user. If you have thoughts about this, you can use our issue tracker to start a discussion.
As an aside, did you know that there is a test website for the Python Package Index? You can use this for making test releases of packages. If you want to take zest.releaser for a test run and do not want to publish your package on the real PyPI yet, you can release to https://testpypi.python.org. Edit your ~/.pypirc file to something like this:
[distutils] index-servers = pypi testpypi [pypi] # default repository: https://pypi.python.org/pypi username:maurits password:secret [testpypi] repository:https://testpypi.python.org/pypi username:maurits password:secret
Then when running our fullrelease or release command, answer 'no' when zest.releaser asks if you want to upload to pypi and answer 'yes' when asked to upload to testpypi.
For more info on twine, see its PyPI page: https://pypi.python.org/pypi/twine
That's it. I hope you enjoyed reading about the improvements. Now go use it! Get it with pip install zest.releaser or pip install zest.releaser[recommended] at https://pypi.python.org/pypi/ or read more at http://zestreleaser.readthedocs.org