How to do Linux and Mac Continuous Integration for Python
Continuous integration allows the whole build, test, and release pipeline to be automated so you have more time to code / sleep. I recently started using it in all my open source projects and for a while I couldn’t seem to find a way to get both linux and mac integration working properly for Python. I managed to look through a bunch of other peoples .yml files and find an answer.
We will be using Travis-ci for this, this ci system uses yml files to set everything up, The file must be called ".travis.yml" and placed in the root of your project. yml files are weird and dont support tabbed indents so we will be using spaces instead.
We first need to specify our language and what operating systems we are going to use. We must use a matrix to specify that for the osx version we are using objective-c instead of python. For some reason if you choose python as the language for osx it fails to install python
language: python matrix: include: - os: linux language: python python: 3.5 - os: osx language: objective-c python: 3.5
So now that we've got it starting linux and osx we need to make sure python gets installed on osx. I used some simple logic to differentiate the linux and osx instructions because they varied somewhat.
before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ;fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python3 ;fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then python3 -V ;fi
For osx we need to use brew to install python3 or whatever version you're using. I used if statements so when the linux version runs through it doesnt do the osx steps.
Now we make our install logic, if you've packaged your code properly you can just use your setup.py
install: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then python setup.py build install ;fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then python3 setup.py build install;fi
Its important to note that the osx has to call python3 specificy if you installed the python 3.x package.
Now we can run our test code once the installation is finished.
script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then python setup.py test ;fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then python3 setup.py test ;fi
Now if you want you can make Travis-ci deploy your project to whatever package manager you want. In this I use pypi (pip). Now to do this on an open source project on github you should probably get your password hashed before putting it on the web. Its hashed with a specific salt linked to your account specifically so others cant deploy your code.
Learn how to secure your password here: https://docs.travis-ci.com/user/encryption-keys/
deploy: provider: pypi user: MyUserName distributions: sdist skip_cleanup: true password: secure: MyUniquePasswordHashed on: branch: master tags: true
For the distribution I used sdist so it uploads the source code to pypi instead of bdist which builds for the current os. when you download the package with pip it will build it for you so dont worry.
I set the target branch to master so it grabs from that branch and set tags to true. I did that so it only builds when you tag the commit and on github that means you made a release. Travis-ci will still build and test your code if you dont tag the commit and you can still tag commits on other branches without it deploying.
You're basically done and your .travis.yml file should look something like this, now you can just go to Travis-ci.org and link your repo and it will do the rest.




















