check-extra.yml
Extra R-package checks that R CMD check passes over. Adapted from IndrajeetPatil/workflows check-extra.yaml (MIT).
Three jobs run in parallel so every failure surfaces at once instead of short-circuiting at the first – the extra R-install cost is the point, not an accident. Disable any job with the matching check-* input if a package has no tests, no vignettes, or no README.Rmd.
What it catches
- Warnings as errors on three surfaces, all under
options(warn = 2L). Examples run in a fresh R session withrun_dontrunandrun_dontteston (thedevtools::run_examples(fresh = TRUE, ...)equivalent), because a parentwarn=2does not reachcallr’s child. Tests use a per-file sweep:testthat::test_file()insidewithr::local_options(list(warn = 2L)). A session-widewarn=2crashes parallel testthat workers (testthat#1912); this is the workaround that issue closed on. Vignettes render viafs::dir_ls("vignettes/", glob = "*.Rmd", recurse = TRUE). A deprecation warning from a dependency is the motivating case: it is invisible in a normal green check until the deprecation becomes an error a release later. - Random test order.
testthat::test_dir("tests/testthat", shuffle = TRUE)with a randomly drawn seed that is logged, so a failure is reproducible.TESTTHAT_PARALLEL=FALSEviawithr::local_envvar, because shuffling is meaningless if tests run in parallel anyway. This catches a test that only passes because an earlier one left state behind. A missingtests/testthatfails this job; disable it withcheck-random-order: falseif the package has no tests. - README render, also with warnings as errors. When
check-readme-freshnessis on (the default), the job also fails ifREADME.mdis modified or untracked after the render – so a consumer does not need a second workflow for that half. Only an explicitfalseopts out of freshness. A missingREADME.Rmdfails this job; disable it withcheck-readme: falseif the package has none.
A missing tests/testthat or vignettes/*.Rmd inside the combined warnings job is a skip with a log line, not a failure, so a package that has only examples still gets those checked.
.qmd vignettes and README.qmd are out of scope: the vignette glob is *.Rmd, matching upstream, and a Quarto README would need Quarto, which this check does not install.
purrr, withr, fs, cli, and pkgload are declared in extra-packages rather than arriving transitively via devtools.
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
path |
string | '.' |
Path to the R package root (the directory holding DESCRIPTION). |
extra-packages |
string | '' |
Extra R packages forwarded to setup-r-dependencies. Use this for packages a README or example needs that are not in DESCRIPTION. |
install-quarto |
boolean | false |
Install Quarto when setting up R dependencies. |
check-warnings |
boolean | true |
Run examples, tests, and vignettes with warnings as errors. |
check-random-order |
boolean | true |
Run testthat with shuffle = TRUE and a logged seed. |
check-readme |
boolean | true |
Render README.Rmd with warnings as errors. |
check-readme-freshness |
boolean | true |
When the README job runs, fail if README.md is modified or untracked after the render. |
Pin @v2: this capability was added after @v1 was frozen, so it does not exist at that tag.
Permissions
Only contents: read (the default), so no permissions: block is needed.
Example
# Copy to .github/workflows/check-extra.yml in your repo.
name: Extra R-package checks
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
extra:
uses: Morrison-Lab/gha/.github/workflows/check-extra.yml@v2
# with:
# path: '.'
# extra-packages: 'any::ggthemes'
# install-quarto: false
# check-warnings: true
# check-random-order: true
# check-readme: true
# check-readme-freshness: trueSee check-extra.yml in examples/ for the full caller stub. (Linked to the directory rather than the file, for the reason check-secrets.qmd records: a blob/main/... link to a capability’s own example 404s on the pull request that introduces it, and check-links rightly fails it.)