Added Rhub. #1421
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTE: This script is a modification of the r-lib/actions standard cehcking script and the public-private sync script, on which it piggybacks to detect when it's in a private repo and can therefore skip some or even all tests. It also builds and uploads binaries for Windows and MacOS. | |
# 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 | |
# Each entry in the config matrix must have the following keys: | |
# | |
# os: windows-latest, macOS-latest, ubuntu-20.04, etc. (as of this writing) | |
# | |
# r: devel or release | |
# | |
# rspm: Linux only, just leave it alone. | |
# | |
# timeout: in minutes | |
# | |
# flags: a comma (or some other aesthetically pleasing and | |
# non-forbidden symbol) separated list of flags. Currently | |
# supported: | |
# | |
# binaries: build and upload as an artefact a binary version (particularly for MacOS and Windows). | |
# | |
# full: run with ENABLE_statnet_TESTS. | |
# | |
# vignettes: build vignettes and manuals; otherwise ignore. | |
# | |
# ubsan: compile with -fsanitize=undefined and fail on any errors identified. | |
# | |
# debug: compile package with -DDEBUG and -UNDEBUG | |
# | |
# covr: run in covr mode may be used with 'full' but probably not with others. | |
# | |
# | |
# Typical public, private, and release configurations are provided in the variables below. | |
on: [push, pull_request] | |
name: R-CMD-check | |
# Set public and private repositories (i.e., USER/PKG). Leave blank to autodetect. | |
env: | |
PUBLIC: '' | |
PRIVATE: '' | |
PUBLIC_CONFIG: '{"config":[ | |
{"os":"windows-latest", "r":"release", "timeout":360, "flags":"binaries"}, | |
{"os":"macOS-latest", "r":"release", "timeout":360, "flags":"binaries, ubsan"}, | |
{"os":"ubuntu-latest", "r":"release", "timeout":360, "flags":"full, ubsan, debug"}, | |
{"os":"ubuntu-latest", "r":"devel", "timeout":360, "flags":"vignettes, remote"}, | |
{"os":"ubuntu-latest", "r":"release", "timeout":360, "flags":"full, covr"}]}' | |
RELEASE_CONFIG: '{"config":[ | |
{"os":"windows-latest", "r":"release", "timeout":360, "flags":"binaries, vignettes, remote, strict"}, | |
{"os":"macOS-latest", "r":"release", "timeout":360, "flags":"binaries, ubsan, vignettes, remote, strict"}, | |
{"os":"ubuntu-latest", "r":"release", "timeout":360, "flags":"full, ubsan, debug, strict"}, | |
{"os":"ubuntu-latest", "r":"devel", "timeout":360, "flags":"vignettes, remote, strict"}, | |
{"os":"ubuntu-latest", "r":"release", "timeout":360, "flags":"full, covr, strict"}]}' | |
PRIVATE_CONFIG: '{"config":[ | |
{"os":"ubuntu-latest", "r":"release", "timeout":10, "flags":"none"} | |
]}' | |
jobs: | |
Set-Matrix-Private: | |
runs-on: ubuntu-latest | |
outputs: | |
matrix: ${{ steps.set-matrix.outputs.matrix }} | |
steps: | |
- name: check-config # Make sure either neither or both are set; abort if not. | |
if: (env.PUBLIC == '') != (env.PRIVATE == '') | |
run: | | |
echo "Configuration problem: only one of the repositories is set." | |
exit 1 | |
- name: detect-repos | |
if: env.PUBLIC == '' && env.PRIVATE == '' # Autodetect always. | |
run: | | |
if [[ "${{ github.repository }}" == *-private ]] | |
then # Current repo is private. | |
IAM="private" | |
PRIVATE="${{ github.repository }}" | |
PUBLIC="${PRIVATE%-private}" | |
else # Current repo is public. | |
IAM="public" | |
PUBLIC="${{ github.repository }}" | |
PRIVATE="$PUBLIC-private" | |
fi | |
echo "IAM=$IAM" >> $GITHUB_ENV | |
echo "PRIVATE=$PRIVATE" >> $GITHUB_ENV | |
echo "PUBLIC=$PUBLIC" >> $GITHUB_ENV | |
- name: public-check # Check if the branch/tag exists in the public repository. | |
if: env.IAM == 'private' # Only check if from private repo. | |
run: | | |
set +e | |
git ls-remote --exit-code https://github.com/${{ env.PUBLIC }} ${{ github.ref }} | |
echo "FOUND_PUBLIC=$?" >> $GITHUB_ENV | |
- name: set-matrix | |
id: set-matrix | |
run: | | |
if [[ "${{ env.IAM }}" == 'public' ]] # Public: full set. | |
then | |
config='${{ env.PUBLIC_CONFIG }}' | |
elif [[ "${{ env.FOUND_PUBLIC }}" != '0' ]] # Private with no public analogue: reduced set. | |
then | |
config='${{ env.PRIVATE_CONFIG }}' | |
else # Private with public analogue: no checking. | |
config='' | |
fi | |
config="${config//$'\r'/' '}" | |
config="${config//$'\n'/' '}" | |
echo "matrix=$config" >> $GITHUB_OUTPUT | |
R-CMD-check: | |
needs: Set-Matrix-Private | |
if: needs.Set-Matrix-Private.outputs.matrix != '' | |
runs-on: ${{ matrix.config.os }} | |
name: ${{ matrix.config.os }} (r ${{ matrix.config.r }}, flags ${{ matrix.config.flags }}) | |
strategy: | |
fail-fast: false | |
matrix: ${{fromJson(needs.Set-Matrix-Private.outputs.matrix)}} | |
env: | |
HOMEBREW_NO_INSTALL_CLEANUP: 1 | |
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true | |
steps: | |
- name: If available, use the Janitor's key rather than the repository-specific key. | |
id: set-pat | |
run: | | |
if [[ -n "${{ secrets.JANITORS_GITHUB_PAT }}" ]] | |
then | |
echo "GITHUB_PAT=${{ secrets.JANITORS_GITHUB_PAT }}" >> $GITHUB_ENV | |
else | |
echo "GITHUB_PAT=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV | |
fi | |
shell: bash | |
- uses: actions/checkout@v4 | |
- uses: r-lib/actions/setup-r@v2 | |
with: | |
use-public-rspm: true | |
r-version: ${{ matrix.config.r }} | |
- name: Install tidy (on Linux if running vignettes) | |
if: runner.os == 'Linux' && contains(matrix.config.flags, 'vignettes') | |
run: | | |
/usr/bin/sudo DEBIAN_FRONTEND=noninteractive apt-get install -y tidy | |
shell: bash | |
- uses: r-lib/actions/setup-pandoc@v2 | |
- name: Install tinytex (system) | |
if: contains(matrix.config.flags, 'vignettes') | |
uses: r-lib/actions/setup-tinytex@v2 | |
- uses: r-lib/actions/setup-r-dependencies@v2 | |
with: | |
extra-packages: | | |
any::rcmdcheck | |
any::covr | |
any::V8 | |
any::xml2 | |
needs: | | |
check | |
coverage | |
- name: Install tinytex (R) | |
if: contains(matrix.config.flags, 'vignettes') | |
run: | | |
if(!requireNamespace("tinytex", quietly = TRUE)) pak::pkg_install("tinytex") | |
tinytex:::install_yihui_pkgs() | |
tinytex::tlmgr_install("makeindex") | |
shell: Rscript {0} | |
- name: Build | |
if: contains(matrix.config.flags, 'binaries') | |
run: | | |
dir.create("binaries", FALSE) | |
pkgbuild::build(binary=TRUE, vignettes=FALSE, dest_path = "binaries") | |
shell: Rscript {0} | |
- name: Upload build results | |
if: contains(matrix.config.flags, 'binaries') && !failure() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ runner.os }}-r${{ matrix.config.r }}-binaries | |
path: binaries | |
- name: Clean up build results | |
if: contains(matrix.config.flags, 'binaries') | |
run: rm -rf binaries | |
shell: bash | |
- name: Check | |
if: contains(matrix.config.flags, 'covr') == false | |
timeout-minutes: ${{ matrix.config.timeout }} | |
env: | |
_R_CHECK_CRAN_INCOMING_REMOTE_: ${{ contains(matrix.config.flags, 'remote') }} | |
_R_CHECK_FORCE_SUGGESTS_: false | |
ENABLE_statnet_TESTS: ${{ contains(matrix.config.flags, 'full') }} | |
R_VIGNETTES: ${{ contains(matrix.config.flags, 'vignettes') }} | |
FAIL_ON_WARN: ${{ contains(matrix.config.flags, 'strict') }} | |
USE_UBSAN: ${{ contains(matrix.config.flags, 'ubsan') }} | |
SET_DEBUG: ${{ contains(matrix.config.flags, 'debug') }} | |
run: | | |
if(Sys.getenv("R_VIGNETTES") == "true"){ | |
check_args <- c("--as-cran") | |
build_args <- c("--compact-vignettes=gs+qpdf") | |
}else{ | |
check_args <- c("--no-manual", "--as-cran", "--ignore-vignettes") | |
build_args <- c("--no-manual", "--no-build-vignettes") | |
} | |
if(Sys.getenv("ENABLE_statnet_TESTS") == "true"){ | |
check_args <- c(check_args, "--run-donttest") | |
} | |
error_on <- if(Sys.getenv("FAIL_ON_WARN") == "true") "warning" else "error" | |
extra_flags <- c() | |
if(Sys.getenv("USE_UBSAN") == "true"){ | |
extra_flags <- c(extra_flags, "-fsanitize=undefined") | |
Sys.setenv(UBSAN_OPTIONS=paste(Sys.getenv("UBSAN_OPTIONS"), "print_stacktrace=1")) | |
} | |
if(Sys.getenv("SET_DEBUG") == "true") extra_flags <- c(extra_flags, "-UNDEBUG", "-DDEBUG") | |
# Before R 4.3.0, R itself was not compliant. | |
if(getRversion() >= "4.3") extra_flags <- c(extra_flags, "-Wstrict-prototypes") | |
Sys.setenv(PKG_LIBS=paste(c(Sys.getenv("PKG_LIBS"), extra_flags), collapse=" "), | |
PKG_CXXFLAGS=paste(c(Sys.getenv("PKG_CXXFLAGS"), extra_flags), collapse=" "), | |
PKG_CFLAGS=paste(c(Sys.getenv("PKG_CFLAGS"), extra_flags), collapse=" ")) | |
rcmdcheck::rcmdcheck(args = check_args, build_args = build_args, error_on = error_on, check_dir = "check") | |
shell: Rscript {0} | |
- name: Check UBSAN output | |
if: contains(matrix.config.flags, 'ubsan') | |
# NB: xargs -r only works in GNU, so not on MacOS. | |
run: | | |
find check/ -name '*.Rout' -print0 > check/Rout.list | |
if [ -s check/Rout.list ] | |
then | |
cat check/Rout.list | xargs -0 grep -E '\.[hc]:[0-9]+:[0-9]+: +runtime error:' > check/ubsan.err || true | |
if [ -s check/ubsan.err ] | |
then | |
echo "UBSAN errors:" >&2 | |
cat check/ubsan.err >&2 | |
exit 1 | |
fi | |
fi | |
shell: bash | |
- name: Upload check results | |
if: contains(matrix.config.flags, 'covr') == false && failure() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ runner.os }}-r${{ matrix.config.r }}-results | |
path: | | |
check | |
!check/*/00_pkg_src | |
- name: Test coverage | |
if: contains(matrix.config.flags, 'covr') | |
timeout-minutes: ${{ matrix.config.timeout }} | |
env: | |
_R_CHECK_CRAN_INCOMING_REMOTE_: false | |
_R_CHECK_FORCE_SUGGESTS_: ${{ runner.os != 'macOS' }} # Rmpi is not available on macOS. | |
ENABLE_statnet_TESTS: ${{ contains(matrix.config.flags, 'full') }} | |
run: | | |
cov <- covr::package_coverage( | |
type=c("tests", "examples"), | |
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 results | |
if: contains(matrix.config.flags, 'covr') | |
uses: codecov/codecov-action@v4 | |
with: | |
fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} | |
file: ./cobertura.xml | |
plugin: noop | |
disable_search: true | |
token: ${{ secrets.CODECOV_TOKEN }} |