When building, deploying, or testing with continuous integration (CI) systems (e.g. GitHub Actions, Travis CI, AppVeyor, and others), one often needs to download and install a set of R packages before the service can be run. Normally, one will have to download and reinstall these packages on each build, which can often be slow – especially in environments where binary packages are not available from your R package repositories.
renv can often be helpful in these situations. The
general idea is:
Call
renv::snapshot()on your local machine, to generaterenv.lock;Call
renv::restore()on your CI service, to restore the project library fromrenv.lock;Ensure that the project library, as well as the global
renvcache, are cached by the CI service.
Normally, renv will use the R package repositories as
encoded in renv.lock during restore, and this will override
any repositories set in other locations (e.g. in .Rprofile
or .Rprofile.site). We’ll discuss some strategies for
providing an alternate R package repository to use during restore
below.
GitHub Actions
When using GitHub Actions, you typically need two steps:
- Cache any packages installed by
renv, - Use
renv::restore()to restore packages.
As an example, these steps might look like:
env:
RENV_PATHS_ROOT: ~/.local/share/renv
steps:
- name: Cache packages
uses: actions/cache@v1
with:
path: ${{ env.RENV_PATHS_ROOT }}
key: ${{ runner.os }}-renv-${{ hashFiles('**/renv.lock') }}
restore-keys: |
${{ runner.os }}-renv-
- name: Restore packages
shell: Rscript {0}
run: |
if (!requireNamespace("renv", quietly = TRUE)) install.packages("renv")
renv::restore()
See also the example on GitHub actions.
Travis CI
On Travis CI, one can add the following entries to
.travis.yml to accomplish the above:
cache:
directories:
- $HOME/.local/share/renv
- $TRAVIS_BUILD_DIR/renv/library
install:
- Rscript -e "if (!requireNamespace('renv', quietly = TRUE)) install.packages('renv')"
- Rscript -e "renv::restore()"
script:
- Rscript -e '<your-build-action>'
Note that we provide both install and
script steps, as we want to override the default behaviors
provided by Travis for R (which might attempt to install different
version of R packages than what is currently encoded in
renv.lock). See https://docs.travis-ci.com/user/languages/r/#customizing-the-travis-build-steps
for more details.
It’s also possible to override the package repository used during
restore by setting the RENV_CONFIG_REPOS_OVERRIDE
environment variable. For example:
env:
global:
- RENV_CONFIG_REPOS_OVERRIDE=<cran>
replacing <cran> with your desired R package
repository. This can also be accomplished in a similar way by
setting:
options(renv.config.repos.override = <...>)
but it is generally more ergonomic to set the associated environment
variable. (See ?config for more details.) This can be
useful if you’d like to, for example, enforce the usage of a MRAN checkpoint during restore, or
another similarly-equipped repository.
See https://docs.travis-ci.com/user/caching for more details on how Travis manages caching.
GitLab CI
The following template can be used as a base when using
renv with GitLab
CI:
variables:
RENV_CONFIG_REPOS_OVERRIDE: "http://cran.r-project.org"
RENV_PATHS_CACHE: ${CI_PROJECT_DIR}/cache
RENV_PATHS_LIBRARY: ${CI_PROJECT_DIR}/renv/library
cache:
key: ${CI_JOB_NAME}
paths:
- ${RENV_PATHS_CACHE}
- ${RENV_PATHS_LIBRARY}
before_script:
- < ... other pre-deploy steps ... >
- Rscript -e "if (!requireNamespace('renv', quietly = TRUE)) install.packages('renv')"
- Rscript -e "renv::restore()"