From 0d1f02ff362f85d308b0a7aabb2b47427fc71a21 Mon Sep 17 00:00:00 2001 From: jgabry Date: Thu, 24 Sep 2026 11:26:25 -0600 Subject: [PATCH 1/2] Run the pure R tests on CRAN and check that configuration in CI tests/testthat.R skipped the whole suite unless NOT_CRAN was set. Six files need no CmdStan at all (the build record, stan_build_info(), JSON writing, print_stan_file() and the stanc option handling), and four more are pure apart from a few tests, so CRAN can run those. The runner now always calls test_check(), every file that needs CmdStan starts with skip_on_cran(), and the six CmdStan tests inside the mixed files skip themselves. On CRAN that is 441 tests in about five seconds. The make mock is no help here: it stands in for make and the executable's info call, but stanc still runs for real. A new workflow, "CRAN check", runs R CMD check --as-cran on ubuntu-latest with NOT_CRAN unset and no CmdStan installed, so a test that forgets its skip fails on the PR instead of on CRAN. The same configuration passes locally with the home directory and the CMDSTAN variable pointed away from the local installation: 0 failures, 55 skips, no warnings. That check's new-submission NOTE also listed three bookdown.org links in register_knitr_engine()'s help page that now redirect to pkg.yihui.org; they point at the new pages, in the vignette too. Part of #1059. --- .github/workflows/R-CMD-check-cran.yaml | 61 +++++++++++++++++++ R/knitr.R | 6 +- man/register_knitr_engine.Rd | 6 +- tests/testthat.R | 4 +- tests/testthat/README.md | 6 ++ tests/testthat/test-build-info.R | 1 + tests/testthat/test-build-record-compile.R | 2 + tests/testthat/test-cpp-options.R | 3 + tests/testthat/test-csv.R | 2 + tests/testthat/test-data.R | 2 + tests/testthat/test-example.R | 1 + tests/testthat/test-failed-chains.R | 2 + tests/testthat/test-fit-gq.R | 2 + tests/testthat/test-fit-init.R | 2 + tests/testthat/test-fit-laplace.R | 2 + tests/testthat/test-fit-mcmc.R | 2 + tests/testthat/test-fit-mle.R | 2 + tests/testthat/test-fit-shared.R | 2 + tests/testthat/test-fit-vb.R | 2 + tests/testthat/test-install.R | 2 + tests/testthat/test-installation-check.R | 2 + tests/testthat/test-knitr.R | 1 + tests/testthat/test-model-cmdstan-defaults.R | 2 + tests/testthat/test-model-code-print.R | 2 + .../testthat/test-model-compile-user_header.R | 2 + tests/testthat/test-model-compile.R | 2 + tests/testthat/test-model-data.R | 1 + tests/testthat/test-model-diagnose.R | 2 + tests/testthat/test-model-expose-functions.R | 2 + .../testthat/test-model-generate_quantities.R | 2 + tests/testthat/test-model-init.R | 2 + tests/testthat/test-model-laplace.R | 2 + tests/testthat/test-model-methods.R | 2 + tests/testthat/test-model-optimize.R | 2 + tests/testthat/test-model-output_dir.R | 2 + tests/testthat/test-model-pathfinder.R | 2 + tests/testthat/test-model-rebuild-rules.R | 2 + tests/testthat/test-model-rebuild.R | 2 + tests/testthat/test-model-sample-metric.R | 2 + tests/testthat/test-model-sample.R | 2 + tests/testthat/test-model-sample_mpi.R | 2 + tests/testthat/test-model-stale-executable.R | 2 + tests/testthat/test-model-variables.R | 2 + tests/testthat/test-model-variational.R | 2 + tests/testthat/test-opencl.R | 2 + tests/testthat/test-path.R | 2 + tests/testthat/test-profiling.R | 2 + tests/testthat/test-stan-file-functions.R | 2 + tests/testthat/test-threads.R | 2 + tests/testthat/test-utils.R | 2 + vignettes/r-markdown.Rmd | 2 +- 51 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/R-CMD-check-cran.yaml diff --git a/.github/workflows/R-CMD-check-cran.yaml b/.github/workflows/R-CMD-check-cran.yaml new file mode 100644 index 000000000..053ddca7b --- /dev/null +++ b/.github/workflows/R-CMD-check-cran.yaml @@ -0,0 +1,61 @@ +--- +# Check CmdStanR the way CRAN does: NOT_CRAN unset and no CmdStan +# installed, so only the tests that need neither run. +# yamllint disable rule:line-length + +name: CRAN check + +'on': + push: + branches: + - master + pull_request: + branches: + - master + - v1.0 + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + R-CMD-check-cran: + if: "! contains(github.event.head_commit.message, '[ci skip]')" + runs-on: ubuntu-latest + + name: ubuntu-latest (release, CRAN) + + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + PKG_SYSREQS_DB_UPDATE_TIMEOUT: 30s + + steps: + - uses: actions/checkout@v7 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: 'release' + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + cache: "always" + extra-packages: any::rcmdcheck, local::. + + - uses: r-lib/actions/check-r-package@v2 + env: + _R_CHECK_CRAN_INCOMING_: false + + - 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@v7 + with: + name: cran-check-results + path: check diff --git a/R/knitr.R b/R/knitr.R index 9560daf5f..51c8bce2b 100644 --- a/R/knitr.R +++ b/R/knitr.R @@ -25,7 +25,7 @@ #' for an example. #' #' **Note:** When running chunks interactively in RStudio (e.g. when using -#' [R Notebooks](https://bookdown.org/yihui/rmarkdown/notebook.html)), it has +#' [R Notebooks](https://pkg.yihui.org/rmarkdown-book/notebook)), it has #' been observed that the built-in, RStan-based engine is used for `stan` #' chunks even when CmdStanR's engine has been registered in the session. When #' the R Markdown document is knit/rendered, the correct engine is used. As a @@ -37,8 +37,8 @@ #' `cmdstan` engine with `override = FALSE`. #' #' @references -#' * [Register a custom language engine for knitr](https://bookdown.org/yihui/rmarkdown-cookbook/custom-engine.html) -#' * [knitr's built-in Stan language engine](https://bookdown.org/yihui/rmarkdown/language-engines.html#stan) +#' * [Register a custom language engine for knitr](https://pkg.yihui.org/rmarkdown-cookbook/custom-engine) +#' * [knitr's built-in Stan language engine](https://pkg.yihui.org/rmarkdown-book/language-engines#stan) #' #' @seealso [eng_cmdstan()] #' diff --git a/man/register_knitr_engine.Rd b/man/register_knitr_engine.Rd index fb7a0d94d..e0601086a 100644 --- a/man/register_knitr_engine.Rd +++ b/man/register_knitr_engine.Rd @@ -32,7 +32,7 @@ See the vignette for an example. \strong{Note:} When running chunks interactively in RStudio (e.g. when using -\href{https://bookdown.org/yihui/rmarkdown/notebook.html}{R Notebooks}), it has +\href{https://pkg.yihui.org/rmarkdown-book/notebook}{R Notebooks}), it has been observed that the built-in, RStan-based engine is used for \code{stan} chunks even when CmdStanR's engine has been registered in the session. When the R Markdown document is knit/rendered, the correct engine is used. As a @@ -45,8 +45,8 @@ specify \code{engine = "cmdstan"} in the chunk options after registering the } \references{ \itemize{ -\item \href{https://bookdown.org/yihui/rmarkdown-cookbook/custom-engine.html}{Register a custom language engine for knitr} -\item \href{https://bookdown.org/yihui/rmarkdown/language-engines.html#stan}{knitr's built-in Stan language engine} +\item \href{https://pkg.yihui.org/rmarkdown-cookbook/custom-engine}{Register a custom language engine for knitr} +\item \href{https://pkg.yihui.org/rmarkdown-book/language-engines#stan}{knitr's built-in Stan language engine} } } \seealso{ diff --git a/tests/testthat.R b/tests/testthat.R index 8a3cfed47..d32cadb01 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,6 +1,4 @@ library(testthat) library(cmdstanr) -if (identical(Sys.getenv("NOT_CRAN"), "true")) { - test_check("cmdstanr") -} +test_check("cmdstanr") diff --git a/tests/testthat/README.md b/tests/testthat/README.md index 37e10cd35..e23666ef9 100644 --- a/tests/testthat/README.md +++ b/tests/testthat/README.md @@ -21,6 +21,12 @@ against a mocked CmdStan, so nothing is compiled. `test-model-rebuild.R` compiles for real and checks the executable that results from a sequence of calls. +Every file that needs CmdStan starts with `skip_on_cran()`, and a test +that needs CmdStan inside an otherwise pure file calls it itself, so on +CRAN, where nothing is installed, only the pure R tests run. The +`CRAN check` workflow runs the suite the same way, with no CmdStan +installed, so a missing skip fails there rather than on CRAN. + Files that compile call `set_cmdstan_path()` at the top. `with_mocked_cli()` in `helper-mock-cli.R` stands in for `make` and for the executable's `info` call, so a test can go through the build code without a compiler. diff --git a/tests/testthat/test-build-info.R b/tests/testthat/test-build-info.R index c238063f1..63eae1e2a 100644 --- a/tests/testthat/test-build-info.R +++ b/tests/testthat/test-build-info.R @@ -324,6 +324,7 @@ test_that("untracked dependencies are ordered by kind and deduplicated", { }) test_that("a real user header is reported under dependencies and nowhere else", { + skip_on_cran() stan_file <- file.path(withr::local_tempdir(), "bernoulli_external.stan") file.copy(testing_stan_file("bernoulli_external"), stan_file) header <- withr::local_tempfile( diff --git a/tests/testthat/test-build-record-compile.R b/tests/testthat/test-build-record-compile.R index a58d8df3f..e45ea03aa 100644 --- a/tests/testthat/test-build-record-compile.R +++ b/tests/testthat/test-build-record-compile.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() # No C++ is compiled here: the mock writes a text file where make would have diff --git a/tests/testthat/test-cpp-options.R b/tests/testthat/test-cpp-options.R index 563641f68..90cf21f10 100644 --- a/tests/testthat/test-cpp-options.R +++ b/tests/testthat/test-cpp-options.R @@ -305,6 +305,7 @@ data_file <- test_path("resources", "data", "bernoulli.data.json") features <- function(mod) mod$.__enclos_env__$private$reported_features_ test_that("a feature inherited from make/local is reported, not requested", { + skip_on_cran() stan_file <- file.path(withr::local_tempdir(), "bernoulli.stan") file.copy(stan_program, stan_file) threaded <- paste0( @@ -331,6 +332,7 @@ test_that("a feature inherited from make/local is reported, not requested", { }) test_that("an executable reporting no threading flag is unknown, not off", { + skip_on_cran() stan_file <- file.path(withr::local_tempdir(), "bernoulli.stan") file.copy(stan_program, stan_file) info <- "stan_version_major=2\nstan_version_minor=39\nstan_version_patch=0" @@ -350,6 +352,7 @@ test_that("an executable reporting no threading flag is unknown, not off", { }) test_that("an executable adopted from live info reports threading as unknown", { + skip_on_cran() stan_file <- file.path(withr::local_tempdir(), "bernoulli.stan") file.copy(stan_program, stan_file) info <- "stan_version_major=2\nstan_version_minor=39\nstan_version_patch=0" diff --git a/tests/testthat/test-csv.R b/tests/testthat/test-csv.R index ada4f60f4..1a49bf4d0 100644 --- a/tests/testthat/test-csv.R +++ b/tests/testthat/test-csv.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_bernoulli_optimize <- testing_fit("bernoulli", method = "optimize", seed = 1234) fit_bernoulli_variational <- testing_fit("bernoulli", method = "variational", seed = 123) diff --git a/tests/testthat/test-data.R b/tests/testthat/test-data.R index 2392a53d4..327396208 100644 --- a/tests/testthat/test-data.R +++ b/tests/testthat/test-data.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit <- testing_fit("bernoulli", method = "sample", seed = 123) fit_vb <- testing_fit("bernoulli", method = "variational", seed = 123) diff --git a/tests/testthat/test-example.R b/tests/testthat/test-example.R index 9f8a47cb3..647c8fc5f 100644 --- a/tests/testthat/test-example.R +++ b/tests/testthat/test-example.R @@ -12,6 +12,7 @@ stan_program <- " " test_that("cmdstanr_example works", { + skip_on_cran() fit_mcmc <- cmdstanr_example("logistic", chains = 2, force_recompile = TRUE) checkmate::expect_r6(fit_mcmc, "CmdStanMCMC") expect_equal(fit_mcmc$num_chains(), 2) diff --git a/tests/testthat/test-failed-chains.R b/tests/testthat/test-failed-chains.R index b76e87001..08b8ef0fc 100644 --- a/tests/testthat/test-failed-chains.R +++ b/tests/testthat/test-failed-chains.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("chain_fails") stan_program_init_warnings <- testing_stan_file("init_warnings") diff --git a/tests/testthat/test-fit-gq.R b/tests/testthat/test-fit-gq.R index fe4e40a2b..ce0756b82 100644 --- a/tests/testthat/test-fit-gq.R +++ b/tests/testthat/test-fit-gq.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit <- testing_fit("bernoulli", method = "sample", seed = 123) fit_gq <- testing_fit("bernoulli_ppc", method = "generate_quantities", seed = 123, fitted_params = fit) diff --git a/tests/testthat/test-fit-init.R b/tests/testthat/test-fit-init.R index da602862f..57f915a3d 100644 --- a/tests/testthat/test-fit-init.R +++ b/tests/testthat/test-fit-init.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() data_list_schools <- testing_data("schools") diff --git a/tests/testthat/test-fit-laplace.R b/tests/testthat/test-fit-laplace.R index b2258a581..e7177a41a 100644 --- a/tests/testthat/test-fit-laplace.R +++ b/tests/testthat/test-fit-laplace.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_laplace <- testing_fit("logistic", method = "laplace", seed = 100) PARAM_NAMES <- c("alpha", "beta[1]", "beta[2]", "beta[3]") diff --git a/tests/testthat/test-fit-mcmc.R b/tests/testthat/test-fit-mcmc.R index 24a5769c5..b78009bfc 100644 --- a/tests/testthat/test-fit-mcmc.R +++ b/tests/testthat/test-fit-mcmc.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_mcmc <- testing_fit("logistic", method = "sample", seed = 123, chains = 2, save_metric = FALSE) diff --git a/tests/testthat/test-fit-mle.R b/tests/testthat/test-fit-mle.R index db970a1c5..40ee475df 100644 --- a/tests/testthat/test-fit-mle.R +++ b/tests/testthat/test-fit-mle.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_mle <- testing_fit("logistic", method = "optimize", seed = 123) mod <- testing_model("bernoulli") diff --git a/tests/testthat/test-fit-shared.R b/tests/testthat/test-fit-shared.R index d5a65bc9f..870367dba 100644 --- a/tests/testthat/test-fit-shared.R +++ b/tests/testthat/test-fit-shared.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fits <- list() fits[["sample"]] <- testing_fit("logistic", method = "sample", diff --git a/tests/testthat/test-fit-vb.R b/tests/testthat/test-fit-vb.R index 986f38eb2..61f5c92b8 100644 --- a/tests/testthat/test-fit-vb.R +++ b/tests/testthat/test-fit-vb.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_vb <- testing_fit("logistic", method = "variational", seed = 123) fit_vb_sci_not <- testing_fit("logistic", method = "variational", seed = 123, iter = 200000, adapt_iter = 100000) diff --git a/tests/testthat/test-install.R b/tests/testthat/test-install.R index 177eb8e88..c4eff4c97 100644 --- a/tests/testthat/test-install.R +++ b/tests/testthat/test-install.R @@ -1,4 +1,6 @@ # avoid parallel on Mac due to strange intermittent TBB errors on Github Actions +skip_on_cran() + CORES <- if (os_is_macos()) 1 else 2 cmdstan_test_tarball_url <- Sys.getenv("CMDSTAN_TEST_TARBALL_URL") diff --git a/tests/testthat/test-installation-check.R b/tests/testthat/test-installation-check.R index 0f37f4ca9..260d9ee38 100644 --- a/tests/testthat/test-installation-check.R +++ b/tests/testthat/test-installation-check.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("bernoulli") diff --git a/tests/testthat/test-knitr.R b/tests/testthat/test-knitr.R index 7d9ca3378..06a0b8686 100644 --- a/tests/testthat/test-knitr.R +++ b/tests/testthat/test-knitr.R @@ -5,6 +5,7 @@ test_that("eng_cmdstan throws correct errors", { }) test_that("eng_cmdstan works", { + skip_on_cran() skip_if_not_installed("knitr") code <- " parameters { diff --git a/tests/testthat/test-model-cmdstan-defaults.R b/tests/testthat/test-model-cmdstan-defaults.R index 100b6b8d3..f3649c803 100644 --- a/tests/testthat/test-model-cmdstan-defaults.R +++ b/tests/testthat/test-model-cmdstan-defaults.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") diff --git a/tests/testthat/test-model-code-print.R b/tests/testthat/test-model-code-print.R index 341be7bbd..8b085cf53 100644 --- a/tests/testthat/test-model-code-print.R +++ b/tests/testthat/test-model-code-print.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("bernoulli") mod <- testing_model("bernoulli") diff --git a/tests/testthat/test-model-compile-user_header.R b/tests/testthat/test-model-compile-user_header.R index 035dabebe..d1aad3327 100644 --- a/tests/testthat/test-model-compile-user_header.R +++ b/tests/testthat/test-model-compile-user_header.R @@ -1,3 +1,5 @@ +skip_on_cran() + local_mocked_stanc <- function(.local_envir = parent.frame()) { local_mocked_bindings( get_cmdstan_flags = function(flag_name, ...) character(), diff --git a/tests/testthat/test-model-compile.R b/tests/testthat/test-model-compile.R index c66f870a9..f2d30cc42 100644 --- a/tests/testthat/test-model-compile.R +++ b/tests/testthat/test-model-compile.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- cmdstan_example_file() local_cmdstan_make_local(cpp_options = list("PRECOMPILED_HEADERS"="false")) diff --git a/tests/testthat/test-model-data.R b/tests/testthat/test-model-data.R index 68eb4c745..4bde63bf3 100644 --- a/tests/testthat/test-model-data.R +++ b/tests/testthat/test-model-data.R @@ -1,4 +1,5 @@ # see separate test-json for testing writing data to JSON +skip_on_cran() set_cmdstan_path() mod <- testing_model("logistic") diff --git a/tests/testthat/test-model-diagnose.R b/tests/testthat/test-model-diagnose.R index 0ef2db687..3850855b7 100644 --- a/tests/testthat/test-model-diagnose.R +++ b/tests/testthat/test-model-diagnose.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") data_list <- testing_data("bernoulli") diff --git a/tests/testthat/test-model-expose-functions.R b/tests/testthat/test-model-expose-functions.R index c671eef96..e56112769 100644 --- a/tests/testthat/test-model-expose-functions.R +++ b/tests/testthat/test-model-expose-functions.R @@ -1,4 +1,6 @@ # Standalone functions not expected to work on WSL yet +skip_on_cran() + skip_if(os_is_wsl()) set_cmdstan_path() diff --git a/tests/testthat/test-model-generate_quantities.R b/tests/testthat/test-model-generate_quantities.R index bdb02d0dd..8da44e83a 100644 --- a/tests/testthat/test-model-generate_quantities.R +++ b/tests/testthat/test-model-generate_quantities.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit <- testing_fit("bernoulli", method = "sample", seed = 123) mod_gq <- testing_model("bernoulli_ppc") diff --git a/tests/testthat/test-model-init.R b/tests/testthat/test-model-init.R index c82d79761..4bb035abe 100644 --- a/tests/testthat/test-model-init.R +++ b/tests/testthat/test-model-init.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") data_list <- testing_data("bernoulli") diff --git a/tests/testthat/test-model-laplace.R b/tests/testthat/test-model-laplace.R index 213f36b73..41c05cde4 100644 --- a/tests/testthat/test-model-laplace.R +++ b/tests/testthat/test-model-laplace.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("logistic") data_list <- testing_data("logistic") diff --git a/tests/testthat/test-model-methods.R b/tests/testthat/test-model-methods.R index 94b6b4f93..2ecb0437b 100644 --- a/tests/testthat/test-model-methods.R +++ b/tests/testthat/test-model-methods.R @@ -1,3 +1,5 @@ +skip_on_cran() + skip_if(os_is_wsl()) set_cmdstan_path() diff --git a/tests/testthat/test-model-optimize.R b/tests/testthat/test-model-optimize.R index 658052c01..62974b069 100644 --- a/tests/testthat/test-model-optimize.R +++ b/tests/testthat/test-model-optimize.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") data_list <- testing_data("bernoulli") diff --git a/tests/testthat/test-model-output_dir.R b/tests/testthat/test-model-output_dir.R index 711388567..a8a19a53a 100644 --- a/tests/testthat/test-model-output_dir.R +++ b/tests/testthat/test-model-output_dir.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() local_output_sandbox <- function(pattern = "sandbox", .local_envir = parent.frame()) { diff --git a/tests/testthat/test-model-pathfinder.R b/tests/testthat/test-model-pathfinder.R index 73200422c..b19c45f94 100644 --- a/tests/testthat/test-model-pathfinder.R +++ b/tests/testthat/test-model-pathfinder.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("bernoulli") mod <- testing_model("bernoulli") diff --git a/tests/testthat/test-model-rebuild-rules.R b/tests/testthat/test-model-rebuild-rules.R index bc4b2a799..5d1382228 100644 --- a/tests/testthat/test-model-rebuild-rules.R +++ b/tests/testthat/test-model-rebuild-rules.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() # The decision cmdstan_model() makes: build, reuse, or adopt. No C++ is diff --git a/tests/testthat/test-model-rebuild.R b/tests/testthat/test-model-rebuild.R index fb9965efe..bce872a52 100644 --- a/tests/testthat/test-model-rebuild.R +++ b/tests/testthat/test-model-rebuild.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() # A fresh copy of a resources/stan/ program (with its include file, for diff --git a/tests/testthat/test-model-sample-metric.R b/tests/testthat/test-model-sample-metric.R index 5789e5834..0f479ccee 100644 --- a/tests/testthat/test-model-sample-metric.R +++ b/tests/testthat/test-model-sample-metric.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") data_list <- testing_data("bernoulli") diff --git a/tests/testthat/test-model-sample.R b/tests/testthat/test-model-sample.R index 59c134968..aa68b418b 100644 --- a/tests/testthat/test-model-sample.R +++ b/tests/testthat/test-model-sample.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("bernoulli") mod <- testing_model("bernoulli") diff --git a/tests/testthat/test-model-sample_mpi.R b/tests/testthat/test-model-sample_mpi.R index 9463cbbbc..9f26d3dcd 100644 --- a/tests/testthat/test-model-sample_mpi.R +++ b/tests/testthat/test-model-sample_mpi.R @@ -1,3 +1,5 @@ +skip_on_cran() + test_that("sample_mpi() works", { skip_if(!mpi_toolchain_present()) mpi_file <- write_stan_file(" diff --git a/tests/testthat/test-model-stale-executable.R b/tests/testthat/test-model-stale-executable.R index 27e16aa4e..c93163d31 100644 --- a/tests/testthat/test-model-stale-executable.R +++ b/tests/testthat/test-model-stale-executable.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() # What R/model.R's private assert_current() and its callers say about every diff --git a/tests/testthat/test-model-variables.R b/tests/testthat/test-model-variables.R index 62d24aff7..e1acfc9d7 100644 --- a/tests/testthat/test-model-variables.R +++ b/tests/testthat/test-model-variables.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() test_that("$variables() work correctly with example models", { diff --git a/tests/testthat/test-model-variational.R b/tests/testthat/test-model-variational.R index 538d7ab0c..281cfd0cf 100644 --- a/tests/testthat/test-model-variational.R +++ b/tests/testthat/test-model-variational.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() mod <- testing_model("bernoulli") data_list <- testing_data("bernoulli") diff --git a/tests/testthat/test-opencl.R b/tests/testthat/test-opencl.R index 582e11fcd..3055bff00 100644 --- a/tests/testthat/test-opencl.R +++ b/tests/testthat/test-opencl.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit <- testing_fit("bernoulli", method = "sample", seed = 123, chains = 1) diff --git a/tests/testthat/test-path.R b/tests/testthat/test-path.R index bae7c3f95..0948e8f86 100644 --- a/tests/testthat/test-path.R +++ b/tests/testthat/test-path.R @@ -1,3 +1,5 @@ +skip_on_cran() + Sys.unsetenv("CMDSTAN") PATH <- absolute_path(set_cmdstan_path()) VERSION <- cmdstan_version() diff --git a/tests/testthat/test-profiling.R b/tests/testthat/test-profiling.R index dd45c45c2..8cf08e909 100644 --- a/tests/testthat/test-profiling.R +++ b/tests/testthat/test-profiling.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() diff --git a/tests/testthat/test-stan-file-functions.R b/tests/testthat/test-stan-file-functions.R index cd967b9e8..4384ea88c 100644 --- a/tests/testthat/test-stan-file-functions.R +++ b/tests/testthat/test-stan-file-functions.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() # The standalone functions do what the model methods do, from a file alone. diff --git a/tests/testthat/test-threads.R b/tests/testthat/test-threads.R index 062356d83..e0289aa8f 100644 --- a/tests/testthat/test-threads.R +++ b/tests/testthat/test-threads.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() stan_program <- testing_stan_file("bernoulli") stan_gq_program <- testing_stan_file("bernoulli_ppc") diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index ebc08851f..ff0550391 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -1,3 +1,5 @@ +skip_on_cran() + set_cmdstan_path() fit_mcmc <- testing_fit("logistic", method = "sample", seed = 123, chains = 2) diff --git a/vignettes/r-markdown.Rmd b/vignettes/r-markdown.Rmd index 73648be89..afd9146cb 100644 --- a/vignettes/r-markdown.Rmd +++ b/vignettes/r-markdown.Rmd @@ -150,7 +150,7 @@ cache directory. ## Running interactively When running chunks interactively in RStudio (e.g. when using -[R Notebooks](https://bookdown.org/yihui/rmarkdown/notebook.html)), it has been +[R Notebooks](https://pkg.yihui.org/rmarkdown-book/notebook)), it has been observed that the built-in, RStan-based engine is used for `stan` chunks even when CmdStanR's engine has been registered in the session as the engine for `stan`. As a workaround, when running chunks *interactively*, it is recommended From 9ddd1c085be6453345330b16fd35f36f6db8ab6f Mon Sep 17 00:00:00 2001 From: jgabry Date: Thu, 24 Sep 2026 13:54:38 -0600 Subject: [PATCH 2/2] Unset NOT_CRAN in the CRAN check job r-lib/actions/setup-r exports NOT_CRAN=true, so the first run of the workflow evaluated the vignettes and failed when the internals vignette asked for a CmdStan path. CRAN leaves the variable unset, so the check step now sets it to false, which the vignettes' EVAL parameter and skip_on_cran() both read as "on CRAN". Checked locally with rcmdcheck building the vignettes and no CmdStan visible: 0 errors, 0 warnings. Building the vignettes also surfaced two URLs the earlier check did not reach: the qs2 repository moved to qsbase/qs2, and the CRAN policies link loses its anchor, which R's URL check treats as a non-canonical CRAN URL. Part of #1059. --- .github/workflows/R-CMD-check-cran.yaml | 3 +++ vignettes/cmdstanr-internals.Rmd | 2 +- vignettes/cmdstanr.Rmd | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/R-CMD-check-cran.yaml b/.github/workflows/R-CMD-check-cran.yaml index 053ddca7b..d24de2342 100644 --- a/.github/workflows/R-CMD-check-cran.yaml +++ b/.github/workflows/R-CMD-check-cran.yaml @@ -44,8 +44,11 @@ jobs: cache: "always" extra-packages: any::rcmdcheck, local::. + # setup-r exports NOT_CRAN=true, which would evaluate the vignettes and + # run every test; CRAN leaves it unset. - uses: r-lib/actions/check-r-package@v2 env: + NOT_CRAN: false _R_CHECK_CRAN_INCOMING_: false - name: Show testthat output diff --git a/vignettes/cmdstanr-internals.Rmd b/vignettes/cmdstanr-internals.Rmd index ef4b7b11e..91b09edc3 100644 --- a/vignettes/cmdstanr-internals.Rmd +++ b/vignettes/cmdstanr-internals.Rmd @@ -525,7 +525,7 @@ installation from source. Installation-time compilation builds executables on the installing system so they can be reused without recompilation at runtime. This is different from including compiled executables in the source package: compiled artifacts are generally not portable across platforms, and -[CRAN source packages may not contain binary executable code](https://cran.r-project.org/web/packages/policies.html#Source-packages). +[CRAN source packages may not contain binary executable code](https://cran.r-project.org/web/packages/policies.html). The [`instantiate`](https://wlandau.github.io/instantiate/) package provides a current workflow for installation-time compilation. See the `instantiate` diff --git a/vignettes/cmdstanr.Rmd b/vignettes/cmdstanr.Rmd index 86c287b5e..496f64923 100644 --- a/vignettes/cmdstanr.Rmd +++ b/vignettes/cmdstanr.Rmd @@ -479,7 +479,7 @@ fit2 <- readRDS("fit.RDS") But if your model object is large, then `fit$save_object()` can take a long time if saving in the default RDS format. For large objects, we recommend using the -much faster [`qs2`](https://github.com/traversc/qs2) format. The saved object +much faster [`qs2`](https://github.com/qsbase/qs2) format. The saved object can then be read back into R using `qs2::qs_read()`. ```{r save_object_qs_full, eval = FALSE}