Skip to content

Add testthat-module reusable workflow - #44

Merged
eliotmcintire merged 3 commits into
mainfrom
feat/testthat-module-workflow
Sep 10, 2026
Merged

eliotmcintire merged 3 commits into
mainfrom
feat/testthat-module-workflow

Conversation

@eliotmcintire

Copy link
Copy Markdown
Contributor

Runs a SpaDES module's testthat suite. This is the CI half of the module release wave — until now only the 6 CBM modules ran tests in CI, via a workflow that depended on a personal fork; the other ~200 module repos either render an Rmd or have no workflow at all.

It is render-module-rmd.yaml with two jobs swapped out

Everything above the render step — spatial system deps, the apt retry wrapper, install-Require, install-SpaDES, and dependency resolution straight from the module's own reqdPkgs via SpaDES.core::packages() — is deliberately identical, so a fix to one is a fix to both. That includes the hard-won details: the -reusable concurrency suffix (#33), GITHUB_PAT on the job, single-indexing packages(...)[[1]], and [skip-ci] read from head_commit (#34).

There is no commit job, and the omission is load-bearing. The workflow runs convertToPackage(), which rewrites a module and is not reversible. Nothing it produces may be pushed back. Since it is a near-copy of a workflow that does commit, this is called out in the file itself so nobody restores it by symmetry.

Three decisions

The module is tested as a package. A module keeps its functions inline in <module>.R, so without conversion they are only parsed into a simList and a test cannot call one directly — you would write sim@.xData$.mods$myModule$myHelper(3L). convertToPackage(destinationPath = ) builds the rendition in a throwaway directory, leaving the module untouched, and the tests run against a real namespace, so expect_equal(myHelper(3L), 6L) works as in any package. Verified end to end locally.

A module with no tests passes. Almost every module currently carries only the dead newModule() scaffolding (test-template.R with C:/Users/yonluo/... paths). Failing hard would paint the whole family red for the absence of tests rather than for a defect. The workflow reports "no tests" in the job summary and exits clean.

Coverage goes to the job summary, not codecov. Module repos have no CODECOV_TOKEN and no codecov.yml, and ~28 modules with near-zero tests would create 28 projects reading 0–5% with no history for the house target: auto ratchet to compare against. SpaDES.core::moduleCoverage() reports against <module>.R rather than the generated R/ copy — see PredictiveEcology/SpaDES.core#441.

One temporary step

install-SpaDES installs the released SpaDES.core, which does not have convertToPackage(destinationPath = ) or moduleCoverage() (SpaDES.core #440 and #441, both merged to development). Until a release carries them, the workflow installs SpaDES.core@development explicitly. The step is commented as removable and names the PRs.

Also added

  • examples/testthat-module.caller.yaml — the call site
  • examples/module-tests-setup.R — a starting tests/testthat/setup.R for a module, which sets options and a scratch tree and deliberately installs nothing

Not yet done

This has not run against a real module. I intend to pilot it on one small module (historicFires) before rolling callers out to the wave, rather than opening 28 PRs against an untested workflow.

🤖 Generated with Claude Code

https://claude.ai/code/session_0125hLaqRWaPcutdboenVK2g

eliotmcintire and others added 2 commits September 10, 2026 07:18
Runs a SpaDES module's testthat suite. It is render-module-rmd.yaml with the
render and commit jobs replaced by a test run; everything above them is
deliberately identical, so a fix to one is a fix to both.

There is no commit job, and the omission is load-bearing: the workflow runs
convertToPackage(), which rewrites a module and is not reversible, so nothing it
produces may be pushed back to the repository.

The module is tested as a package. A module keeps its functions inline in
<module>.R, so without conversion they are only ever parsed into a simList and a
test cannot call one directly. convertToPackage(destinationPath = ) builds the
rendition in a throwaway directory and the tests run against a real namespace.
Verified end to end locally: a test calling myHelper(3L) directly passes.

A module with no tests reports that and passes rather than failing. Almost every
module currently carries only the dead newModule() scaffolding, and failing hard
would paint the family red for the absence of tests rather than for a defect.

Coverage goes to the job summary rather than codecov: module repositories have no
CODECOV_TOKEN and no codecov.yml, and ~28 modules with near-zero tests would
create 28 projects reading 0-5% with no history for the target: auto ratchet to
compare against.

Carries a temporary step installing SpaDES.core@development, because
install-SpaDES installs the released SpaDES.core which lacks
convertToPackage(destinationPath = ) and moduleCoverage(). Remove once released.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125hLaqRWaPcutdboenVK2g
testthat runs with the working directory set to tests/testthat, so the module
directory is two levels up and SpaDES.core's modulePath -- the directory
containing modules -- is three, not one. Getting this wrong is silent: the module
is simply not found and tests fail on something unrelated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0125hLaqRWaPcutdboenVK2g
pkgload, roxygen2, testthat, covr and withr are only in SpaDES.core's
Suggests, so install-SpaDES does not provide them. The pilot run on
fireSense_EscapeFit#4 died in convertToPackage() before any test ran:
requireNamespace("pkgload", quietly = TRUE) is not TRUE.

render-module-rmd gets its tools from install-Rmd-pkgs; this is the
counterpart that was missing when the render job was replaced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133867aFrmKtbhpNXasToP9
@eliotmcintire
eliotmcintire merged commit 2229d06 into main Sep 10, 2026
1 check passed
@eliotmcintire
eliotmcintire deleted the feat/testthat-module-workflow branch September 10, 2026 17:01
eliotmcintire added a commit to PredictiveEcology/fireSense_EscapeFit that referenced this pull request Sep 10, 2026
PredictiveEcology/actions#44 merged and its branch was deleted, so the
@feat/testthat-module-workflow ref no longer resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133867aFrmKtbhpNXasToP9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant