Continuous delivery isn't just for web applications, it's valuable to be able to quickly get feedback from real users for any kind of software project. Also, I'm lazy, so automating the release process for any software to the point that I only have to merge a branch into master is great.
I recently set up continuous deployment of my npTDMS Python package to PyPI (the Python package index) using Wercker. Wercker is a continuous integration and deployment solution built on Docker. You build your code inside a Docker container and can specify a Docker image to use that contains the build dependencies for your project. This Docker image can come from any public or private registry, so you can use your own Docker image and have complete control over the build environment. I created a Python image containing everything needed to build and test my library and hosted it on Docker Hub. The Dockerfile looks like this:
FROM ubuntu:14.04 RUN sudo apt-get update && \ sudo apt-get install -y \ python3 python3-numpy python3-setuptools python3-nose python3-pandas \ python python-numpy python-setuptools python-nose python-pandas \ pep8 python-pip python-wheel
This Dockerfile lives in a git repository on GitHub. Any commits to this repository trigger a new Docker image build using Docker Hub's auto-build feature.
wercker.yml I set the Docker image to use, pointing it at my
image on Docker Hub:
The test section in my
wercker.yml defines what to run to build and test my code,
and looks like:
build: steps: - script: name: PEP8 Check code: | pep8 ./nptdms - script: name: Test on Python 2.7 code: | python2.7 setup.py install nosetests - script: name: Test on Python 3 code: | python3 setup.py install nosetests3
This tells Wercker to run pep8 to check code style, then run tests on Python 2.7 and Python 3 using nose.
Wercker lets you define deployment steps and you can optionally enable
automatic deployment from specific branches after successful builds.
The deployment step in my
wercker.yml file is pretty simple, it looks like this:
deploy: steps: - script: name: Deploy to PyPI code: | echo "[pypirc] servers = pypi [server-login] username:$PYPI_USER password:$PYPI_PASSWORD" > ~/.pypirc python setup.py sdist upload python setup.py bdist_wheel upload
This simply configures my PyPI credentials then runs the commands to upload a new release
as a source package and a Python wheel.
PYPI_PASSWORD variables are configured in the Wercker UI and are kept secret.
Now after any successful build on master, Wercker will automatically deploy a new release to PyPI!
One thing to note with this approach is that PyPI will reject an upload of a new release if the version number has not changed, so if you enable automatic deployment from your master branch, you should ensure any pull request into that branch increments the version number. Remember to follow semantic versioning!
wercker.yml file for npTDMS can be found in the