Skip to content

ci: let @claude run R and file follow-up issues#218

Merged
d-morrison merged 3 commits into
mainfrom
ci/claude-can-run-R-commands
May 19, 2026
Merged

ci: let @claude run R and file follow-up issues#218
d-morrison merged 3 commits into
mainfrom
ci/claude-can-run-R-commands

Conversation

@d-morrison
Copy link
Copy Markdown
Member

Summary

Two capabilities for the @claude (Claude Code workflow) so it can do work that previously had to be hand-patched or trailed in PR comments.

R toolchain

  • Install JAGS (apt-get) → r-lib/actions/setup-r@v2setup-r-dependencies@v2 with any::devtools, any::roxygen2, any::rjags.
  • Extend claude_args --allowed-tools with Bash(Rscript:*), Bash(R:*), Bash(R CMD:*).

Motivation: @claude requests like "rerun devtools::document()" on PR #207 failed because the runner had no R toolchain and the Bash allowlist was git-only. Claude resorted to editing man/*.Rd by hand and the maintainer had to verify manually. See this thread.

Cost: ~1–3 min of extra setup time per @claude invocation when the dependency cache is warm; slower on cold cache. Acceptable for the tasks that need it.

Follow-up issue filing

  • Bump permissions: issues: readissues: write.
  • Add Bash(gh issue:*) to the allowlist.

So Claude can open a tracking issue for deferred work instead of burying it in a PR comment that gets lost.

Out of scope

  • The same expansion for claude-code-review.yml (auto-trigger on pull_request). Reviews are review-only and shouldn't be filing issues or running long install steps on every push.

Test plan

  • After merge, @claude on a PR with a request like "regenerate the Rd for X" and confirm Claude runs devtools::document() rather than hand-editing the Rd.
  • Ask @claude to "file a follow-up issue for $thing" and confirm the issue lands.
  • Confirm cold-cache invocation time is acceptable (< 5 min added).

🤖 Generated with Claude Code

Adds two capabilities to .github/workflows/claude.yml so @claude
invocations can do work that previously had to be hand-patched or
buried in comments.

R toolchain
-----------
Install JAGS via apt-get, then set up R + dependencies (including
devtools, roxygen2, and rjags) before the Run Claude Code step, and
extend claude_args' --allowed-tools with Bash(Rscript:*), Bash(R:*),
and Bash(R CMD:*). Without this, devtools::document() — and
generally anything that needs to load the package — failed with
"command not found" / "no R toolchain", and Claude resorted to
editing man/*.Rd by hand (see PR #207 thread).

Cost: ~1–3 min of extra setup time per @claude invocation when the
dependency cache is warm; slower on cold cache or after a dep change.
Acceptable since the tasks that need it (document, style, lint) would
otherwise block on a maintainer's local environment.

Follow-up issue filing
----------------------
Bump the workflow's permissions: issues: read → write, and add
Bash(gh issue:*) to the allowlist. With this, Claude can file
follow-up issues for items it identifies but defers from the current
PR (out-of-scope refactors, broader investigations, etc.) instead of
trailing them in a PR comment that gets lost.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 00:05
@github-actions github-actions Bot review requested due to automatic review settings May 19, 2026 00:05
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 19, 2026

Claude finished @d-morrison's task in 2m 0s —— View job


Code Review: PR #218ci: let @claude run R and file follow-up issues

Overall: The motivation is solid and the implementation is mostly clean. A few items worth addressing before merge.


Issues

1. Bash(R CMD:*) is redundant and potentially misleading

.github/workflows/claude.yml, line 136:

claude_args: '--allowed-tools "Bash(Rscript:*)" "Bash(R:*)" "Bash(R CMD:*)" "Bash(gh issue:*)"'

When a user runs R CMD check ., the executable is R and the arguments are CMD check .. Claude Code's tool allowlist matches against the command being executed, so Bash(R:*) already covers every R CMD ... invocation. The Bash(R CMD:*) entry either never matches (if the action does prefix-matching on just the executable name), or it's a strict subset of Bash(R:*) (if it does full-string prefix matching). Either way, it adds no coverage and may confuse readers who assume the three entries are non-overlapping.

Fix this →


2. R version is not pinned

.github/workflows/claude.yml, line 59–61:

- uses: r-lib/actions/setup-r@v2
  with:
    use-public-rspm: true

No r-version is specified, so this floats to whatever setup-r@v2 defaults to. Other workflows (test-coverage.yaml, copilot-setup-steps.yml) also don't pin it, but it's worth being intentional: a future R minor release could break something in the middle of a @claude run. Consider adding r-version: "release" (explicit float) or a specific version to match the other workflows, especially since this workflow installs packages from source.


3. Every @claude invocation pays the full R setup cost

As acknowledged in the PR description, all four setup steps (apt install, pandoc, R, dependencies) run unconditionally on every trigger — including simple tasks like updating a PR description or answering a question. On a cold cache this could add 5+ minutes to something that never touches R.

This is an accepted trade-off per the PR description ("Acceptable for the tasks that need it"), so not a blocker — just confirming it's intentional and flagging that the 5-min bound in the test plan may be optimistic on truly cold caches.


Looks Good

  • Bash(gh issue:*) scope: Allowing gh issue (and only gh issue, not gh pr or gh repo) is appropriately scoped. Combined with issues: write, Claude can file/comment on issues without gaining broader repo write access.

  • issues: write permission: The bump from readwrite is minimal and the comment explaining the reason is helpful.

  • findjags() case fix: Correct. The runjags function is findjags() (all lowercase), not findJAGS(). The fix in both test-coverage.yaml and copilot-setup-steps.yml is accurate.

  • System lib list: Mirrors copilot-setup-steps.yml as stated. Good for reproducibility.

  • needs: check in setup-r-dependencies: Appropriate if you want R CMD check to work; the extra-packages list (lintr, spelling, rcmdcheck) is well-chosen for the stated use cases.

  • NEWS.md and WORDLIST: Both updated correctly.


Summary

One substantive fix (remove the redundant Bash(R CMD:*) entry) and one optional improvement (pin R version). The findjags() fixes and the follow-up-issue capability are clean additions.

Follow-up to the #207 Claude advisory: R-CMD-check.yaml on
cran-submission was already updated to the lowercase form
runjags::findjags(); test-coverage.yaml and copilot-setup-steps.yml
were not. The two casings are aliases at runtime, so this is purely
a consistency fix to avoid a stale-feeling diff once 0.1.0 lands.

R-CMD-check.yaml itself is left alone here — it'll pick up the
lowercase form (plus several other r-lib action version bumps) when
cran-submission merges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 00:08
@github-actions github-actions Bot review requested due to automatic review settings May 19, 2026 00:10
Bring the @claude workflow's R setup closer to what
copilot-setup-steps.yml already installs:

* apt-get the system libs that source-builds typically need
  (libcurl, libssl, libxml2, libfont*/libharfbuzz/libfribidi/
  libfreetype, libpng, libtiff5, libjpeg) alongside JAGS, so
  textshaping/ragg/curl/xml2 don't fail when pak falls back to
  source.
