flowchart TD A(Discuss workflow <br> purpose) --> B(Create <br> workflow) B --> C(Push <br> workflow) C --> D(Observe <br> feedback) D --> E(Address <br> feedback) E --> F(Discuss <br> implementation) F --> A
R/Pharma
November 4th, 2022
This workshop aims to discuss and show you how to implement 8 simple CI/CD workflows for a bare bones R package 📦
Setup
Setup
devel
within GitHub 🪵Setup
https
link to your repo {devtools}
package ⏬devtools::install_dev_deps()
to install all necessary packages Setup
Setup
README.md
file by adding today’s date 📆Commit
button > Stage README.md
> Add a message 📜Type: Package
Package: cicdworkshop
Title: Demo Package for R/Pharma CI/CD Workshop
Version: 0.0.1
Authors@R:
person("Open", "Source", , "osauthor@noreply.pharmaverse.com", role = c("aut", "cre"))
Description: Intended to demo CI/CD pipelines on GitHub.
License: Apache License (>= 2)
URL: https://pharmaverse.github.io/cicdworkshop.rinpharma2022
Depends:
R (>= 3.5)
Imports:
lifecycle
Suggests:
covr,
devtools,
knitr,
lintr,
pkgdown,
rmarkdown,
roxygen2,
spelling,
styler,
testthat
VignetteBuilder:
knitr
Encoding: UTF-8
Language: en-US
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.1
flowchart TD A(Discuss workflow <br> purpose) --> B(Create <br> workflow) B --> C(Push <br> workflow) C --> D(Observe <br> feedback) D --> E(Address <br> feedback) E --> F(Discuss <br> implementation) F --> A
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
Why have a workflow that checks the Package Build?
1 2 3 4 5 6 7 8
name: R CMD check
on:
pull_request: {branches: ['main']}
jobs:
Check:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Install dependencies
run: devtools::install_dev_deps()
shell: Rscript {0}
- name: Build package
run: R CMD build .
- name: Check package
run: R CMD check --no-manual *.tar.gz
Advanced Usage: AdmiralCI’s R CMD Check Workflow
1 2 3 4 5 6 7 8
Why have a workflow that checks Links in your Package?
1 2 3 4 5 6 7 8
name: Check URLs
on:
pull_request: {branches: ['main']}
jobs:
Links:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Check URLs in docs
uses: lycheeverse/lychee-action@v1.5.1
with:
fail: true
jobSummary: true
format: markdown
output: links-results.md
args: >-
--exclude "https://github.com.*.git|lycheeverse.*"
--no-progress **/*.md **/*.Rmd
env: {GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"}
Advanced Usage: AdmiralCI’s Link Check Workflow
1 2 3 4 5 6 7 8
Why have a workflow that checks the spelling in your package?
1 2 3 4 5 6 7 8
name: Spellcheck
on:
pull_request: {branches: ['main']}
jobs:
Spelling:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Run Spelling Check test
uses: insightsengineering/r-spellcheck-action@v2
Advanced Usage: AdmiralCI’s Spellcheck Workflow
1 2 3 4 5 6 7 8
Why have a workflow that checks your Code Style in your Package?
1 2 3 4 5 6 7 8
name: Style
on:
pull_request: {branches: ['main']}
jobs:
Style:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install styler
run: if (!require("styler")) install.packages("styler")
shell: Rscript {0}
- name: Run styler
run: styler::style_pkg(dry = "fail")
shell: Rscript {0}
Advanced Usage: AdmiralCI’s styler
Workflow
1 2 3 4 5 6 7 8
Why have a workflow that runs a Linter in your Package?
1 2 3 4 5 6 7 8
name: Lint Code Base
on:
pull_request: {branches: ['main']}
jobs:
Linter:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
with: {fetch-depth: 0}
- name: Lint Code Base
uses: github/super-linter/slim@v4
env:
VALIDATE_ALL_CODEBASE: false
VALIDATE_R: true
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LINTR_ERROR_ON_LINT: true
Advanced Usage: AdmiralCI’s lintr
Workflow
1 2 3 4 5 6 7 8
Why have a workflow that checks your Manual pages in your Package?
{roxygen2}
1 2 3 4 5 6 7 8
name: ROxygen
on:
pull_request: {branches: ['main']}
jobs:
ManPages:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Roxygen check
run: |
git config --global --add safe.directory $(pwd)
R -s -e "roxygen2::roxygenize('.', roclets = c('rd', 'collate', 'namespace'))"
if [[ -n `git status -s | grep -E "man|DESCRIPTION|NAMESPACE"` ]]; then
echo "❌ Manual pages are NOT up-to-date ❌" && exit 1
fi
echo "Manual pages are up-to-date 😇"
shell: bash
Advanced Usage: AdmiralCI’s roxygen
Workflow
1 2 3 4 5 6 7 8
Why have a workflow that checks the Test Coverage in your Package?
1 2 3 4 5 6 7 8
name: Test Coverage
on:
pull_request: {branches: [main]}
jobs:
Coverage:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install covr
run: if (!require("covr")) install.packages("covr")
shell: Rscript {0}
- name: Run coverage
run: covr::package_coverage(quiet = FALSE)
shell: Rscript {0}
Advanced Usage: AdmiralCI’s covr
Workflow
1 2 3 4 5 6 7 8
Why have a workflow that publishes a website for your Package?
1 2 3 4 5 6 7 8
name: pkgdown
on:
pull_request: {branches: ['main']}
push: {branches: ['main']}
jobs:
Generate:
runs-on: ubuntu-latest
container: {image: "rocker/tidyverse:4.2.1"}
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Build site
run: pkgdown::build_site_github_pages(install = TRUE, dest_dir = "public")
shell: Rscript {0}
- name: Deploy to GitHub pages
if: github.event_name == 'push'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
keep_files: true
Advanced Usage: AdmiralCI’s pkgdown
Workflow