npx claudepluginhub choxos/rpkgagent --plugin r-package-developmentThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
This skill covers setting up comprehensive GitHub Actions workflows for R package development, including cross-platform testing, continuous integration, automated documentation deployment, and test coverage reporting.
Every R package should have these three workflows:
Create .github/workflows/R-CMD-check.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
permissions: read-all
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:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Pandoc
uses: r-lib/actions/setup-pandoc@v2
- name: Setup R
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
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update -y
sudo apt-get install -y libcurl4-openssl-dev
- name: Install dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- name: Check package
uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
For simpler packages, you can use fewer test configurations:
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: R-CMD-check
permissions: read-all
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: 'release'}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-pandoc@v2
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
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
For packages with system dependencies (e.g., gdal, jags, gsl):
- name: Install system dependencies on macOS
if: runner.os == 'macOS'
run: |
brew install gdal proj geos
- name: Install system dependencies on Linux
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
libgdal-dev \
libproj-dev \
libgeos-dev \
libudunits2-dev
- name: Install system dependencies on Windows
if: runner.os == 'Windows'
run: |
# Usually handled by rtools or binary packages
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
error-on: '"error"' # Can be "warning", "note", or "error"
build_args options:
--no-manual: Skip PDF manual creation (faster, requires less LaTeX)--compact-vignettes=gs+qpdf: Compress vignettes with Ghostscript and qpdf--no-build-vignettes: Skip vignette building entirely--resave-data: Optimize data file compressionCreate .github/workflows/pkgdown.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]
release:
types: [published]
workflow_dispatch:
name: pkgdown
# Limit concurrency: cancel in-progress runs when new ones are triggered
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
permissions:
contents: write
jobs:
pkgdown:
runs-on: ubuntu-latest
# Only restrict concurrency for non-PR jobs
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Pandoc
uses: r-lib/actions/setup-pandoc@v2
- name: Setup R
uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- name: Install dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::pkgdown, local::.
needs: website
- name: Build site
run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
shell: Rscript {0}
- name: Deploy to GitHub Pages
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: docs
branch: gh-pages
clean: true
single-commit: false
- name: Build and deploy
if: github.event_name != 'pull_request'
run: |
git config --local user.name "$GITHUB_ACTOR"
git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)'
- name: Build site for preview
if: github.event_name == 'pull_request'
run: |
pkgdown::build_site(preview = FALSE, install = FALSE)
shell: Rscript {0}
- name: Upload preview
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v3
with:
name: pkgdown-preview
path: docs/
Create .github/workflows/test-coverage.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
permissions: read-all
jobs:
test-coverage:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup R
uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- name: Install dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::covr, any::xml2
needs: coverage
- name: Test coverage
run: |
cov <- covr::package_coverage(
quiet = FALSE,
clean = FALSE,
install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
)
covr::to_cobertura(cov)
shell: Rscript {0}
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
files: ./cobertura.xml
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
- name: Show testthat output
if: always()
run: |
## --------------------------------------------------------------------
find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash
CODECOV_TOKEN to GitHub secrets (Settings > Secrets and variables > Actions)[](https://codecov.io/gh/username/packagename)
- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coverage.lcov
Respond to comments like /document or /style:
Create .github/workflows/pr-commands.yaml:
on:
issue_comment:
types: [created]
name: Commands
jobs:
document:
if: startsWith(github.event.comment.body, '/document')
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/pr-fetch@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: r-lib/actions/setup-r@v2
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::roxygen2
- name: Document
run: roxygen2::roxygenise()
shell: Rscript {0}
- name: Commit
run: |
git config --local user.name "$GITHUB_ACTOR"
git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
git add man/\* NAMESPACE
git commit -m 'Document' || echo "No changes to commit"
- uses: r-lib/actions/pr-push@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
style:
if: startsWith(github.event.comment.body, '/style')
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/pr-fetch@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: r-lib/actions/setup-r@v2
- name: Install styler
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 "$GITHUB_ACTOR@users.noreply.github.com"
git add \*.R
git commit -m 'Style' || echo "No changes to commit"
- uses: r-lib/actions/pr-push@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
Create .github/workflows/lint.yaml:
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: lint
permissions: read-all
jobs:
lint:
runs-on: ubuntu-latest
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- 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, local::.
needs: lint
- name: Lint
run: lintr::lint_package()
shell: Rscript {0}
env:
LINTR_ERROR_ON_LINT: true
# Add R-CMD-check workflow
usethis::use_github_action("check-standard")
# Add pkgdown workflow
usethis::use_github_action("pkgdown")
# Add test-coverage workflow
usethis::use_github_action("test-coverage")
# Add lint workflow
usethis::use_github_action("lint")
# List available workflows
usethis::use_github_actions()
# Browse workflow files
usethis::use_github_action()
Place workflows in .github/workflows/ directory:
.github/
workflows/
R-CMD-check.yaml
pkgdown.yaml
test-coverage.yaml
lint.yaml
Problem: Workflow can't push to gh-pages or create releases
Solution: Add permissions block:
permissions:
contents: write # For pushing to gh-pages
# Or for fine-grained control:
# contents: read
# pages: write
# id-token: write
Problem: Rate limited or can't access private repos
Solution: Set environment variable:
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
For private dependencies, create a Personal Access Token:
repo scopeGH_PATGITHUB_PAT: ${{ secrets.GH_PAT }}Problem: vignettes fail on Ubuntu devel
Solution: Skip vignettes on devel:
- uses: r-lib/actions/check-r-package@v2
with:
build_args: 'c("--no-manual", if (Sys.getenv("R_VERSION") != "devel") "--compact-vignettes=gs+qpdf")'
Or add system dependencies:
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
texlive-latex-base \
texlive-fonts-recommended \
texlive-fonts-extra \
texlive-latex-extra
Problem: macOS builds fail with missing system libraries
Solution: Use Homebrew:
- name: Install system dependencies
if: runner.os == 'macOS'
run: |
brew install pkg-config
brew install openssl
brew install libgit2
Problem: Multiple pushes create conflicting deployments
Solution: Use concurrency groups:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
For pkgdown specifically:
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
Problem: Old package versions used despite new releases
Solution: Dependencies are cached by setup-r-dependencies. To force refresh:
- uses: r-lib/actions/setup-r-dependencies@v2
with:
cache-version: 2 # Increment this to bust cache
Problem: PDF manual fails on Windows
Solution: Skip manual on Windows:
- uses: r-lib/actions/check-r-package@v2
with:
build_args: 'c(if (.Platform$OS.type != "windows") "--no-manual", "--compact-vignettes=gs+qpdf")'
Or install TinyTeX:
- name: Install TinyTeX
if: runner.os == 'Windows'
run: |
install.packages("tinytex")
tinytex::install_tinytex()
shell: Rscript {0}
Problem: Snapshot tests fail but snapshots aren't committed
Solution: Use upload-snapshots: true:
- uses: r-lib/actions/check-r-package@v2
with:
upload-snapshots: true
Then download artifacts and commit manually, or use pr-commands workflow.
Problem: Push to main but workflow doesn't run
Solution: Check:
main vs master).github/workflows/.yaml or .yml extensionProblem: README badge doesn't show status
Solution: Ensure badge URL matches workflow name:
<!-- Workflow name: R-CMD-check -->
[](https://github.com/username/repo/actions/workflows/R-CMD-check.yaml)
Get badge from GitHub: Repository > Actions > Select workflow > ... > Create status badge
[](https://github.com/username/packagename/actions/workflows/R-CMD-check.yaml)
[](https://codecov.io/gh/username/packagename)
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[](https://CRAN.R-project.org/package=packagename)
strategy:
fail-fast: false # Don't cancel all if one fails
matrix:
config:
- {os: macos-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}
exclude: # Skip specific combinations
- os: windows-latest
r: 'devel'
- name: Install LaTeX
if: runner.os == 'Linux' && matrix.config.r == 'release'
run: sudo apt-get install texlive
- name: Build PDF manual
if: matrix.config.r != 'devel'
run: R CMD Rd2pdf .
env:
# Global (all jobs)
GLOBAL_VAR: value
jobs:
check:
env:
# Job-level
JOB_VAR: value
steps:
- name: Step with env
env:
# Step-level
STEP_VAR: value
run: echo $STEP_VAR
Run checks daily to catch upstream breakage:
on:
schedule:
- cron: '0 8 * * *' # 8 AM UTC daily
workflow_dispatch: # Allow manual trigger
This comprehensive setup ensures robust CI/CD for your R package.