Skip to content

fix(ci): locate Rscript under R.home("bin") in the scheduled site legs - #88

Merged
ShixiangWang merged 1 commit into
mainfrom
ci/rhome-bin-and-cache-input
Nov 7, 2026
Merged

ShixiangWang merged 1 commit into
mainfrom
ci/rhome-bin-and-cache-input

Conversation

@ShixiangWang

Copy link
Copy Markdown
Contributor

What

Repairs the scheduled site leg — red since 2026-10-22 (last green 0322d38,
run 39722405686) — and re-arms the selfcheck law that should have caught it.

Root cause, measured twice

Two shapes of one defect, both invisible to the step's own guard:

Run Job Shape
42216557267 127887921027 bare closure — R.home read without call parens → cannot coerce type 'closure' to vector of type 'character'
42367209708 128387675594 binless call — file.path(R.home(), "Rscript") names <home>/Rscript, a path that exists on no Linux R install → error in running command / Execution halted

PR #80 (5396971 fix(ci): call R.home() in the scheduled site legs) moved the
failure from the first shape to the second; it did not fix the leg. Both shapes
leave attr(res, "status") NULL when the spawn never happens, so the leg's own
if (!is.null(st) && st != 0L) stop(...) guard cannot fire. This must be a
source law, not a runtime probe.

Fix

  • Both spawn sites (site bundle, deploy guard) now use
    file.path(R.home("bin"), "Rscript"), the spelling already in use at
    ci.yml:705.
  • tools/ci-selfcheck.py gains binless_rhome_hits plus a gating check, and
    the pre-existing bare_rhome_hits discriminator is corrected from != "()"
    to != "(" so the argument-bearing call is no longer mis-flagged as a bare
    closure.
  • Firing controls widened in the same change: both measured typo shapes must
    redden, and R.home(), R.home("bin"), and file.path(R.home("bin"), "R")
    must pass.
  • use-cache: true dropped from the CRAN-shape monolith's
    setup-r-dependencies step. The pinned v2 action declares cache (required,
    default 'true') and has no use-cache input, so the line was silently
    ignored while caching was already on — a behaviour-neutral removal.

Evidence

  • Positive control: binless_rhome_hits returns 2 hits on main, 0 on this
    tree
    .
  • python3 tools/ci-selfcheck.py → exit 0, zero FAIL lines, all four R.home
    checks PASS.
  • tests/testthat/test-cjk-census.R → 23 pass, 0 fail (it covers both edited
    files, and no new non-ASCII was introduced).

Test plan

  • guards job green — python3 tools/ci-selfcheck.py is a named PR-gate
    step (ci.yml:145), so the new law gates this PR itself.
  • After merge: re-dispatch .github/workflows/scheduled.yml and convert the
    site job from red to measured green.

The scheduled site job has been red since 2026-10-22 and was root-caused
to two shapes of the same defect, both guard-blind:

  run 42216557267 site job 127887921027 -- bare closure: `R.home` was read
  without its call parens, so system2() received a function object.
  run 42367209708 site job 128387675594 -- binless call: `R.home()` was
  called, but `file.path(R.home(), "Rscript")` names `<home>/Rscript`,
  which exists on no Linux R installation. system2() fails to spawn, the
  "error in running command" surfaces with a NULL `status` attribute, and
  the step's own `attr(res, "status")` guard is structurally blind to it.

Both spawn sites (site bundle, deploy guard) now use
file.path(R.home("bin"), "Rscript"), which is the spelling already used at
ci.yml:705.

The selfcheck law that should have caught this was blind in two ways, and
both are repaired here:

  * `bare_rhome_hits` compared the two characters after `R.home` against
    the literal "()", so it flagged the correct `R.home("bin")` call as a
    bare closure. The discriminator is the single `(` that follows a real
    call; the firing control was widened to pin the argument-bearing form.
  * No law covered the binless call at all. `binless_rhome_hits` now scans
    every workflow for `file.path(R.home(), ...)` and a gating check
    reddens on it, with a firing control that pins the measured typo, the
    bin-bearing form, a bare `R.home()` read, and a `file.path(R.home("bin"),
    "R")` non-binary.

Positive control: `binless_rhome_hits` returns 2 hits on main and 0 on this
tree. The law is Linux-exact -- darwin ships a `<home>/Rscript` shim, so
the runner is the only place this can be measured.

Also drops `use-cache: true` from the CRAN-shape monolith's
setup-r-dependencies step. The pinned v2 action declares `cache` (required,
default 'true') and has no `use-cache` input, so the line was silently
ignored while caching was already on: the removal is behaviour-neutral.
@ShixiangWang
ShixiangWang merged commit fb85398 into main Nov 7, 2026
9 checks passed
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