From a589350c797878145f38966ce00561a725e219ae Mon Sep 17 00:00:00 2001 From: jgabry Date: Tue, 6 Jan 2026 14:57:51 -0700 Subject: [PATCH 1/8] Enable optional custom tarball URL in unit tests closes #1130 --- .github/workflows/R-CMD-check.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 6664d79f0..7929aa86b 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -11,6 +11,12 @@ name: Unit tests pull_request: branches: - master + workflow_dispatch: + inputs: + tarball_url: + description: 'CmdStan tarball URL to test with.' + required: false + default: 'latest' jobs: R-CMD-check: @@ -36,6 +42,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} NOT_CRAN: true CMDSTANR_OPENCL_TESTS: ${{ matrix.config.opencl }} + CMDSTAN_TEST_TARBALL_URL: ${{ github.event.inputs.tarball_url || 'latest' }} PKG_SYSREQS_DB_UPDATE_TIMEOUT: 30s steps: @@ -86,7 +93,16 @@ jobs: - name: Install cmdstan run: | cmdstanr::check_cmdstan_toolchain(fix = TRUE) - cmdstanr::install_cmdstan(cores = 2) + if (Sys.getenv("CMDSTAN_TEST_TARBALL_URL") == "latest" || + Sys.getenv("CMDSTAN_TEST_TARBALL_URL") == "") { + cmdstanr::install_cmdstan(cores = 2) + } else { + cmdstanr::install_cmdstan( + cores = 2, + overwrite = TRUE, + release_url = Sys.getenv("CMDSTAN_TEST_TARBALL_URL") + ) + } shell: Rscript {0} - name: Session info From 93ea57c05b91562e77a765521f57dc57649689b4 Mon Sep 17 00:00:00 2001 From: jgabry Date: Tue, 6 Jan 2026 16:19:27 -0700 Subject: [PATCH 2/8] Fix error --- .github/workflows/R-CMD-check.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 7929aa86b..aeedc01de 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -16,7 +16,7 @@ name: Unit tests tarball_url: description: 'CmdStan tarball URL to test with.' required: false - default: 'latest' + default: '' jobs: R-CMD-check: @@ -42,7 +42,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} NOT_CRAN: true CMDSTANR_OPENCL_TESTS: ${{ matrix.config.opencl }} - CMDSTAN_TEST_TARBALL_URL: ${{ github.event.inputs.tarball_url || 'latest' }} + CMDSTAN_TEST_TARBALL_URL: ${{ github.event.inputs.tarball_url }} PKG_SYSREQS_DB_UPDATE_TIMEOUT: 30s steps: @@ -93,15 +93,15 @@ jobs: - name: Install cmdstan run: | cmdstanr::check_cmdstan_toolchain(fix = TRUE) - if (Sys.getenv("CMDSTAN_TEST_TARBALL_URL") == "latest" || - Sys.getenv("CMDSTAN_TEST_TARBALL_URL") == "") { - cmdstanr::install_cmdstan(cores = 2) - } else { + tarball_url <- Sys.getenv("CMDSTAN_TEST_TARBALL_URL") + if (nzchar(tarball_url)) { cmdstanr::install_cmdstan( cores = 2, overwrite = TRUE, - release_url = Sys.getenv("CMDSTAN_TEST_TARBALL_URL") + release_url = tarball_url ) + } else { + cmdstanr::install_cmdstan(cores = 2) } shell: Rscript {0} From 9748e66858ec5742d8cf9b5b380884caec310d6b Mon Sep 17 00:00:00 2001 From: jgabry Date: Wed, 7 Jan 2026 10:49:28 -0700 Subject: [PATCH 3/8] Update installation tests to hopefully avoid TBB errors * Bump version number when testing install of older CmdStan * Disable test installing older CmdStan versions when using a custom tarball url --- tests/testthat/test-install.R | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index a9c064829..daf374907 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -91,6 +91,9 @@ test_that("install_cmdstan() errors if invalid version or URL", { }) test_that("install_cmdstan() works with version and release_url", { + # this test is irrelevant if tests are using a release candidate tarball URL so skip + skip_if(!is.null(cmdstan_test_tarball_url)) + if (getRversion() < '3.5.0') { dir <- tempdir() } else { @@ -100,7 +103,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_message( expect_output( install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, - release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.35.0/cmdstan-2.35.0.tar.gz", + release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.36.0/cmdstan-2.36.0.tar.gz", wsl = os_is_wsl()), "Compiling C++ code", fixed = TRUE @@ -112,7 +115,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_message( expect_output( install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, - version = "2.35.0", + version = "2.36.0", # the URL is intentionally invalid to test that the version has higher priority release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.27.3/cmdstan-2.27.3.tar.gz", wsl = os_is_wsl()), @@ -125,7 +128,7 @@ test_that("install_cmdstan() works with version and release_url", { "version and release_url shouldn't both be specified", fixed = TRUE ) - expect_true(dir.exists(file.path(dir, "cmdstan-2.35.0"))) + expect_true(dir.exists(file.path(dir, "cmdstan-2.36.0"))) set_cmdstan_path(cmdstan_default_path()) }) @@ -256,10 +259,10 @@ test_that("Install from release file works", { dir <- tempdir(check = TRUE) } - destfile = file.path(dir, "cmdstan-2.35.0.tar.gz") + destfile <- file.path(dir, "cmdstan-2.36.0.tar.gz") download_with_retries( - "https://github.com/stan-dev/cmdstan/releases/download/v2.35.0/cmdstan-2.35.0.tar.gz", + "https://github.com/stan-dev/cmdstan/releases/download/v2.36.0/cmdstan-2.36.0.tar.gz", destfile) expect_message( From 4a60a03b6cb0ebad7d4bc27b30d3724484b010d6 Mon Sep 17 00:00:00 2001 From: jgabry Date: Wed, 7 Jan 2026 10:56:14 -0700 Subject: [PATCH 4/8] Delete cmdstan-tarball-check.yaml This functionality is now available in the regular unit tests --- .github/workflows/cmdstan-tarball-check.yaml | 101 ------------------- 1 file changed, 101 deletions(-) delete mode 100644 .github/workflows/cmdstan-tarball-check.yaml diff --git a/.github/workflows/cmdstan-tarball-check.yaml b/.github/workflows/cmdstan-tarball-check.yaml deleted file mode 100644 index 056e37f68..000000000 --- a/.github/workflows/cmdstan-tarball-check.yaml +++ /dev/null @@ -1,101 +0,0 @@ ---- -# Github Actions workflow to check CmdStanR tarball -# yamllint disable rule:line-length - -name: Custom CmdStan tarball unit tests - -'on': - workflow_dispatch: - inputs: - tarball_url: - description: 'CmdStan tarball URL to test with.' - required: true - default: 'latest' - -jobs: - tarball-check: - runs-on: ${{ matrix.config.os }} - - name: ${{ matrix.config.os }} (${{ matrix.config.r }}) - - strategy: - fail-fast: false - matrix: - config: - - {os: macOS-latest, r: 'release', rtools: ''} - - {os: windows-latest, r: 'release', rtools: '44'} - - {os: ubuntu-20.04, r: 'release', rtools: ''} - env: - R_REMOTES_NO_ERRORS_FROM_WARNINGS: true - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - CMDSTAN_TEST_TARBALL_URL: ${{ github.event.inputs.tarball_url }} - NOT_CRAN: true - - steps: - - uses: actions/checkout@v6 - - name: Install system dependencies - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y libcurl4-openssl-dev || true - sudo apt-get install -y openmpi-bin openmpi-common libopenmpi-dev || true - - - uses: r-lib/actions/setup-r@v2.11.3 - with: - r-version: ${{ matrix.config.r }} - rtools-version: ${{ matrix.config.rtools }} - - - uses: r-lib/actions/setup-pandoc@v2.11.3 - - - name: Query dependencies - run: | - install.packages('remotes') - saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) - writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") - shell: Rscript {0} - - - name: Cache R packages - if: runner.os != 'Windows' - uses: actions/cache@v5 - with: - path: ${{ env.R_LIBS_USER }} - key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- - - - name: Install dependencies - run: | - remotes::install_deps(dependencies = TRUE) - remotes::install_cran("rcmdcheck") - remotes::install_local(path = ".", INSTALL_opts = "--no-test-load") - cmdstanr::check_cmdstan_toolchain(fix = TRUE) - if (Sys.getenv("CMDSTAN_TEST_TARBALL_URL") == "latest") { - cmdstanr::install_cmdstan(cores = 2, overwrite = TRUE) - } else { - cmdstanr::install_cmdstan(cores = 2, overwrite = TRUE, release_url = "${{ github.event.inputs.tarball_url }}") - } - shell: Rscript {0} - - - name: Session info - run: | - options(width = 100) - pkgs <- installed.packages()[, "Package"] - sessioninfo::session_info(pkgs, include_base = TRUE) - shell: Rscript {0} - - - name: Check - env: - _R_CHECK_CRAN_INCOMING_: false - run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran", "--ignore-vignettes"), build_args = c("--no-build-vignettes"), error_on = "warning", check_dir = "check") - shell: Rscript {0} - - - name: Show testthat output - if: always() - run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true - shell: bash - - - name: Upload check results - if: failure() - uses: actions/upload-artifact@v6 - with: - name: ${{ runner.os }}-r${{ matrix.config.r }}-results - path: check From 0e004fb21b24a4273049c2d17e412e5261d7c494 Mon Sep 17 00:00:00 2001 From: jgabry Date: Wed, 7 Jan 2026 14:13:36 -0700 Subject: [PATCH 5/8] rebuild with cores=1 to avoid potential TBB parallelism bug --- tests/testthat/test-install.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index daf374907..2a63ea755 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -190,7 +190,7 @@ test_that("toolchain checks on Windows with RTools 3.5 work", { test_that("clean and rebuild works", { expect_output( - rebuild_cmdstan(), + rebuild_cmdstan(cores = 1), paste0("CmdStan v", cmdstan_version(), " built"), fixed = TRUE ) From b64b1e5afb043fdd5a94b58455efe711004e9590 Mon Sep 17 00:00:00 2001 From: jgabry Date: Wed, 7 Jan 2026 16:14:17 -0700 Subject: [PATCH 6/8] try cores=1 in a few more places --- tests/testthat/test-install.R | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index 2a63ea755..ec96a1668 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -13,7 +13,7 @@ test_that("install_cmdstan() successfully installs cmdstan", { } expect_message( expect_output( - install_cmdstan(dir = dir, cores = 2, quiet = FALSE, overwrite = TRUE, + install_cmdstan(dir = dir, cores = 1, quiet = FALSE, overwrite = TRUE, release_url = cmdstan_test_tarball_url, wsl = os_is_wsl()), "Compiling C++ code", @@ -52,7 +52,7 @@ test_that("install_cmdstan() errors if it times out", { expect_warning( expect_message( install_cmdstan(dir = dir, timeout = 1, quiet = TRUE, overwrite = dir_exists, - release_url = cmdstan_test_tarball_url, wsl = os_is_wsl()), + cores = 1, wsl = os_is_wsl()), if (dir_exists) "* Removing the existing installation" else "* * Installing CmdStan from https://github.com", fixed = TRUE ), @@ -64,8 +64,7 @@ test_that("install_cmdstan() errors if it times out", { expect_warning( expect_message( install_cmdstan(dir = dir, timeout = 1, quiet = FALSE, overwrite = dir_exists, - release_url = cmdstan_test_tarball_url, - wsl = os_is_wsl()), + cores = 1, wsl = os_is_wsl()), if (dir_exists) "* Removing the existing installation" else "* * Installing CmdStan from https://github.com", fixed = TRUE ), @@ -102,7 +101,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_message( expect_output( - install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, + install_cmdstan(dir = dir, overwrite = TRUE, cores = 1, release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.36.0/cmdstan-2.36.0.tar.gz", wsl = os_is_wsl()), "Compiling C++ code", @@ -114,7 +113,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_warning( expect_message( expect_output( - install_cmdstan(dir = dir, overwrite = TRUE, cores = 4, + install_cmdstan(dir = dir, overwrite = TRUE, cores = 1, version = "2.36.0", # the URL is intentionally invalid to test that the version has higher priority release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.27.3/cmdstan-2.27.3.tar.gz", @@ -218,11 +217,11 @@ test_that("Downloads respect quiet argument", { # expect_message has trouble capturing the messages from download.file # so handle manually install_normal <- suppressWarnings( - capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = FALSE), + capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = FALSE, cores = 1), type = "message") ) install_quiet <- suppressWarnings( - capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = TRUE), + capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = TRUE, cores = 1), type = "message") ) @@ -267,7 +266,7 @@ test_that("Install from release file works", { expect_message( expect_output( - install_cmdstan(dir = dir, cores = 2, quiet = FALSE, overwrite = TRUE, + install_cmdstan(dir = dir, cores = 1, quiet = FALSE, overwrite = TRUE, release_file = destfile, wsl = os_is_wsl()), "Compiling C++ code", From 978292b43fcc2684a197eaee55d130c830f8b03e Mon Sep 17 00:00:00 2001 From: jgabry Date: Thu, 8 Jan 2026 08:52:46 -0700 Subject: [PATCH 7/8] use multiple cores for testing installation on windows and linux --- tests/testthat/test-install.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index ec96a1668..f41d1545d 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -1,5 +1,8 @@ context("install") +# avoid parallel on Mac due to strange intermittent TBB errors on Github Actions +CORES <- if (os_is_macos()) 1 else 2 + cmdstan_test_tarball_url <- Sys.getenv("CMDSTAN_TEST_TARBALL_URL") if (!nzchar(cmdstan_test_tarball_url)) { cmdstan_test_tarball_url <- NULL From 236a8da01cbe7a36859cc4486809eb23cfac38aa Mon Sep 17 00:00:00 2001 From: jgabry Date: Thu, 8 Jan 2026 08:54:23 -0700 Subject: [PATCH 8/8] use multiple cores for testing installation on windows and linux --- tests/testthat/test-install.R | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index f41d1545d..ad7ad069e 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -16,7 +16,7 @@ test_that("install_cmdstan() successfully installs cmdstan", { } expect_message( expect_output( - install_cmdstan(dir = dir, cores = 1, quiet = FALSE, overwrite = TRUE, + install_cmdstan(dir = dir, cores = CORES, quiet = FALSE, overwrite = TRUE, release_url = cmdstan_test_tarball_url, wsl = os_is_wsl()), "Compiling C++ code", @@ -55,7 +55,7 @@ test_that("install_cmdstan() errors if it times out", { expect_warning( expect_message( install_cmdstan(dir = dir, timeout = 1, quiet = TRUE, overwrite = dir_exists, - cores = 1, wsl = os_is_wsl()), + cores = CORES, wsl = os_is_wsl()), if (dir_exists) "* Removing the existing installation" else "* * Installing CmdStan from https://github.com", fixed = TRUE ), @@ -67,7 +67,7 @@ test_that("install_cmdstan() errors if it times out", { expect_warning( expect_message( install_cmdstan(dir = dir, timeout = 1, quiet = FALSE, overwrite = dir_exists, - cores = 1, wsl = os_is_wsl()), + cores = CORES, wsl = os_is_wsl()), if (dir_exists) "* Removing the existing installation" else "* * Installing CmdStan from https://github.com", fixed = TRUE ), @@ -104,7 +104,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_message( expect_output( - install_cmdstan(dir = dir, overwrite = TRUE, cores = 1, + install_cmdstan(dir = dir, overwrite = TRUE, cores = CORES, release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.36.0/cmdstan-2.36.0.tar.gz", wsl = os_is_wsl()), "Compiling C++ code", @@ -116,7 +116,7 @@ test_that("install_cmdstan() works with version and release_url", { expect_warning( expect_message( expect_output( - install_cmdstan(dir = dir, overwrite = TRUE, cores = 1, + install_cmdstan(dir = dir, overwrite = TRUE, cores = CORES, version = "2.36.0", # the URL is intentionally invalid to test that the version has higher priority release_url = "https://github.com/stan-dev/cmdstan/releases/download/v2.27.3/cmdstan-2.27.3.tar.gz", @@ -192,7 +192,7 @@ test_that("toolchain checks on Windows with RTools 3.5 work", { test_that("clean and rebuild works", { expect_output( - rebuild_cmdstan(cores = 1), + rebuild_cmdstan(cores = CORES), paste0("CmdStan v", cmdstan_version(), " built"), fixed = TRUE ) @@ -220,11 +220,11 @@ test_that("Downloads respect quiet argument", { # expect_message has trouble capturing the messages from download.file # so handle manually install_normal <- suppressWarnings( - capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = FALSE, cores = 1), + capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = FALSE, cores = CORES), type = "message") ) install_quiet <- suppressWarnings( - capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = TRUE, cores = 1), + capture.output(install_cmdstan(dir = dir, overwrite = TRUE, quiet = TRUE, cores = CORES), type = "message") ) @@ -269,7 +269,7 @@ test_that("Install from release file works", { expect_message( expect_output( - install_cmdstan(dir = dir, cores = 1, quiet = FALSE, overwrite = TRUE, + install_cmdstan(dir = dir, cores = CORES, quiet = FALSE, overwrite = TRUE, release_file = destfile, wsl = os_is_wsl()), "Compiling C++ code",