Continuous integration for R projects: from Travis CI to GitHub actions step by step
November 24, 2020
Continuous Integration Travis CI GitHub Actions R package
covr
pkgdown
usethis
Marie-Hélène Brice, Willian Vieira
Table of Contents
I have been using Travis CI (https://travis-ci.org/) since 2015 and GitHub Actions (hereafter GH Actions; https://github.com/features/actions) for over a year now1. While using these two hosted continuous integration services, I came to realize that I was spending less time troubleshooting with GH Actions than I was with Travis. For this reason, I am now setting GH Actions workflows for my new projects (mainly R and Julia projects) and slowly migrating older projects from Travis to GH Actions. Turns out that was the right move! Indeed, as Jeroen Ooms explains in his recent post Moving away from Travis CI, by next year, Travis will no longer be free for open source projects (see also), which gives me a good reason to speed up the migration process! As I was working on such migration recently, I felt that I should to share some notes about this!
inSilecoMisc as an example
The package I worked on was
inSilecoMisc
. Note that I have
already detailed elsewhere various features including in inSilecoMisc (e.g.
here and
there).
What matters here, is what was Travis CI doing for me. The screenshot below
shows the different jobs I set (described in
.travis.yml).
Travis was set to check inSilecoMisc
on macOS and Linux (Ubuntu Bionic and Focal), for different versions of R (oldrel, rel and devel). The last job, checked the package on Ubuntu Focal, uploaded covr
results to
CodeCov, built inSilecoMisc
’s website (via pkgdown
) and deploy to a GitHub Pages. So my goal was to set up a workflow with GitHub Actions that would do the same jobs.
Ciao Travis!
The first step was to stop using Travis CI. To do so, I first needed to go on
https://travis-ci.org and turn off the jobs described above, so I looked for inSilecoMisc
in my list of projects and switched it off (see screenshot below).
Then, as I was using a deploy
key for the
website, I deleted it in the settings on GitHub repository (). Last, on my local repository I removed .travis.yaml
(e.g. git rm .travis.yaml
). Note that I still have a version of this file as a
gist. Once
this was done, I committed my changes and pushed!
Add a workflow
GH Actions are well-documented and my
goal here is not to explain how to set an entire workflow. Rather I would like
to focus on certain part of the workflow. That said, one should keep in mind
that thanks to Docker images and the large diversity
of Actions available, GH Actions are powerful and extremely flexible. For R
users interested in using GH Actions to check their package, it is worth noting
that usethis
has several
functions to add such workflows:
|
|
The workflow I ended up using, R-CMD-check.yaml (appended at the end of the post) is based on one of the template file available in usethis
that I’ve simplified a bit (I use only 4 combinations OS / R versions) and extended to use the CodeCov and deploy the website.
Code coverage
To use CodeCov with Actions, a token is required. So, I clicked on the Settings
tab of the inSilecoMisc
page and copied the upload token:
Then I created a new secret CODECOV_TOKEN
on inSileco
’s GitHub repository and I pasted the token.
I chose CODECOV_TOKEN
because it’s pretty clear, but the name does not matter as long as the same variable name is used in R-CMD-check.yaml. Below is the code bloc in the workflow that handles code coverage:
|
|
Note that ${{secrets.CODECOV_TOKEN}}
returns the token value I set as a secret
above. Also, I used an if:
filed to upload the results of the code coverage
only once. I chose to do it on MacOS (for no specific reason) and I kept the
part matrix.config.r == 'release'
in case I would add another configuration
(currently, this is useless).
Website
Build
In order to build the package I simply install pkgdown
and use it to generates the HTML pages. Below is the code bloc I wrote for this:
|
|
There are a few lines that require some explanations. First, I decided to build this on Ubuntu (again, this is arbitrary). Second, the following line:
|
|
was required as dependencies were missing for
curl
and
textshaping
. Third, the two
last lines are two git operations that I used to retrieve te content of the
previous commit. I did so to be able to have both the “main” website at
https://insileco.github.io/inSilecoMisc/ and “dev” version at
https://insileco.github.io/inSilecoMisc/dev (this is detailed in another post
“Deploy a pkgdown website on gh-pages
manually”).
Deploy
To deploy the website to GitHub Pages, I used
peaceiris/actions-gh-pages
(version 3). There are two
ways to deploy the website that are well explained in the README of
peaceiris/actions-gh-pages
.
via a deploy key
For this, one needs to generate a pair of ssh keys. On my Debian machine, I used the following command line in my terminal:
|
|
Then I set the public key as a deploy key
and the private one as a secret.
Again, I chose ACTIONS_DEPLOY_KEY
for its clarity, but the name does not
matter as long as the correct variable name is used in
R-CMD-check.yaml.
|
|
I used publish_dir: ./docs
as this is where pkgdown
stores
stored the web pages in my case
(see the file
_pkgdown.yml).
Note that I didn’t need to specify the branch to be used for the website as
the default is gh-pages
and I already had a branch gh-pages
set up2.
via a personal access token
The second option is to create and use a personal access token (this is the solution I opted for in the end).
And then set this token as a secret for the repository.
Once the secret is set, the variable name should be passed as github_token
(instead of deploy_key
), like so:
|
|
Incidentally, organization secrets allow user to have secrets at the organisation level, so that the same token can be used for several repositories!
Everything is working fine now 🎆, check out inSilecoMisc
! Below is the entire workflow
Entire workflow
Below is the whole R-CMD-check.yaml file I ended using (note that for recent projects the default branch name is main
instead of master
).
|
|
Hope this could be of help 😄!
-
see my first post about GitHub Actions on my personal blog. ↩︎
-
Use
publish_branch: your-branch
to setyour-branch
as the branch were files will be published. ↩︎
Edits
May 21, 2021 -- Edit the tricks to keep both the versions of the website (dev and last releases).