I’m working on a Python package right now that I want to make sure is properly tested. Previously I had been using Travis for this but their new pricing structure made me look for alternatives. In EMPress we recently switched to GitHub actions as it is free for public repos. However, when I looked at how it worked I was fairly confused at first.
One of the lead developers of EMPress was kind enough to walk me through EMPress’s main.yml
file but it still took me a bit to figure out the rest.
I’ve written a small walkthrough of how my own main.yml
file works in the hopes that it will help someone else (or me in the future).
The GitHub link to the file can be found here.
name: BIRDMAn CI
This is pretty self-explanatory - at the top level I have the name of the workflow as it appears on the repository page.
on:
pull_request:
branches:
- main
push:
branches:
- main
This block of code specifies when I want this workflow to be triggered.
For this project I want each PR and push to main
to run the workflow.
jobs:
build:
runs-on: ubuntu-latest
The project I’m working is designed for Linux/macOS so I’m going to focus on those testing environments.
The build
name can be anything - it’s just the name of the collection of instructions.
Here’s where things start to get a little hairier.
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: 0
The first step I list uses one of GitHub’s officially supported actions: checkout
This step checks out the project repository (here: gibsramen/BIRDMAn) so I can access the code.
Why this isn’t defaulted I’m not really sure - I guess since GH actions are extensible there are times when it wouldn’t make sense to do this first.
The persist-credentials
option doesn’t actually matter here (I think) - I just copied it from EMPress.
The fetch-depth
option specifies to get all the history.
- uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: birdman
python-version: 3.7
This block is where things started getting really confusing. I wanted to create a new conda environment to hold the dependencies so I use this action to specify the Python version. In the future I’d like to test things out with future versions but for the moment that’s not super important.
- name: Test conda installation
shell: bash -l {0}
run: conda info
One of the things that confused me most when writing this file was how to get the environment to persist.
In EMPress we use conda run
to specify that commands should be run with a given environment but that seems a bit clunky to me.
I think the shell: bash -l {0}
instruction allows me to use the conda environment we just created.
The login shell I’m pretty sure allows me to make use of the environment variables and stuff for using conda.
I use this command throughout the rest of the file but there’s likely a way to use it only once and have it persist.
Here, I just test that the conda installation works - if it does the build will show birdman
as the current environment.
- name: Install PyStan
shell: bash -l {0}
run: pip install pystan==3.0.0b7
- name: Install conda packages
shell: bash -l {0}
run: |
conda install -c conda-forge dask biom-format patsy pytest xarray scikit-bio
This is the block that installs the required packages for running BIRDMAn.
I first install a specific version of PyStan through pip
and then the rest through conda.
The version of PyStan I use is still in beta so it’s not yet on conda.
- name: Install BIRDMAn
shell: bash -l {0}
run: pip install -e .
This is just installing the BIRDMAn package locally so that I can test it.
For this reason I used checkout
above to get the actual code.
- name: Run tests
shell: bash -l {0}
run: pytest --disable-pytest-warnings
Finally, I run the unit tests I wrote to make sure things work. If all of the above tasks complete successfully, our workflow passes and we are good to go.
In the future I’ll probably add flake8
testing or other such stylistic checks.
I’ll also probably have to install node.js
if I end up making a visualization for model diagnostics.
That’s it for now! Hope this helps you use GitHub actions with conda (even if the person reading this is me in several months).