Skip to content

Documented the extended state API. #1417

Documented the extended state API.

Documented the extended state API. #1417

Workflow file for this run

# 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 }}