Skip to content

chore: remove the dead revdeps-check action, close the self-test coverage gap, fix the docs - #29

Closed
achubaty wants to merge 6 commits into
mainfrom
chore/ci-housekeeping
Closed

chore: remove the dead revdeps-check action, close the self-test coverage gap, fix the docs#29
achubaty wants to merge 6 commits into
mainfrom
chore/ci-housekeeping

Conversation

@achubaty

@achubaty achubaty commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Housekeeping wave: a dead action, a coverage gap that made a green check meaningless, four documentation drifts, and the repository's first dependency tracking. Every finding below was re-verified against this repository, the tags, and the org before it was acted on.

Deliberately disjoint from #28 (the reusable-workflow consolidation): this PR does not touch R-CMD-check.yaml, test-coverage.yaml, pkgdown.yaml, test-downstream.yaml or setup-r-deps/action.yaml. Overlap is limited to two files and is described at the bottom.


1. revdeps-check removed (7bd056b)

Three defects, verified in R rather than by reading:

isTRUE("true")                      #> FALSE   -- for every string, always
as.difftime("30", units = "mins")   #> Time difference of NA mins
  • cranonly never worked. isTRUE("${{ inputs.cranonly }}") is FALSE for every value the template can produce, so the CRAN-only branch was unreachable and the else branch always ran. Not a harmless no-op: the crancache key does interpolate inputs.cranonly, so setting it bought a separate cache namespace holding an identical revdep set.
  • timeout never worked. as.difftime() parses a character argument with strptime(format = "%X"); "30" is not a time of day, so revdep_check(timeout = NA) is what has always been passed — in an action whose own README says these checks are "too resource intensive for standard GitHub runners".
  • pak was never installed. Step one calls pak::pkg_install(); r-lib/actions/setup-r does not ship pak, and the README's usage example shows exactly that setup.
  • And a fourth, found while assessing the fix: the Check reverse dependencies step recomputes the revdep set unconditionally from revdepcheck.extras, ignoring cranonly entirely. The two steps disagree about what is being checked, so fixing the isTRUE alone would have been wrong.

Deleted rather than fixed, because the evidence says unmaintained and unmaintainable here:

evidence state
quickPlot/.github/workflows/revdeps.yaml (the only consumer in the org) disabled_manually, 0 recorded runs
SpaDES.tools runs revdepcheck locally from revdep/check.R
self-test coverage impossible by the action's own README

A "fixed" version would be untested code that merely looks maintained — which is how it got here. Nothing breaks that was working: @v0.5 and every earlier tag still carry the action, and git revert 7bd056b restores it.

2. self-test.yaml: three actions were in paths: with no job (915edbf)

