Running R in GitHub Actions

· 4 min read · Updated March 12, 2026 · intermediate
R GitHub Actions CI/CD devtools

GitHub Actions lets you automate R workflows directly in your repository. Whether you’re checking an R package, running tests, or building documentation, CI saves time and catches problems early. This guide covers the essentials for running R in GitHub Actions.

Setting Up R in GitHub Actions

The r-lib/actions repository provides ready-made workflows for R projects. Start with the setup-R action:

steps:
  - uses: actions/checkout@v4
  
  - uses: r-lib/actions/setup-r@v2
    with:
      r-version: '4.3'

This checks out your code and installs the specified R version. You can also use "devel" for the development version or a matrix strategy to test against multiple R versions.

Installing R Packages

Package installation is typically the slowest step in R CI. Use the setup-renv action to cache your dependencies:

- uses: r-lib/actions/setup-renv@v2

This restores packages from a lockfile (renv.lock), dramatically speeding up subsequent runs. If you prefer not to use renv, the setup-r action includes basic caching:

- uses: r-lib/actions/setup-r@v2
  with:
    r-version: '4.3'
    cache: true

The cache: true option caches the user library between runs based on yourDESCRIPTION file.

Running R CMD check

The standard way to validate an R package is R CMD check. The r-lib/actions repository provides a dedicated action:

- uses: r-lib/actions/check-r-package@v2

This action runs a full R CMD check with proper settings for CI environments. It handles OS-specific differences and configures the environment appropriately.

For more control, you can run check manually:

- name: Run R CMD check
  run: |
    R CMD build .
    R CMD check *_*.tar.gz
  shell: Rscript {0}

Running Tests with testthat

If you’re using testthat for unit tests, run them in your workflow:

- name: Run tests
  run: |
    library(testthat)
    library(yourpackage)
    test_dir("tests/testthat")
  shell: Rscript {0}

Or use the dedicated test action:

- uses: r-lib/actions/setup-r-dependencies@v2
  with:
    extra-packages: testthat

- name: Test package
  run: |
    library(testthat)
    test_check("yourpackage")
  shell: Rscript {0}

The setup-r-dependencies action installs packages listed in your Description file, making it easy to set up your test environment.

Building pkgdown Sites

Many R packages host their documentation on GitHub Pages using pkgdown. Here’s a complete workflow:

name: pkgdown

on:
  push:
    branches: [main]

jobs:
  pkgdown:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - uses: r-lib/actions/setup-r@v2
      
      - uses: r-lib/actions/setup-renv@v2
      
      - name: Build site
        run: pkgdown::build_site()
        shell: Rscript {0}
      
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs

This builds your pkgdown site on every push to main and deploys it to GitHub Pages. Make sure to enable GitHub Pages in your repository settings.

Rendering Quarto and R Markdown

For Quarto documents or R Markdown reports, use an appropriate rendering step:

- name: Render Quarto
  run: quarto::quarto_render("report.qmd")
  shell: Rscript {0}

- name: Render R Markdown
  run: rmarkdown::render("report.Rmd")
  shell: Rscript {0}

Add dependencies to your workflow as needed:

- name: Install Quarto
  uses: quarto-dev/quarto-actions/setup@v2
  with:
    version: 1.4

Caching Strategies

Package installation is expensive. Here are two caching approaches:

- uses: r-lib/actions/setup-renv@v2

Commit your renv.lock file to the repository. The action restores the exact package versions on each run.

Using setup-r with cache

- uses: r-lib/actions/setup-r@v2
  with:
    cache: true

This caches your library based on your DESCRIPTION file. It’s simpler but less precise than renv.

For maximum speed, combine both—use setup-renv for reproducibility and add a manual cache step for additional packages:

- uses: actions/cache@v4
  with:
    path: ~/.local/bin
    key: ${{ runner.os }}-quarto-${{ hashFiles('*.qmd') }}

Complete Example: R Package CI

Here’s a full workflow that combines several elements:

name: R Package CI

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  test:
    runs-on: ${{ matrix.config.os }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - { os: ubuntu-latest, r: '4.3' }
          - { os: ubuntu-latest, r: '4.2' }
          - { os: macOS-latest, r: '4.3' }
          - { os: windows-latest, r: '4.3' }

    steps:
      - uses: actions/checkout@v4

      - uses: r-lib/actions/setup-r@v2
        with:
          r-version: ${{ matrix.config.r }}

      - uses: r-lib/actions/setup-renv@v2

      - name: Run tests
        run: |
          library(testthat)
          test_check("mypackage")
        shell: Rscript {0}

      - name: Run R CMD check
        run: |
          R CMD build .
          R CMD check *_*.tar.gz --as-cran
        shell: Rscript {0}

This runs tests and checks on multiple R versions and operating systems. Adjust the matrix based on your package’s compatibility requirements.

Conclusion

GitHub Actions provides powerful CI/CD for R projects. Start with the r-lib actions—they’re maintained by the R community and handle the nuances of R environments. Focus on caching package installations, using renv for reproducibility, and automating the checks that matter for your project. Once configured, your R package CI will catch issues automatically on every push.

See Also