* setup-pandoc, so vignettes and pkgdown can be rebuilt.
* Extend extra-packages with rmarkdown, lintr, spelling, and
  rcmdcheck — the latter two let Claude run
  spelling::spell_check_package() and R CMD check locally before
  pushing, which is exactly the loop that's been forcing follow-up
  pushes.

Intentionally not ported: the rjags source-install step (pak
handles it given libjags from apt) and the two verification echo
steps (diagnostic only — useful when debugging the setup file
itself, not on every @claude invocation). Also keeping action
versions at @v2, not @Head (matches the cran-submission direction).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 00:15
@github-actions github-actions Bot review requested due to automatic review settings May 19, 2026 00:16
@d-morrison d-morrison merged commit 13dcf54 into main May 19, 2026
15 checks passed
@d-morrison d-morrison deleted the ci/claude-can-run-R-commands branch May 19, 2026 00:22
@claude claude Bot mentioned this pull request May 19, 2026
15 tasks
claude Bot pushed a commit that referenced this pull request May 19, 2026
Co-authored-by: Douglas Ezra Morrison <d-morrison@users.noreply.github.com>
d-morrison added a commit that referenced this pull request May 19, 2026
Same three-way conflict as the previous main → cran-submission merge:

* DESCRIPTION — kept the 0.1.0 release Title and version from
  cran-submission. Main's dev version (0.0.0.9054 after #218) is
  superseded.
* NEWS.md — kept cran-submission's "first CRAN release" intro and
  0.1.0 structure. All of main's incoming dev-version bullets
  (#218 R toolchain + gh issue allowlist, findjags casing,
  #210/#216/#217, OS-snapshot consolidation, Copilot decomposition)
  are already represented under ## Developer-facing changes from
  the prior merge and the "Incorporate PR #218 changes" cherry,
  so the main-side block is dropped rather than re-merged.
* inst/WORDLIST — union of both branches, ASCII-sorted, CRLF
  preserved.

Workflow files (.github/workflows/{claude,copilot-setup-steps,
test-coverage}.yml) auto-merged to main's version, so cran-submission
now inherits #218's @claude R toolchain, gh issue allowlist, and
the lowercase runjags::findjags() consistency fix in test-coverage
and copilot-setup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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