install-Require/**, install-Rmd-pkgs/** and install-SpaDES/** all triggered the workflow, which then ran setup-r-deps, stage-gdrive-auth and install-spatial-deps and went green. A green check meaning "not tested" is the same signal as "tested and fine".

Jobs added for all three, Linux-only (Require::setLinuxBinaryRepo() is a no-op off Ubuntu/Debian, and every consumer runs ubuntu-latest). Writing them turned up three real problems:

  • install-Require's default is asserted, not assumed. The job calls the action with no with: and then reads RemoteRef out of the installed DESCRIPTION, so "the default silently stopped resolving" fails the build. A second leg passes GitTag: main to prove the input is honoured rather than ignored.
  • The ordering dependency is real and already violated in the org. install-Rmd-pkgs and install-SpaDES both open with Require::setLinuxBinaryRepo(), so they die with "there is no package called 'Require'" unless install-Require ran earlier in the same job — and SpaDES.core's own inst/templates/render-module-rmd.yaml.template calls install-Rmd-pkgs (line 51) before install-Require (line 53). The jobs encode the order that works; both READMEs now state it as a requirement.
  • The SpaDES metapackage is archived on CRAN — 2026-07-13, "requires archived package 'reproducible'"; available.packages() does not list it and src/contrib/SpaDES_2.0.11.tar.gz is 404. Require::Require("SpaDES") is the whole of install-SpaDES, so the action cannot resolve from CRAN today. The job adds extra-repositories: https://predictiveecology.r-universe.dev (which carries 2.0.11.9000); setLinuxBinaryRepo() inserts Posit's binary repo before the CRAN mirror and preserves the rest of getOption("repos"), so the entry survives into the action. Documented in the action's README too.

Every path in the paths: filter now has a job behind it.

3. Documentation (56634a0) and licensing (fd74c00)

  • install-Require/README.md documented GitTag as defaulting to "master". git ls-remote https://github.com/PredictiveEcology/Require.git lists no master branch and no master tag — the documented default named a ref that does not exist.
  • setup-r-deps/README.md said "Pin to a tag or SHA rather than @main". That contradicts the org standard settled in ci: pin the reusable workflows to @main instead of c2b2459 SpaDES.tools#124, and it is advice that cannot be followed: setup-r-deps and stage-gdrive-auth postdate v0.5, so no published tag contains either action (git cat-file -e v0.5:setup-r-deps/action.yaml → absent, for every tag). For the actions that do exist at a tag, following it means pinning the ubuntugis PPA (see §4). And a pin buys less than it appears to: the reusable workflows resolve setup-r-deps@main at run time.
  • Root README.md listed five actions, omitting setup-r-deps, stage-gdrive-auth and all four reusable workflows. Rewritten: composite actions and reusable workflows in two tables, and "Releases and tags" becomes "Which ref to use" — @main, with the three reasons.
  • install-SpaDES/README.md still said the metapackage comes from CRAN (see §2).
  • setup-r-deps and stage-gdrive-auth had no LICENSE; every older action directory ships one. Added, MIT, 2026.

4. Tag hygiene — findings and recommendation (nothing executed)

Verified, with git show <tag>:install-spatial-deps/action.yaml:

tag ppa:ubuntugis/ubuntugis-unstable
v0, v0.0.1 action does not exist yet
v0.1, v0.2, v0.3 yessudo add-apt-repository -y …
v0.4, v0.5 yesretry 5m "sudo -E add-apt-repository -y …"
main no (removed in #24)

Who is pinned (GitHub code search across org:PredictiveEcology, 62 files in 26 repos — a lower bound, since only indexed default branches are searched):

ref repos
install-spatial-deps@v0.2 14
install-spatial-deps@50d9a4d2… (SpaDES.tools) 1 — that SHA is v0.2's commit, so it carries the PPA too
install-spatial-deps@v0.1 1 (LandR)
install-spatial-deps@v0.3 1 (quickPlot)
install-spatial-deps@v0.4, @v0.5 0
install-Require@v0.2 / @v0 / @v0.0.1 7 / 3 / 1
install-Rmd-pkgs@v0.2, install-SpaDES@v0 3, 3
install-spatial-deps@main 4

So ~17 repos are pinned to a PPA-carrying install-spatial-deps, and the two newest tags have no consumers at all.

The pins cluster in two copy-pasted files, which is where a migration should start:

  • update-citation-cff.yaml in the flagship packages — SpaDES.tools (@50d9a4d2b92e…, which is v0.2's commit: git rev-parse v0.2^{commit} matches it exactly), reproducible (@v0.2), SpaDES.core (@v0.2);
  • render-module-rmd.yaml in the module repos, all seeded from SpaDES.core's inst/templates/render-module-rmd.yaml.template (@v0.2).

Options

  1. Delete v0.1v0.5. Turns a latent ABI bug into an immediate org-wide Unable to resolve action outage across ~20 repos, each needing its own PR before CI runs again, and takes the last copy of revdeps-check with it. The failure mode is worse than the bug. No.
  2. Cut v0.6 from current main. Cheap, non-destructive, and the first tag that would actually be correct (no PPA, macOS PROJ_DATA, version assertions, and the first to contain setup-r-deps/stage-gdrive-auth). Does nothing by itself for anyone pinned to v0.2. Yes, but second.
  3. Deprecation note on each release body. Zero risk, zero effect on running CI, and visible only to someone browsing the releases page — not to the person staring at libgdal.so.34: cannot open shared object file. Worth doing; not a fix.
  4. Move everyone to @main. One-line, mechanically greppable change per repo; fixes the ABI break for real and picks up every subsequent fix. The usual objection (moving target) is already answered here: self-test.yaml gates main, and a pin never froze the composite actions anyway.
  5. (considered, rejected) Re-point v0.2 at a fixed commit. Would fix every consumer with no PR, but silently changes the meaning of a published ref — and v0.2's install-Require/install-Rmd-pkgs would jump ~18 months in the process. It destroys the only guarantee a tag offers.

Recommendation: 4, then 2, with 3 as a cheap supplement. Not 1, not 5.

  • Migrate consumers to @main, starting with the 14 repos on install-spatial-deps@v0.2 and SpaDES.tools' SHA pin.
  • Fix SpaDES.core/inst/templates/render-module-rmd.yaml.template first, or new module repos keep being created with both bugs — it seeds @v0.2 pins and the broken action order from §2.
  • Cut v0.6 from main once refactor(ci): route every reusable workflow through setup-r-deps; drop the retry fallback #28 lands, so anyone who must pin has a correct tag.
  • Add a one-line note to the v0.1v0.5 release bodies naming the PPA.
  • Leave the tags in place. If the org ever does delete any, v0.4 and v0.5 are the free ones — nothing references them.

5. Supply chain (8a8b35a)

.github/dependabot.yml added for the github-actions ecosystem: two blocks (/ for the workflows, /setup-r-deps for the only composite action with a third-party uses:), grouped, monthly, conventional-commit prefix. Dependabot leaves branch refs alone, so the internal …@main pins are untouched.

Not re-pinned here — these are #28's files. For that pass, by priority:

file needs a SHA pin
pkgdown.yaml JamesIves/github-pages-deploy-action@v4 ← third-party with contents: write, highest priority; actions/checkout@v7; r-lib/actions/{setup-pandoc,setup-r,setup-r-dependencies}@v2
test-downstream.yaml nick-fields/retry@v3, actions/upload-artifact@v4, actions/checkout@v7 ×2, r-lib/actions/*@v2 ×4
test-coverage.yaml actions/checkout@v7, r-lib/actions/*@v2 ×3
R-CMD-check.yaml actions/checkout@v7, r-lib/actions/check-r-package@v2
setup-r-deps/action.yaml nick-fields/retry@v3, r-lib/actions/*@v2 ×5
self-test.yaml (this PR) actions/checkout@v7, r-lib/actions/setup-r@v2 — left floating on purpose, so the conversion happens in one pass rather than half of it here

Drift worth fixing in that pass: NEWS.md under v0.4 records "nick-fields/retry v3 -> v4". Both call sites are still on v3.


Overlap with #28

git merge-tree against ci/route-workflows-through-setup-r-deps: NEWS.md and .github/workflows/self-test.yaml auto-merge cleanly (different regions — this PR appends jobs at the end of the file, #28 edits the setup-r-deps job). One conflict, in setup-r-deps/README.md: #28 adds a needs row to the inputs table three lines below the pinning sentence this PR rewrites. Whichever merges second takes both edits; there is no disagreement about content.

Validation

  • every YAML in the repo re-parsed (yaml.safe_load) and actionlint clean, repo-wide, at each commit;
  • R semantics checked by running them, not by reading (isTRUE, as.difftime);
  • tag claims checked with git show <tag>:…, git cat-file -e; ref existence with git ls-remote; consumers with GitHub code search; CRAN archival against available.packages() and cran.r-project.org.

🤖 Generated with Claude Code

achubaty and others added 6 commits August 31, 2026 17:48
…SpaDES

The `paths:` filter already listed all three, so editing any of them fired
self-test -- which then ran setup-r-deps, stage-gdrive-auth and
install-spatial-deps and went green. A green check that means "not tested" is
worse than no check: it is the same signal as "tested and fine", and these are
the three oldest actions in the repo, the ones most likely to have rotted.

They had. Three findings fell straight out of writing the jobs:

- **install-Require's default was dead.** It was `master`, and
  PredictiveEcology/Require has no `master` branch and no `master` tag --
  `git ls-remote` lists neither -- so the documented default was a hard
  `install_github` failure. The default is `development` now; the job asserts
  it by reading `RemoteRef` out of the installed DESCRIPTION, so it fails if
  the default ever silently stops resolving again. A second leg passes
  `GitTag: main` to prove the input is honoured and not ignored.

- **install-Rmd-pkgs and install-SpaDES cannot run before install-Require.**
  Both open with `Require::setLinuxBinaryRepo()`, so without Require already
  installed in the same job they die with "there is no package called
  'Require'". An action cannot declare that dependency, and the org already
  gets it wrong: SpaDES.core's `render-module-rmd.yaml.template` calls
  install-Rmd-pkgs *before* install-Require. These jobs encode the working
  order and comment why.

- **the `SpaDES` metapackage is archived on CRAN** (2026-07-13, "requires
  archived package 'reproducible'"). `Require::Require("SpaDES")` is the whole
  of install-SpaDES, and it cannot resolve from CRAN today, so the job adds
  `extra-repositories: https://predictiveecology.r-universe.dev`, which carries
  2.0.11.9000. `setLinuxBinaryRepo()` inserts Posit's binary repo before the
  CRAN mirror and keeps the rest of `getOption("repos")`, so the entry survives
  into the action.

Linux-only, because `setLinuxBinaryRepo()` is a no-op off Ubuntu/Debian and
every consumer of these actions in the org runs `ubuntu-latest`. `GITHUB_PAT`
is set per job because all three install from GitHub and unauthenticated
api.github.com calls are rate-limited per (shared) runner IP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… dead

Verified, one at a time:

- `isTRUE("${{ inputs.cranonly }}")` -- `isTRUE()` of a character vector is
  `FALSE` in R for every value the template can produce ("true", "TRUE", "1"),
  so the CRAN-only branch was unreachable and the `else` branch always ran.
  Not a no-op, either: the crancache key *does* interpolate
  `inputs.cranonly`, so a caller who set it got a separate cache namespace
  holding an identical revdep set;

- `as.difftime("30", units = "mins")` is `NA mins` -- `as.difftime()` parses a
  character argument with `strptime(format = "%X")`, and "30" is not a time of
  day. So `revdep_check(timeout = NA)` is what has always been passed, in an
  action whose own README says these checks are "too resource intensive for
  standard GitHub runners". A silently-NA timeout is the worst possible
  failure mode there;

- the first step calls `pak::pkg_install()` and nothing installs pak.
  `r-lib/actions/setup-r` does not ship it, and the README's usage example
  shows exactly that setup, so anyone following the documentation got
  "there is no package called 'pak'" on step one;

- and the fix for the first item would not have been one line: the *Check
  reverse dependencies* step recomputes the revdep set unconditionally from
  `revdepcheck.extras`, ignoring `cranonly` outright, so the two steps
  disagree about what is being checked.

Deleting rather than fixing. The action has one consumer in the org --
`quickPlot`'s `revdeps.yaml` -- and that workflow is `disabled_manually` with
zero recorded runs, so nothing has exercised this code. `SpaDES.tools`, the
other repo with revdeps to check, runs `revdepcheck` locally from
`revdep/check.R`. A fixed version could not be verified either: self-test
cannot run it, by the README's own admission, so "fixed" would mean untested
code that merely looks maintained -- which is how it got here.

Nothing breaks that was working. `@v0.5` and every earlier tag still carry the
action, and `git revert` restores it if the org would rather host revdep
checks here than run them locally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…list

Four verified drifts, in rough order of how much damage each does:

- **`setup-r-deps/README.md` told readers to pin.** "Pin to a tag or SHA rather
  than `@main`" is the opposite of the org standard settled in
  PredictiveEcology/SpaDES.tools#124, and it is advice that cannot be followed:
  `setup-r-deps` and `stage-gdrive-auth` postdate `v0.5`, so **no published tag
  contains either action** -- `@v0.5` resolves to "action not found". Worse, a
  reader who pinned an action that *does* exist at a tag would be pinning the
  ubuntugis-unstable PPA, which every tag from `v0.1` to `v0.5` still adds
  (`git show v0.5:install-spatial-deps/action.yaml`), i.e. the libgdal37 /
  libgdal34 ABI break this repository spent months removing. And a pin buys
  less than it looks: the reusable workflows resolve
  `setup-r-deps@main` at run time, so a SHA-pinned caller still gets main's
  actions;

- **`install-Require/README.md` documented `GitTag` as defaulting to
  `"master"`.** The action moved to `development`, and
  `PredictiveEcology/Require` has no `master` branch and no `master` tag at all
  -- `git ls-remote` lists neither -- so the documented default was not merely
  stale, it named a ref that does not exist;

- **the root README listed five actions.** It omitted `setup-r-deps` and
  `stage-gdrive-auth`, the two that every reusable workflow now runs through,
  and all four reusable workflows, which are the repository's main product.
  Its "Releases and tags" section is now "Which ref to use" and gives the
  three concrete reasons for `@main`;

- **`install-SpaDES/README.md` said the metapackage comes from CRAN.** `SpaDES`
  was archived there on 2026-07-13 ("requires archived package
  'reproducible'"), so `Require::Require("SpaDES")` cannot resolve from CRAN;
  the README now says to add the org r-universe, as the new self-test job does.

Also: the ordering dependency on `install-Require` is now stated as a hard
requirement in both dependent READMEs rather than a "note", and the usage
examples move off `actions/checkout@v3` (deprecated Node.js 20 runtime) and off
tag pins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every other action directory here ships one -- install-Require,
install-Rmd-pkgs, install-SpaDES, install-spatial-deps -- and both new READMEs
already ended without the "released under the MIT License" section the older
ones carry. The repository root is MIT, so nothing about the licensing changes;
this only stops the two newest actions from looking like the unlicensed ones
when someone vendors a single directory.

Copyright year is 2026, matching when these two were written, exactly as
install-spatial-deps/LICENSE says 2023 and the 2022 actions say 2022.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nothing in this repository tracked its third-party actions. All of them float
on a major tag -- `actions/checkout@v7`, `r-lib/actions/*@v2`,
`nick-fields/retry@v3`, `actions/upload-artifact@v4`, `actions/cache/*@v4`,
`JamesIves/github-pages-deploy-action@v4` -- which is a mutable pointer owned by
someone else: it can move between two runs of the same commit, and nothing here
would record that it had. Upstream r-lib pins by full SHA throughout, which is
only livable if something bumps the pins for you.

It doubles as the drift detector this repo has already needed once: v0.4's NEWS
records "`nick-fields/retry` v3 -> v4", and both call sites are still on v3.

Two update blocks, because `github-actions` scans `.github/workflows/*` under
`directory: "/"` and treats a composite action as its own directory;
`setup-r-deps` is the only composite action here with a third-party `uses:`.
Grouped so a month of upstream releases arrives as one PR, and monthly rather
than weekly because this is a six-file infrastructure repo, not an application.

Deliberately no SHA re-pinning in this commit. The four reusable workflows are
being rewritten in parallel (they all move onto `setup-r-deps`), and re-pinning
across a rewrite would be a guaranteed conflict for no benefit -- the pins are
worth converting in one pass afterwards, on top of this config.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three `install-*` jobs and the documented `install-Require`-first ordering
were missing from the development section.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@achubaty

Copy link
Copy Markdown
Contributor Author

Withdrawn: this repository is under active rework by its owner, so a PR from outside that effort would only be noise or would be superseded. Closing rather than leaving it open.

The branch chore/ci-housekeeping is left in place if any of it is wanted later; the findings behind it (dead revdeps-check inputs, the paths:-without-jobs gap in self-test.yaml, the documentation drift, and the ubuntugis PPA in every published tag) have been reported separately.

@achubaty achubaty closed this Aug 31, 2026
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