# GitHub Actions for R
## Contents
- [[#Links|Links]]
- [[#R CMD Check|R CMD Check]]
- [[#Example Workflows|Example Workflows]]
- [[#Quickstart CI workflow|Quickstart CI workflow]]
- [[#When should you use it?|When should you use it?]]
- [[#Standard CI workflow|Standard CI workflow]]
- [[#When should you use it?|When should you use it?]]
- [[#Tidyverse CI workflow|Tidyverse CI workflow]]
- [[#When should you use it?|When should you use it?]]
- [[#Test coverage workflow|Test coverage workflow]]
- [[#Lint workflow|Lint workflow]]
- [[#Commands workflow|Commands workflow]]
- [[#When should you use it?|When should you use it?]]
- [[#Render Rmarkdown|Render Rmarkdown]]
- [[#Build pkgdown site|Build pkgdown site]]
- [[#Document package|Document package]]
- [[#Style package|Style package]]
- [[#Build bookdown site|Build bookdown site]]
- [[#Build blogdown site|Build blogdown site]]
- [[#Shiny App Deployment|Shiny App Deployment]]
- [[#Docker based workflow|Docker based workflow]]
- [[#Bioconductor-friendly workflow|Bioconductor-friendly workflow]]
- [[#Lint project workflow|Lint project workflow]]
- [[#Forcing binaries|Forcing binaries]]
- [[#Appendix: Links|Appendix: Links]]
## Links
- [[GHA - R Build Blogdown]]
- [[GHA - R Build Bookdown]]
- [[GHA - R Build-Check-Install]]
- [[GHA - R Check (Standard)]]
- [[GHA - R Code Coverage]]
- [[GHA - R Docker]]
- [[GHA - R Lint]]
- [[GHA - R Package Validation]]
- [[GHA - R pkgcheck]]
- [[GHA - R pkgdown]]
- [[GHA - R Render RMD]]
- [[GHA - R roxygen]]
- [[GHA - R ShinyApp Deploy]]
- [[GHA - R Spelling]]
- [[GHA - R Test Coverage]]
- [[GHA - Release]]
## R CMD Check
- `check-full.yml`
```yaml
# NOTE: This workflow is overkill for most R packages
# check-standard.yaml is likely a better choice
# usethis::use_github_action("check-standard") will install it.
#
# For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag.
# https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: macOS-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: windows-latest, r: '3.6'}
- {os: ubuntu-18.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest", http-user-agent: "R/4.0.0 (ubuntu-18.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions" }
- {os: ubuntu-18.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"}
- {os: ubuntu-18.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"}
- {os: ubuntu-18.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"}
- {os: ubuntu-18.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"}
- {os: ubuntu-18.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"}
env:
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@v1
id: install-r
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
- uses: r-lib/actions/setup-pandoc@v1
- name: Install pak and query dependencies
run: |
install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")
saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds")
shell: Rscript {0}
- name: Restore R package cache
uses: actions/cache@v2
with:
path: |
${{ env.R_LIBS_USER }}/*
!${{ env.R_LIBS_USER }}/pak
key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }}
restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
pak::local_system_requirements(execute = TRUE)
pak::pkg_system_requirements("rcmdcheck", execute = TRUE)
shell: Rscript {0}
- name: Install dependencies
run: |
pak::local_install_dev_deps(upgrade = TRUE)
pak::pkg_install("rcmdcheck")
shell: Rscript {0}
- name: Session info
run: |
options(width = 100)
pkgs <- installed.packages()[, "Package"]
sessioninfo::session_info(pkgs, include_base = TRUE)
shell: Rscript {0}
- name: Check
env:
_R_CHECK_CRAN_INCOMING_: false
run: |
options(crayon.enabled = TRUE)
rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
shell: Rscript {0}
- name: Show testthat output
if: always()
run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash
- name: Upload check results
if: failure()
uses: actions/upload-artifact@main
with:
name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results
path: check
```
- `check-standard.yml`
```yaml
# For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag.
# https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: windows-latest, r: 'release'}
- {os: macOS-latest, r: 'release'}
- {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
- {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"}
env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@v1
with:
r-version: ${{ matrix.config.r }}
- uses: r-lib/actions/setup-pandoc@v1
- name: Query dependencies
run: |
install.packages('remotes')
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
shell: Rscript {0}
- name: Restore R package cache
if: runner.os != 'Windows'
uses: actions/cache@v2
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
while read -r cmd
do
eval sudo $cmd
done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))')
- name: Install dependencies
run: |
remotes::install_deps(dependencies = TRUE)
remotes::install_cran("rcmdcheck")
shell: Rscript {0}
- name: Check
env:
_R_CHECK_CRAN_INCOMING_REMOTE_: false
run: |
options(crayon.enabled = TRUE)
rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
shell: Rscript {0}
- name: Upload check results
if: failure()
uses: actions/upload-artifact@main
with:
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
path: check
```
## Example Workflows
Package workflows:
- [`check-release`](#quickstart-ci-workflow) - A simple CI workflow to
check with the release version of R.
- [`check-standard`](#standard-ci-workflow) - A standard CI workflow
to check with the release version of R on the three major OSs.
- [`check-full`](#tidyverse-ci-workflow) - A more complex CI workflow
- [`test-coverage`](#test-coverage-workflow) - Run `covr::codecov()`
on an R package.
- [`lint`](#lint-workflow) - Run `lintr::lint_package()` on an R
package.
- [`pr-commands`](#commands-workflow) - Adds `/document` and `/style`
commands for pull requests.
- [`pkgdown`](#build-pkgdown-site) - Build a
[pkgdown](https://pkgdown.r-lib.org/) site for an R package and
deploy it to [GitHub Pages](https://pages.github.com/).
- [`document`](#document-package) - Run `roxygen2::roxygenise()` on an
R package.
- [`style`](#style-package) - Run `styler::style_pkg()` on an R
package.
RMarkdown workflows:
- [`render-rmarkdown`](#render-rmarkdown) - Render one or more
Rmarkdown files when they change and commit the result.
- [`bookdown`](#build-bookdown-site) - Build a
[bookdown](https://bookdown.org) site and deploy it to [GitHub
Pages](https://pages.github.com/).
- [`blogdown`](#build-blogdown-site) - Build a
[blogdown](https://bookdown.org/yihui/blogdown/) site and deploy it
to [GitHub Pages](https://pages.github.com/).
Other workflows:
- [`docker`](#docker-based-workflow) - For custom workflows based on
docker containers.
- [Bioconductor](#bioconductor-friendly-workflow) - A CI workflow for
packages to be released on Bioconductor.
- [`lint-project`](#lint-project-workflow) - Run `lintr::lint_dir()`
on an R project.
- [`shiny-deploy`](#shiny-app-deployment) - Deploy a Shiny app to
shinyapps.io or RStudio Connect.
Options and advice:
- [Forcing binaries](#forcing-binaries) - An environment variable to
always use binary packages.
### Quickstart CI workflow
`usethis::use_github_action("check-release")`
This workflow installs latest release R version on macOS and runs R CMD
check via the [rcmdcheck](https://github.com/r-lib/rcmdcheck) package.
If this is the first time you have used CI for a project this is
probably what you want to use.
#### When should you use it?
1. You have a simple R package
2. There is no OS-specific code
3. You want a quick start with R CI
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- uses: r-lib/actions/check-r-package@v2
```
### Standard CI workflow
`usethis::use_github_action("check-standard")`
This workflow runs R CMD check via the
[rcmdcheck](https://github.com/r-lib/rcmdcheck) package on the three
major OSs (linux, macOS and Windows) with the current, development, and
previous versions of R. If you plan to someday submit your package to
CRAN or Bioconductor this is likely the workflow you want to use.
#### When should you use it?
1. You plan to submit your package to CRAN or Bioconductor
2. Your package has OS-specific code
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: macOS-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
```
### Tidyverse CI workflow
`usethis::use_github_action("check-full")`
This workflow installs the last 5 minor R versions and runs R CMD check
via the [rcmdcheck](https://github.com/r-lib/rcmdcheck) package on the
three major OSs (linux, macOS and Windows). This workflow is what the
tidyverse teams uses on their repositories, but is overkill for less
widely used packages, which are better off using the simpler quickstart
CI workflow.
#### When should you use it?
1. You are a tidyverse developer
2. You have a complex R package
3. With OS-specific code
4. And you want to ensure compatibility with many older R versions
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
#
# NOTE: This workflow is overkill for most R packages and
# check-standard.yaml is likely a better choice.
# usethis::use_github_action("check-standard") will install it.
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: R-CMD-check
jobs:
R-CMD-check:
runs-on: ${{ matrix.config.os }}
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
strategy:
fail-fast: false
matrix:
config:
- {os: macOS-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
# Use 3.6 to trigger usage of RTools35
- {os: windows-latest, r: '3.6'}
# Use older ubuntu to maximise backward compatibility
- {os: ubuntu-18.04, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-18.04, r: 'release'}
- {os: ubuntu-18.04, r: 'oldrel-1'}
- {os: ubuntu-18.04, r: 'oldrel-2'}
- {os: ubuntu-18.04, r: 'oldrel-3'}
- {os: ubuntu-18.04, r: 'oldrel-4'}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
```
### Test coverage workflow
`usethis::use_github_action("test-coverage")`
This example uses the [covr](https://covr.r-lib.org) package to query
the test coverage of your package and upload the result to
[codecov.io](https://codecov.io)
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: test-coverage
jobs:
test-coverage:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::covr
needs: coverage
- name: Test coverage
run: covr::codecov(quiet = FALSE)
shell: Rscript {0}
```
### Lint workflow
`usethis::use_github_action("lint")`
This example uses the [lintr](https://github.com/jimhester/lintr)
package to lint your package and return the results as build
annotations.
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: lint
jobs:
lint:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::lintr
needs: lint
- name: Lint
run: lintr::lint_package()
shell: Rscript {0}
```
### Commands workflow
`usethis::use_github_action("pr-commands")`
This workflow enables the use of 2 R specific commands in pull request
issue comments. `/document` will use
[roxygen2](https://roxygen2.r-lib.org/) to rebuild the documentation for
the package and commit the result to the pull request. `/style` will use
[styler](https://styler.r-lib.org/) to restyle your package.
#### When should you use it?
1. You get frequent pull requests, often with documentation only fixes.
2. You regularly style your code with styler, and require all additions
be styled as well.
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
issue_comment:
types: [created]
name: Commands
jobs:
document:
if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }}
name: document
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/pr-fetch@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::roxygen2
needs: pr-document
- name: Document
run: roxygen2::roxygenise()
shell: Rscript {0}
- name: commit
run: |
git config --local user.name "$GITHUB_ACTOR"
git config --local user.email "
[email protected]"
git add man/\* NAMESPACE
git commit -m 'Document'
- uses: r-lib/actions/pr-push@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
style:
if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }}
name: style
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v2
- uses: r-lib/actions/pr-fetch@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: r-lib/actions/setup-r@v2
- name: Install dependencies
run: install.packages("styler")
shell: Rscript {0}
- name: Style
run: styler::style_pkg()
shell: Rscript {0}
- name: commit
run: |
git config --local user.name "$GITHUB_ACTOR"
git config --local user.email "
[email protected]"
git add \*.R
git commit -m 'Style'
- uses: r-lib/actions/pr-push@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
```
### Render Rmarkdown
`usethis::use_github_action("render-rmarkdown")`
This example automatically re-builds any Rmarkdown file in the
repository whenever it changes and commits the results to the same
branch.
``` yaml
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
paths: ['**.Rmd']
name: render-rmarkdown
jobs:
render-rmarkdown:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
- uses: r-lib/actions/setup-renv@v2
- name: Render Rmarkdown files and Commit Results
run: |
RMD_PATH=($(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '[.]Rmd