Running steps conditionally

Steps and stages can be run conditionally using the control workflow of {tic}. Possible conditionals are

Common tasks to use this feature are testing on multiple R versions and the restriction of certain tasks that should only be executed once (e.g. the deployment of a {pkgdown} site).

Conditional execution: Use cases

The following shows some example code blocks to condition certain stages and their respective steps on

  • the R Version (using an environment variable)
# this env var already exists by default on Travis
# for other systems you need to set a custom env var in the CI YAML
if (ci_is_env("TRAVIS_R_VERSION_STRING", "release")) {
  get_stage("after_success") %>%
    add_step(step_...())
}
  • the CI service
if (ci_on_travis()) {
  get_stage("<stage>") %>%
    add_step(step_...())
}
  • a specific branch
if (ci_get_branch() == "main") {
  get_stage("<stage>") %>%
    add_step(step_...())
}

Installation of packages

Required packages are installed based on the “Depends”/“Imports”/“Suggests” fields of the DESCRIPTION file. You should only use the following steps in extraordinary circumstances. An example can be the use of a package in the README.Rmd file which is not listed within the package’s DESCRIPTION file.

GitHub packages

get_stage("install") %>%
  add_step(step_install_github("r-lib/rcmdcheck"))

Note that the underlying remotes::install_github() is vectorized for the repo argument which means you can pass all packages you want to install in a single function call:

add_step(step_install_github(c("r-lib/rcmdcheck", "r-lib/usethis")))

CRAN packages

get_stage("install") %>%
  add_step(step_install_cran("magick"))

CI Meta-Information

The ci() function and its friends (ci_*) hold valuable information about the CI system. They can be used to query information that can be again be utilized for conditioning stages or steps.

For example, the user may wish to only deploy on Travis CI by using ci_on_travis():

if (ci_on_travis()) {
  get_stage("before_deploy") %>%
    add_step(step_setup_ssh())

  get_stage("deploy") %>%
    add_step(step_push_deploy())
}

By using the code above, the specified steps will only be executed on Travis CI. See ?ci for more information on which CI build information can be extracted from this function.

Debugging: Running {tic} locally

Checking for syntax errors

Before pushing to GitHub and triggering a CI build, tic.R can be validated using dsl_load(). This function will source tic.R to check for possible problems. If everything is ok, it will return (invisibly) a list with all stages that will be run in the CI build. Here is a preview of the first two stages:

✔ Loading tic stage configuration from tic.R
dsl_get()[1:2]
$before_install
── before_install ──────────────────────────────────────── stage ──
ℹ No steps defined

$install
── install ─────────────────────────────────────────────── stage ──
▶ step_install_github("ropensci/rotemplate")
▶ step_install_deps(repos = repo_default())

Emulating a CI run locally

A tic configuration can be emulated locally.

First, ensure that all prerequisites are met:

This might install additional packages, or even fail with a descriptive message.

Then, run all steps defined in tic.R:

This emulates a CI run on your local machine by executing all stages and their corresponding steps. Note that this action this will use your local system libraries and not the CI environment. Only the steps that are shown with dsl_get() are executed. Some steps will not be executed as they are conditioned to run on non-interactive environments only, e.g. add_step(covr::codcov()) added by the macro do_package_checks().

✓ Loading tic stage configuration from tic.R
Running install: step_install_github("ropensci/rotemplate")
Skipping install of 'rotemplate' from a github remote, the SHA1 (bec3e6eb) has not changed since last install.
  Use `force = TRUE` to force installation
Running install: step_install_deps(repos = repo_default())

Debugging: Entering the CI build directly

Travis CI

If your build fails and you don’t understand why (error messages are too unspecific, you cannot reproduce the problem locally), you can SSH into the build to debug it. To do so, your repository must be enabled on Travis CI for “ssh debugging”. Unfortunately you need to take manual action by contacting Travis CI via e-mail, asking whether they can activate your repo for ssh debugging. Usually you get a reply within one day including additional information. After that, you either follow the manual instructions you get via mail or take the easy way: travis::travis_debug_job().

All it needs is the “Job ID” of the respective build you want to enter.

Rather than going to the web interface and getting the “Job ID” there, you can also do this from the command line. First, you need to query the overall “Build ID” of the run:

Because every “build” has multiple “Jobs”, you can now query the “Job ID”. For example, when you know that you want to debug the latest build, you can combine both commands:

build_id <- travis::travis_get_builds()[[1]]$id
travis::travis_get_jobs(build_id)

Finally, the build can be restarted by calling travis::travis_debug_job():

job_id <- travis::travis_get_jobs(build_id)[[1]]$id
travis::travis_debug_job(job_id)

Wait a few minutes until the build arrives at the point when it shows the SSH command that can be used to enter the build. It should look similar to ssh [email protected]. If you still do not want to use the browser manually, simple call travis::browse() to open your project on Travis.

Once you are in the build you can use bash functions defined by Travis to to execute specific stages:

The debug session is a VM running a tmate session. This makes it possible to use tmux commands, such as:

  • Create multiple windows with crtl-b c.
  • Switch to a different window: crtl-b <window index> where the indices start with 0, 1, 2 and so on.
  • Scrolling up and down the history: crtl-b [. Press q to exit the scroll mode.

See this cheatsheet for more shortcuts.

Keep in mind that you only have 30 minutes before the VM will be terminated automatically.

Circle CI

Debugging builds on Circle CI is much easiern than on Travis CI. Go to the web interface and click on the three dots as shown in the screenshot. Then you can restart your build from the appearing dropdown menu and SSH into the build in a the same as way shown for Travis CI.

What’s not covered yet?

  • SystemRequirements: {tic} is not yet capable of automatically determining system requirements specified in DESCRIPTION files of an R package. Future plans include to automatically provide suggestions like

    “Please add addons: apt: <library> to .travis.yml” in case system requirements are missing.