Integrating Packagr with Github and Travis CI
How to use Travis CI to deploy your private Python packages to Packagr
In the last tutorial in this series, we looked at how to use Gitlab CI to package your Python code and upload it to Packagr whenever you push new code to your repository. In this tutorial, we are going to look at how to achieve the exact same thing using GitHub and Travis CI.
Setting up your repository
Let’s start by creating a fresh GitHub repository — just click on the big Start project button, and give your repository a name. For the purpose of this example, I created a project called packagr-project, which you can see here.
Important: If you don’t have a paid Travis CI account, then you must create a public Github project
Next, let’s sign up for TravisCI, by clicking on the big Sign up button and logging in with your Github credentials. From there, go to your Settings and you should see a list of all your Github repositories. To enable Travis CI for our new repository, just flip the switch next to its name:
Finally, if you don’t already have a Packagr account, you’ll need to sign up for one. Make a note of your repository URL for later, which you can find by clicking on the Create new package link at the top of the interface
We’re now ready to start writing some code
The folder structure
Clone your Github repository to your local machine, and let’s get started by creating a simple folder structure like the following:
The folder my-package
can be called anything-this is where your actual Python code should live. For the purposes of this tutorial, we’ll just create an extremely simple Python function that returns a “hello,world!” response. Let’s add the following code to the hello.py
file:
def hello(*args, **kwargs):
return 'Hello, world!'
Next, let’s take a look at our setup.py
file. This file defines how our package is built. It should look like this:
from setuptools import setupsetup(name='my-package', version='0.1.0')
We now have the minimum basic code to create a Python package
Testing out the upload
Before we go any further, let’s try and package our code and upload the package to Packagr, just to ensure that everything is working as it should. Open a terminal window from the root folder of your repository, and enter the following four commands, replacing the URL with your own Packagr URL that we made a note of earlier
pip install twine wheel
python setup.py sdist bdist_wheel
cd dist
twine upload --repository-url https://api.packagr.app/63cdQSDO/ *
You’ll be prompted for your Packagr credentials at this stage — once you’ve entered them correctly, the package will upload and you’ll see your new package in the Packagr interface:
Managing versions
Let’s see what happens when we try to execute that last command one more time:
$ twine upload --repository-url https://api.packagr.app/63cdQSDO/ *
Enter your username: christopherdavies553@gmail.com
Enter your password:
Uploading distributions to https://api.packagr.app/63cdQSDO/
Uploading my_package-0.1.0-py3-none-any.whl
100%|███████████████████████| 3.57k/3.57k [00:00<00:00, 8.38kB/s]
HTTPError: 409 Client Error: Conflict for url: https://api.packagr.app/63cdQSDO/
This time, although we didn’t change anything, the upload fails with a 409 error code. This is because we’ve attempted to upload the same package with the same version number. If you change the version number in your setup.py
file as follows, then recreate the package and reupload it, it should work again:
from setuptools import setupsetup(name='my-package', version='0.2.0')
However, having to manually change the version number every time you push code to your repository is going to get boring very quickly. In order to get around this problem, we can use Git tags to update our package version. These tags are available to Travis CI during the build process via the TRAVIS_TAG
environmental variable. So let’s update our setup.py
file to dynamically set the version number at run time, like this:
from setuptools import setup
import osversion = os.environ['TRAVIS_TAG']setup(name='my-package', version=version)
Configuring Travis CI
When you push code to your Travis-connected Github repository, Travis looks for a file called .travis.yml
, which defines the steps taken on pushing your code. Let’s add this file to the root folder of our repository now:
language: python
python:
- "3.6"
script:
- python setup.py bdist_wheel
deploy:
provider: pypi
user: $PACKAGR_USERNAME
password: $PACKAGR_PASSWORD
server: $PACKAGR_REPOSITORY_URL
on:
tags: true
Let’s break this down a bit:
- The
script
parameter creates our package - The
deploy
stage uses thepypi
provider, but defines custom values forserver
,user
andpassword
- The
on
condition means that the deployment will only be run on tagged commits
The server
, user
and password
have been added as environmental variables — for security reasons, you should never include credentials in version control. However, we need to define these environmental variables in Travis in order for them to work. This can be done by clicking the Settings button next to the relevant repository in TravisCI:
Pushing your code
We’re now ready to go! Let’s commit our files, tag the commit and push it with the following commands:
git add my-package/hello.py setup.py
git tag 1.0.0
git push --tags
This should push your code to your GitHub repository, which in turn will trigger the Travis process (as this is a tagged commit). You can monitor the status of your TravisCI build through the interface — if it all goes well, it will eventually complete and turn green, like this:
The package should also now be visible in Packagr:
That’s it! In future, all your tagged commits will repackage your code on Packagr