feat: add a reusable render-module-rmd.yaml workflow - #37
Merged
Conversation
Every SpaDES module repository carries a hand-generated copy of this job, written once by SpaDES.core::use_gha() and never regenerated. The survey in #36 found 74 repositories carrying it across 96 repository/branch combinations, in two generations that had drifted apart: 46 combinations still on ubuntu-20.04 with checkout@v2 and setup-r@v1, and 50 on the newer shape pinning five actions from this repository at @v0.2, @v0 or @v0.0.1. Those pins are the main thing blocking retirement of v0.1-v0.5. A caller now supplies its triggers and the module name; the pins live here and move once. Fixes carried in by the move: - [skip-ci] tested commits[0], the OLDEST commit in a push, and there is no commits field at all on pull_request -- so it worked on neither. Now uses head_commit, as in #34. - No concurrency group, so superseded runs were never cancelled (#30). - The hand-written apt-get install had no apt-get update, no retries and no timeout. That is the shape that left two LandWebUtils jobs sitting 6h on 2026-08-19. Now uses the same retry wrapper as install-spatial-deps. - The commit step ran on pull_request too, where github.ref is refs/pull/N/merge and the push cannot succeed; it failed silently every time, swallowed by `|| echo "No changes to commit"`. Now push-only. Rendering and committing are separate jobs, as in citation.yaml (#35): rendering installs the module's dependency tree and then executes the module's own .Rmd, which must not share a job with a write-scoped token. setup-r-deps is deliberately not used here. It delegates to r-lib/actions/setup-r-dependencies, which resolves from a DESCRIPTION, and modules have none -- their dependencies come from SpaDES.core::packages(). The apt hardening is reproduced instead. The second install-Rmd-pkgs call is preserved rather than dropped: the generated file had it, installing SpaDES can move versions the first call settled, and #36 flags it for someone with the history to confirm or remove. Refs #36. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZoicL7829pkb5ZbS5Ciww
Contributor
Author
|
Merging as this has no effect yet; but it is needed to proceed to following steps in the #36 |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements step 1 of #36.
Adds
.github/workflows/render-module-rmd.yaml, so the module render job stops being a file that each module repository owns a frozen copy of.The problem this solves
From the survey in #36: 74 module repositories carry a hand-generated copy of this job, across 96 repository/branch combinations. Nobody writes it —
SpaDES.core::use_gha()writes it once, and it is never regenerated. So the file has frozen into two generations:ubuntu-20.04,checkout@v2,setup-r@v1, hand-written apt block, nothing from this repoubuntu-latest,checkout@v4, five actions from this repo at@v0.2/@v0/@v0.0.1Those pins are the main reason
v0.1–v0.5cannot be retired. After this, a caller names one ref and the five pins live here.Bugs fixed by the move
These were all in the generated file, in every copy of it:
[skip-ci]worked on neither event. It testedgithub.event.commits[0].message—commits[0]is the oldest commit in a push, so[skip-ci]on the tip was ignored; andpull_requestpayloads have nocommitsfield at all, so it never applied there. Now useshead_commit, matching feat: honour [skip-ci] org-wide; add a reusable revdeps workflow #34.concurrencygroup, so superseded runs were never cancelled — 74 repositories outside the protection feat: cancel superseded runs to stop burning the shared concurrency budget #30 gave the packages.apt-get update, no retries and no timeout. That is the exact shape that left two LandWebUtils jobs sitting for 6h0m on 2026-08-19 before being killed. Now uses the same retry wrapper asinstall-spatial-deps.pull_requesttoo, wheregithub.refisrefs/pull/N/mergeand the push cannot succeed. It failed silently every time, swallowed by|| echo "No changes to commit". Now push-only.Privilege split
Same as
citation.yaml(#35), and the argument is stronger here: rendering installs the module's whole dependency tree and then executes the module's own.Rmd. That must not share a job with a token that can push.rendergetscontents: readand uploads an artifact;commitgetscontents: writeand runs nothing but git.Callers grant
contents: writeon the calling job — a called workflow can only reduce permissions, never widen them.Inputs
module<module>.R/<module>.Rmdbasenamer-versionreleasesystem-depstruefalseextra-apt""Two deliberate deviations from #36, worth review
setup-r-depsis not used. #36 proposed folding it in. It can't be: it delegates tor-lib/actions/setup-r-dependencies, which resolves from aDESCRIPTION, and modules have none — their dependencies come fromSpaDES.core::packages()+Require::Require(). The apt hardening is reproduced inline instead. Worth revisiting ifsetup-r-depsever grows apackages:passthrough.The second
install-Rmd-pkgscall is kept. The generated file calls it twice, once beforeinstall-Requireand once afterinstall-SpaDES. #36 flagged this as possibly deliberate — installing SpaDES can move versions the first call settled — so it is preserved rather than silently dropped. If someone knows the history and it is vestigial, say so and I will remove it.One assumption made explicit
The module name must equal the repository name. This is already baked into the generated file: it calls
SpaDES.core::packages(modules = "<name>", paths = ".."), which only resolves becauseactions/checkoutputs the repo at/home/runner/work/<repo>/<repo>— so..is the module directory. It held for every module surveyed, but it is now stated in a comment rather than implied.Not in this PR
Steps 2–4 of #36: changing the generator in SpaDES.core, updating the 74 existing repositories, and deleting the tags. This is just the piece they depend on.
examples/render-module-rmd.caller.yamlshows the ~20-line caller the generator will emit.Testing
self-test.yamlstill cannot exercise a reusable workflow — it checks out the caller and runs at its root, and this repo has no module. So this lands with the same verification gap as the other six templates; the first real test is a module repository calling it, which is step 3.🤖 Generated with Claude Code
https://claude.ai/code/session_015ZoicL7829pkb5ZbS5Ciww