Transitioning to CircleCI from Github Actions
I recently updated all JaxGaussianProcesses packages to use CircleCI for CI/CD. This post documents my experiences with this.
Why Run Continuous Integration and Continuous Deployment
Setting up CircleCI
Setting up CircleCI is straightforward. You simply create an account using your
Github account and then add the repository you want to use. You can then create
a .circleci folder in the root of your repository and add a config.yml file.
This file contains the configuration for your CI/CD pipeline. To start with, my
file took the following form:
| |
One complication came in that JaxKern stores its dependencies in the setup.py
file, not the requirements.txt file. It seems most CircleCI documentation
assumes the latter structure. To resolve this and install the dev requirements
from your setup.py file, simply replace the python/install-packages step
with the following:
| |
A further nuance is that to use JAX versions greater than 0.4.0, as we do in
JaxKern, you need a pip version greater than the one given in
cimg/python:3.8.0. To resolve this, I simply added the following step:
| |
Customising the CI/CD Pipeline
Continuous Deployment
Continuous deployment is wonderfully helpful. When a set of rules are met, the code is automatically deployed to PyPI. This means that you can be confident that the code on PyPI is always up to date. This is particularly useful for packages that are used by other packages. For example, JaxKern is used by GPJax. If JaxKern is not up to date on PyPI, then GPJax will not work.
To add this into your CircleCI config file, add the following job
| |
There’s a lot here, so let’s unpack it. We first create a .pypirc file. This
file contains the credentials for uploading to PyPI. We then build the package
and upload it to PyPI. The --verbose flag is useful for debugging. If you have
multiple PyPI accounts, you can add them to the .pypirc file. For example, I
have a PyPI account for JaxKern and a PyPI account for my personal projects. I
can add both to the .pypirc file and then upload to the correct account by
specifying the -r or --repository flag.
Note: The environment variables used above i.e., JAXKERN_PYPI and PYPI_TOKEN are set in the CircleCI environment variables, not Github. To set
them, go to the project settings in CircleCI and then click on the Environment Variables tab. You can then add the variables there. The variables themselves
are the API tokens for the PyPI accounts. You can create these tokens in your
personal token setting.
The coverage report generated by pytest is also uploaded to CircleCI. This is achieved by adding the codecov orb to the config.yml file:
| |
Before adding the following chunk to the build-and-test job:
| |
Note - you’ll also need to make an environmental variable in CircleCI for the CODECOV_TOKEN. You can get this token from your Codecov settings.
To only build the package when a new tag is pushed, add the following to the workflows section of the config.yml file:
| |
In this chunk, the publish job is only run when a tag starting with v is pushed. This can be achieved by running
| |
The build-and-test job is required for the publish job to run.
Initial Observations
User Interface
The interface in CircleCI is nice. Compared to Github Actions, I find it much cleaner and easier to navigate. Whilst not critical, this is a nice improvement.
Triggering Workflows
Once a repository is added to CircleCI, it will automatically trigger a workflow for every commit to a branch containing .circleci/config.yml. This is a nice feature, as it means that you can test your CI/CD pipeline before merging it into the main branch.
Builds can be manually triggered through the CircleCI web interface.
Local Testing
I always struggled to run Github actions locally. However, running CircleCI locally was a breeze. On my linux machine I installed CircleCI and Docker and connected the two through the following
| |
You then must authenticate yourself with CircleCI by adding your API token. You can create an API token in your personal token setting. Once this is done, add the token to your CircleCI CLI by running
| |