second draft? #128
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
name: Tests | |
on: | |
push: | |
branches: | |
- main | |
- master | |
pull_request: | |
branches: | |
- main | |
- master | |
# cargo error handling is wrapped by ci-cargo, for simplicity and better logging. | |
# To use ci-cargo in a step, source ci-cargo.ps1 (using `. ./ci-cargo.ps`, note the extra dot in front). | |
# ci-cargo does not handle correctly -- separator, so wrap it in quotes ('--') | |
# A special named parameter called `ActionName` can be used to set the name of current ci-cargo action, | |
# used as `ci-cargo .... -ActionName "Called for documentation purposes"`. | |
jobs: | |
# All tests under this job are run with pre-computed libR-sys bindings. | |
tests_no_bindgen: | |
runs-on: ${{ matrix.config.os }} | |
name: ${{ matrix.config.os }} (R-${{ matrix.config.r }} rust-${{ matrix.config.rust-version }}) | |
strategy: | |
fail-fast: false | |
matrix: | |
config: | |
- { os: windows-latest, r: 'release', rust-version: 'stable-msvc', rtools-version: '43' } | |
- { os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rtools-version: '43' } | |
- { os: windows-latest, r: 'oldrel', rust-version: 'stable-msvc', rtools-version: '42' } | |
- { os: macOS-latest, r: 'release', rust-version: 'stable' } | |
# - {os: macOS-latest, r: 'release', rust-version: 'nightly'} | |
# - {os: macOS-latest, r: 'devel', rust-version: 'stable'} | |
# - {os: macOS-latest, r: 'oldrel', rust-version: 'stable'} | |
- { os: ubuntu-latest, r: 'release', rust-version: 'stable', check_fmt: true } | |
- { os: ubuntu-latest, r: 'release', rust-version: 'nightly' } | |
# R-devel requires LD_LIBRARY_PATH | |
- { os: ubuntu-latest, r: 'devel', rust-version: 'stable' } | |
- { os: ubuntu-latest, r: 'oldrel', rust-version: 'stable' } | |
env: | |
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true | |
# This environment variable enables support for pseudo multi-target cargo builds. | |
# Current stable Rust does not support multi-targeting, | |
# see https://github.com/rust-lang/cargo/issues/8176 | |
# The variable is treated as a comma-separated list of valid Rust targets. | |
# 'default' value emits no '--target' flag. | |
# E.g.: BUILD_TARGETS=i686-pc-windows-gnu,x86_64-pc-windows-gnu builds two times, | |
# each time providing '--target=*-pc-windows-gnu' flag to cargo. | |
BUILD_TARGETS: default | |
# PowerShell core is available on all platforms and can be used to unify scripts | |
defaults: | |
run: | |
shell: pwsh | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
- name: Set up Rust | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ matrix.config.rust-version }} | |
components: rustfmt, clippy | |
- name: Install cargo-expand | |
uses: dtolnay/install@master | |
if: startsWith(runner.os, 'Windows') != true | |
with: | |
crate: cargo-expand | |
# https://github.com/dtolnay/install/issues/12 | |
- name: Install cargo-expand (dtolnay/install#12 workaround) | |
if: startsWith(runner.os, 'Windows') | |
run: cargo install cargo-expand | |
- name: Set up R | |
uses: r-lib/actions/setup-r@v2 | |
with: | |
r-version: ${{ matrix.config.r }} | |
rtools-version: ${{ matrix.config.rtools-version }} | |
# TODO: enable RSPM when all the packages are available | |
use-public-rspm: true | |
- name: Set up Pandoc | |
uses: r-lib/actions/setup-pandoc@v2 | |
- name: Configure Windows | |
if: startsWith(runner.os, 'Windows') | |
run: | | |
$rtools_home = "C:\rtools${{ matrix.config.rtools-version }}" | |
# c.f. https://github.com/wch/r-source/blob/f1501504df8df1668a57d3a1b6f80167f24441d3/src/library/profile/Rprofile.windows#L70-L71 | |
echo "${rtools_home}\x86_64-w64-mingw32.static.posix\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
echo "${rtools_home}\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
# Add target | |
rustup target add x86_64-pc-windows-gnu | |
echo "BUILD_TARGETS=x86_64-pc-windows-gnu" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append ; | |
# The following lines add two tweaks: | |
# | |
# 1. Change the linker name to "x86_64-w64-mingw32.static.posix-gcc.exe". | |
# 2. Add empty libgcc_s.a and libgcc_eh.a, and add them to the compiler's | |
# library search paths via `LIBRARY_PATH` envvar. | |
# | |
# The first tweak is needed because Rtools42 doesn't contain | |
# "x86_64-w64-mingw32-gcc," which `rustc` uses as the default linker | |
# for the `x86_64-pc-windows-gnu` target. | |
# | |
# If we use the Rtools' toolchain, the second tweak is also required. | |
# `rustc` adds `-lgcc_eh` and `-lgcc_s` flags to the compiler, but | |
# Rtools' GCC doesn't have `libgcc_eh` or `libgcc_s` due to the | |
# compilation settings. So, in order to please the compiler, we need | |
# to add empty `libgcc_eh` or `libgcc_s` to the library search paths. | |
# | |
# For more details, please refer to https://github.com/r-windows/rtools-packages/blob/2407b23f1e0925bbb20a4162c963600105236318/mingw-w64-gcc/PKGBUILD#L313-L316 | |
New-Item -Path libgcc_mock -Type Directory | |
New-Item -Path libgcc_mock\libgcc_eh.a -Type File | |
New-Item -Path libgcc_mock\libgcc_s.a -Type File | |
New-Item -Path .cargo -ItemType Directory -Force | |
$pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} | |
echo "LIBRARY_PATH=${pwd_slash}/libgcc_mock;$env:LIBRARY_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
@" | |
[target.x86_64-pc-windows-gnu] | |
linker = "x86_64-w64-mingw32.static.posix-gcc.exe" | |
"@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; | |
env: | |
RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} | |
# This is required for ubuntu r-devel | |
# 'Del alias:R' removes 'R' alias which prevents running R | |
- name: Configure Linux | |
if: startsWith(runner.os, 'linux') | |
run: | | |
Del alias:R | |
echo "LD_LIBRARY_PATH=$(R -s -e 'cat(normalizePath(R.home()))')/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# Check code formatting. As this doesn't depend on the platform, do this only on one platform. | |
- name: Check code formatting | |
if: matrix.config.check_fmt | |
run: cargo fmt -- --check | |
# For each target in the BUILD_TARGETS comma-separated list, run cargo build with appropriate target | |
# Required by Windows builds, does not affect other platforms | |
- name: Build | |
run: | | |
. ./ci-cargo.ps1 | |
foreach($target in ($env:BUILD_TARGETS).Split(',')) { | |
ci-cargo build $(if($target -ne 'default') {"--target=$target"} ) -ActionName "Building for $target target" | |
} | |
# For each target in the BUILD_TARGETS comma-separated list, run cargo test with appropriate target | |
# Required by Windows builds, does not affect other platforms | |
# ! ci-cargo requires '--' to be wrapped in quotes (passed as an explicit string) | |
- name: Run tests | |
run: | | |
. ./ci-cargo.ps1 | |
foreach($target in ($env:BUILD_TARGETS).Split(',')) { | |
# Note: no feature is specified, which means such features like graphics, serde, ndarray, and num-complex are not tested here. | |
ci-cargo test $(if($target -ne 'default') {"--target=$target"} ) '--' --nocapture -ActionName "Testing for $target target" | |
} | |
env: | |
LIBRARY_PATH: ${{ env.LIBRARY_PATH }} | |
RUST_BACKTRACE: 1 | |
# c.f. https://github.com/actions/checkout#checkout-multiple-repos-side-by-side | |
- name: Obtain 'rextendr' | |
uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
repository: extendr/rextendr | |
path: ./tests/rextendr | |
- name: Install dependencies for extendrtests and rcmdcheck | |
uses: r-lib/actions/setup-r-dependencies@v2 | |
with: | |
cache-version: 4 | |
working-directory: tests/extendrtests | |
extra-packages: any::rcmdcheck | |
- name: Install dependencies for rextendr | |
uses: r-lib/actions/setup-r-dependencies@v2 | |
with: | |
cache-version: 4 | |
working-directory: tests/rextendr | |
# TODO: allow warnings on oldrel (cf., https://stat.ethz.ch/pipermail/r-package-devel/2023q2/009229.html) | |
- name: Check R version | |
id: error-on | |
run: | | |
output <- Sys.getenv("GITHUB_OUTPUT") | |
if (.Platform$OS.type == "windows" && getRversion() < "4.3.0") { | |
cat('level=error', file = output, append = TRUE) | |
} else { | |
cat('level=warning', file = output, append = TRUE) | |
} | |
shell: Rscript {0} | |
- name: Run R integration tests using {extendrtests} and `cargo extendr r-cmd-check` | |
run: | | |
cargo extendr r-cmd-check --error-on ${{ steps.error-on.outputs.level }} --check-dir extendrtests_check | |
# With https://github.com/extendr/rextendr/pull/31 | |
# rextendr can be configured using environment variables. | |
# 'patch.crates_io' is used to point libraries to local copies of | |
# extendr-api and extendr-macros, so rextendr tests current version of extendr-* | |
- name: Prepare for R integration tests using {rextendr} | |
id: rextendr_check | |
env: | |
_R_CHECK_CRAN_INCOMING_REMOTE_: false | |
run: | | |
cat("::group::Preparing 'rextendr'\n") | |
patch.crates_io <- | |
paste( | |
paste0( | |
"extendr-api = { path = \"", | |
normalizePath(file.path(getwd(), "extendr-api"), winslash = "/"), | |
"\" }"), | |
paste0( | |
"extendr-macros = { path = \"", | |
normalizePath(file.path(getwd(), "extendr-macros"), winslash = "/"), | |
"\" }"), | |
# uncomment this line when we need to depend on the dev version of libR-sys | |
#'libR-sys = { git = "https://github.com/extendr/libR-sys" }', | |
# use the embedded libR-sys submodule | |
paste0( | |
"libR-sys = { path = \"", | |
normalizePath(file.path(getwd(), "libR-sys"), winslash = "/"), | |
"\" }"), | |
sep = ";") | |
patch.crates_io <- paste0("REXTENDR_PATCH_CRATES_IO=", patch.crates_io) | |
github_env_file <- Sys.getenv("GITHUB_ENV") | |
cat(patch.crates_io, file = github_env_file, append = TRUE) | |
cat("::endgroup::\n") | |
shell: Rscript {0} | |
- name: Run R integration tests using {rextendr} | |
env: | |
REXTENDR_SKIP_DEV_TESTS: 1 | |
uses: r-lib/actions/check-r-package@v2 | |
with: | |
args: 'c("--no-manual", "--as-cran", "--force-multiarch")' | |
working-directory: 'tests/rextendr' | |
check-dir: '"rextendr_check"' | |
error-on: '"${{ steps.error-on.outputs.level }}"' | |
# All tests under this job are run with R devel and freshly generated bindings. | |
# Run bindgen tests without cross-compilation. | |
# Cross-compilation prevents from running doc tests | |
# if toolchain does not match target (Windows x86_64/i686 case), see | |
# > https://github.com/rust-lang/rust/issues/64245 | |
# > https://github.com/rust-lang/cargo/issues/7040 | |
bindgen: | |
runs-on: ${{ matrix.config.os }} | |
name: ${{ matrix.config.os }} w/ bindgen (R-${{ matrix.config.r }} rust-${{ matrix.config.rust-version }} ${{join(matrix.config.rust-targets, ',')}}) | |
strategy: | |
fail-fast: false | |
matrix: | |
config: | |
- { os: ubuntu-latest, r: 'devel', rust-version: 'stable' } | |
- { os: macOS-latest, r: 'devel', rust-version: 'stable' } | |
- { os: windows-latest, r: 'release', rust-version: 'stable-msvc', rust-targets: [ 'x86_64-pc-windows-gnu' ], rtools-version: '43' } | |
- { os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rust-targets: [ 'x86_64-pc-windows-gnu' ], rtools-version: '43' } | |
# When the MSVC target is used, since it's cross-compilation from MSVC | |
# to GNU, the doc tests are usually skipped. Adding `-Zdoctest-xcompile` | |
# lets the doctests run, which accordingly require the nightly toolchain. | |
- { os: windows-latest, r: 'release', rust-version: 'nightly-msvc', rust-targets: [ 'x86_64-pc-windows-gnu' ], rtools-version: '43', extra-args: [ '-Zdoctest-xcompile' ] } | |
- { os: windows-latest, r: 'oldrel', rust-version: 'nightly-msvc', rust-targets: [ 'x86_64-pc-windows-gnu' ], rtools-version: '42', extra-args: [ '-Zdoctest-xcompile' ] } | |
env: | |
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true | |
# PowerShell core is available on all platforms and can be used to unify scripts | |
defaults: | |
run: | |
shell: pwsh | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: 'true' | |
- name: Set up Rust | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ matrix.config.rust-version }} | |
# 1. Update rustup | |
# 2. For each target add respective toolchain & | |
# update target for that toolchain | |
- name: Set up Rust targets | |
run: | | |
$targets = $env:RUST_TARGETS.Split(',') | |
foreach ($target in $targets) { | |
echo "::group::Setting up $env:RUST_TOOLCHAIN $target" | |
if ($target -ne '') { | |
rustup target add $target --toolchain "$env:RUST_TOOLCHAIN" | |
if(!$?) { | |
throw "Last exit code $LASTEXITCODE" | |
} | |
} | |
echo "::endgroup::" | |
} | |
env: | |
RUST_TARGETS: ${{ join(matrix.config.rust-targets, ',') }} | |
RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} | |
- name: Set up R | |
uses: r-lib/actions/setup-r@v2 | |
with: | |
r-version: ${{ matrix.config.r }} | |
rtools-version: ${{ matrix.config.rtools-version }} | |
use-public-rspm: true | |
windows-path-include-mingw: false | |
- name: Configure Windows | |
if: startsWith(runner.os, 'Windows') | |
run: | | |
$rtools_home = "C:\rtools${{ matrix.config.rtools-version }}" | |
echo "::group::Setting up x86_64" | |
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
# c.f. https://github.com/wch/r-source/blob/f1501504df8df1668a57d3a1b6f80167f24441d3/src/library/profile/Rprofile.windows#L70-L71 | |
echo "${rtools_home}\x86_64-w64-mingw32.static.posix\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
echo "${rtools_home}\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
echo "::endgroup::" | |
# The following lines add two tweaks: | |
# | |
# 1. Change the linker name to "x86_64-w64-mingw32.static.posix-gcc.exe". | |
# 2. Add empty libgcc_s.a and libgcc_eh.a, and add them to the compiler's | |
# library search paths via `LIBRARY_PATH` envvar. | |
# | |
# The first tweak is needed because Rtools42 doesn't contain | |
# "x86_64-w64-mingw32-gcc," which `rustc` uses as the default linker | |
# for the `x86_64-pc-windows-gnu` target. | |
# | |
# If we use the Rtools' toolchain, the second tweak is also required. | |
# `rustc` adds `-lgcc_eh` and `-lgcc_s` flags to the compiler, but | |
# Rtools' GCC doesn't have `libgcc_eh` or `libgcc_s` due to the | |
# compilation settings. So, in order to please the compiler, we need | |
# to add empty `libgcc_eh` or `libgcc_s` to the library search paths. | |
# | |
# For more details, please refer to https://github.com/r-windows/rtools-packages/blob/2407b23f1e0925bbb20a4162c963600105236318/mingw-w64-gcc/PKGBUILD#L313-L316 | |
New-Item -Path libgcc_mock -Type Directory | |
New-Item -Path libgcc_mock\libgcc_eh.a -Type File | |
New-Item -Path libgcc_mock\libgcc_s.a -Type File | |
New-Item -Path .cargo -ItemType Directory -Force | |
$pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} | |
echo "LIBRARY_PATH=${pwd_slash}/libgcc_mock;$env:LIBRARY_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
@" | |
[target.x86_64-pc-windows-gnu] | |
linker = "x86_64-w64-mingw32.static.posix-gcc.exe" | |
"@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; | |
env: | |
RUST_TARGETS: ${{ join(matrix.config.rust-targets, ',') }} | |
- name: Configure Linux | |
if: startsWith(runner.os, 'linux') | |
run: | | |
Del alias:R | |
echo "LD_LIBRARY_PATH=$(R -s -e 'cat(normalizePath(R.home()))')/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# 1. Retrieve targets | |
# 2. Retrieve 'libcalng' paths | |
# 3. For each target run | |
# 3.1 Select correct $target & $toolchain | |
# 3.x Run build commands, checking for errors, providing explicit toolchain & target | |
- name: Build | |
run: | | |
echo $LIBRARY_PATH | |
echo $env:LIBRARY_PATH | |
. ./ci-cargo.ps1 | |
$targets = $env:BUILD_TARGETS.Split(',') | |
$toolchain = $env:RUST_TOOLCHAIN | |
$itt = 0..($targets.Length - 1) | |
foreach($i in $itt) { | |
if ($targets[$i] -eq "") { | |
$target = 'default' | |
} | |
else { | |
$target = $targets[$i] | |
} | |
ci-cargo +$toolchain build --manifest-path extendr-api/Cargo.toml --features tests-all $(if($target -ne 'default') {"--target=$target"} ) -ActionName "Build extendr-api for $toolchain/$target" | |
ci-cargo +$toolchain build --manifest-path extendr-engine/Cargo.toml --features tests-all $(if($target -ne 'default') {"--target=$target"} ) -ActionName "Build extendr-engine for $toolchain/$target" | |
} | |
env: | |
BUILD_TARGETS: ${{ join(matrix.config.rust-targets, ',') }} | |
RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} | |
# Identical to the build process, but running more test commands | |
# ! ci-cargo requires '--' to be wrapped in quotes (passed as an explicit string) | |
- name: Run tests | |
run: | | |
. ./ci-cargo.ps1 | |
$targets = $env:BUILD_TARGETS.Split(',') | |
$toolchain = $env:RUST_TOOLCHAIN | |
$itt = 0..($targets.Length - 1) | |
foreach($i in $itt) { | |
if ($targets[$i] -eq "") { | |
$target = 'default' | |
} | |
else { | |
$target = $targets[$i] | |
} | |
ci-cargo +$toolchain test --manifest-path extendr-engine/Cargo.toml --features tests-all $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-engine \w tests-all for $target target" | |
ci-cargo +$toolchain test --manifest-path extendr-api/Cargo.toml --features tests $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-api \w tests for $target target" | |
# graphics tests requires --test-threads=1 | |
ci-cargo +$toolchain test graphics_tests:: --manifest-path extendr-api/Cargo.toml --features tests-graphics $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture --test-threads=1 -ActionName "Test extendr-api \w graphics for $target target" | |
ci-cargo +$toolchain test --manifest-path extendr-api/Cargo.toml --features tests-minimal $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-api \w tests-minimal for $target target" | |
ci-cargo +$toolchain test test_result_list --manifest-path extendr-api/Cargo.toml --features tests-minimal,result_list $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-api \w tests-minimal for $target target with `result_list` feature" | |
ci-cargo +$toolchain test test_result_condition --manifest-path extendr-api/Cargo.toml --features tests-minimal,result_condition $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-api \w tests-minimal for $target target with `result_condition` feature" | |
ci-cargo +$toolchain test --manifest-path extendr-macros/Cargo.toml $(if($target -ne 'default') {"--target=$target"} ) $env:EXTRA_ARGS '--' --nocapture -ActionName "Test extendr-macros for $target target" | |
} | |
env: | |
BUILD_TARGETS: ${{ join(matrix.config.rust-targets, ',') }} | |
RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} | |
EXTRA_ARGS: ${{ join(matrix.config.extra-args, ',') }} |