Repository navigation
GH-50492: [R] Add release process skill - #50499
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@amoeba - are you OK with us adding your social media calculation script in here? |
There was a problem hiding this comment.
Pull request overview
Adds an R-focused “Claude Code” skill to guide maintainers through the CRAN release checklist, updates the existing R packaging checklist to reference that skill, and introduces a small helper script intended to generate contributor stats for release announcements. It also updates RAT excludes to ignore .claude/ content.
Changes:
- Add
.claude/skills/r-cran-release/SKILL.mdwith step-by-step CRAN release instructions. - Update
r/PACKAGING.mdto reference the skill and switch contributor stats guidance to a new in-repo script. - Add
r/tools/contributor_stats.Rand exclude.claude/*from RAT.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
r/tools/contributor_stats.R |
New helper intended to compute contributor stats between git refs for release announcements. |
r/PACKAGING.md |
Links to the new skill and updates/removes overlapping checklist content. |
dev/release/rat_exclude_files.txt |
Excludes .claude/* from RAT scanning. |
.claude/skills/r-cran-release/SKILL.md |
New CRAN release process skill/checklist for maintainers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| stopunlesscommand <- function(command, arguments) { | ||
| out <- tryCatch( | ||
| { | ||
| system2("git", arguments, stdout = TRUE) | ||
| }, | ||
| warning = function(w) { | ||
| stop(w) | ||
| }, | ||
| error = function(e) { | ||
| stop(e) | ||
| } | ||
| ) | ||
|
|
||
| TRUE | ||
| } |
| stopfinotinrepo <- function() { | ||
| stopunlesscommand("git", "reflog main") | ||
| } | ||
|
|
||
| stopifnotref <- function(ref) { | ||
| stopifnot(is.character(ref)) | ||
| stopifnot(nchar(ref) > 0) | ||
| stopunlesscommand("git", paste("reflog", ref)) | ||
| } |
| make_git_log_prev_args <- function(ref_from, subdirectory) { | ||
| paste0("log --pretty='format: %an' ", ref_from, " ", subdirectory, " | sort | uniq") | ||
| } | ||
|
|
||
| make_git_log_next_args <- function(ref_from, ref_to, subdirectory) { | ||
| paste0("log --pretty='format: %an' ", ref_from, "..", ref_to, " ", subdirectory, " | sort | uniq") | ||
| } | ||
|
|
||
| print_new_contributors <- function(ref_from, ref_to, subdirectory = ".") { | ||
| stopfinotinrepo() | ||
| stopifnotref(ref_from) | ||
| stopifnotref(ref_to) | ||
| stopifnot(file.exists(subdirectory)) | ||
|
|
||
| prev_out <- trimws(system2("git", make_git_log_prev_args(ref_from, subdirectory), stdout = TRUE)) | ||
| new_out <- trimws(system2("git", make_git_log_next_args(ref_from, ref_to, subdirectory), stdout = TRUE)) | ||
|
|
||
| setdiff(new_out, prev_out) | ||
| } | ||
|
|
||
| # Contributors (author names) to `subdirectory` between two refs | ||
| contributors_between <- function(ref_from, ref_to, subdirectory = ".") { | ||
| trimws(system2("git", make_git_log_next_args(ref_from, ref_to, subdirectory), stdout = TRUE)) | ||
| } |
| #' new_contributors.R | ||
| #' | ||
| #' Produce a list of names of new contributors between two git refs. The method | ||
| #' this uses is to first get the list of unique contrbutors referancable from | ||
| #' the first ref, then the second ref, and then compute the set difference and | ||
| #' return that. |
| In `r/README.md`, delete everything between `<!-- badges: start -->` and `<!-- badges: end -->` (inclusive): | ||
|
|
||
| ```bash | ||
| sed -i '/<!-- badges: start -->/,/<!-- badges: end -->/d' r/README.md |
|
🤖 : Suggested improvement to step 2 (from doing the 25.0.1 release): when the final release tag (e.g. apache-arrow-25.0.1) already exists, the vote has passed and we should branch from that tag rather than asking which RC to use — picking an RC invites choosing the wrong one (rc0 was a different commit from the final tag here). Proposed change to step 2: Check whether the final release tag exists: git fetch upstream --tags
git tag -l 'apache-arrow-<VERSION>*'If git checkout apache-arrow-<VERSION>Only if the final tag does not exist yet (vote still in progress), ask which RC to use and branch from Step 13 (Wait for Release Vote) could also note: if the branch was created from the final release tag, the vote already passed and this step is a no-op. |
amoeba
left a comment
There was a problem hiding this comment.
Using the script in my gist is fine with me.
+1 assuming we think having a .claude folder at the root of the repo would be okay with non-R maintainers. I haven't followed the LLM usage discussions closely. Also +1 since it's best if any tools we actually use for releases is checked into git.
| Ask before pushing: | ||
|
|
||
| ```bash | ||
| git push upstream maint-<VERSION>-r |
There was a problem hiding this comment.
Having an agent push kinda makes me sweat. What do you think about trying to harden the skill by instructing the agent never to push and instead prompt the user to do so.
There was a problem hiding this comment.
🟡 Changes recommended
The new contributor stats helper can silently produce incorrect totals when sourced outside the repo root, and the release skill includes a non-portable sed -i command that fails on macOS.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
.claude/skills/r-cran-release/SKILL.md:58
sed -iis not portable: BSD/macOSsedrequires an argument for-i(e.g.-i ''), so this step will fail on macOS. Using a backup suffix works on both GNU and BSD sed.
sed -i.bak '/<!-- badges: start -->/,/<!-- badges: end -->/d' r/README.md && rm r/README.md.bak
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
| stopifnotinrepo <- function() { | ||
| git("rev-parse", "--is-inside-work-tree") | ||
| invisible(TRUE) | ||
| } |
| # Contributor statistics for release announcements. | ||
| # | ||
| # The `print_new_contributors()` helper below is adapted from Bryce Mecum's gist: | ||
| # https://gist.github.com/amoeba/4e26c064d1a0d0227cd8c2260cf0072a | ||
| # |
There was a problem hiding this comment.
🟡 Changes recommended
The new contributor stats helper and the CRAN release skill contain inconsistencies that can produce misleading stats and confusing/incorrect instructions during a release.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
r/tools/contributor_stats.R:111
release_contributor_stats()reportstotalas all contributors between refs, butcpp_only/r_only/bothonly describe overlap betweencpp/andr/, so the “only C++ / only R / both” breakdown can be misleading and won’t sum tototalwhen contributors touched neither directory. Consider clarifying the semantics and adding an explicit bucket for contributors who touched neithercpp/norr/so the stats are internally consistent.
- Files reviewed: 4/4 changed files
- Comments generated: 1
- Review effort level: Lite
| ```bash | ||
| cd r && make build | ||
| ``` | ||
|
|
||
| After the build, check for any generated doc changes that need to be committed: | ||
|
|
||
| ```bash | ||
| git status | ||
| ``` | ||
|
|
||
| If there are modified `.Rd` files or other doc changes, commit them: | ||
|
|
||
| ```bash | ||
| git add r/man/ r/inst/NOTICE.txt | ||
| git commit -m "[R] Update generated documentation" | ||
| ``` | ||
|
|
||
| Ask the user to push. | ||
|
|
||
| Then run the check: | ||
|
|
||
| ```r | ||
| devtools::check_built("arrow_<VERSION>.tar.gz") | ||
| ``` |
Rationale for this change
Add a Claude Code skill to guide folks through the CRAN release process, and add
.claude/to the RAT excludes.What changes are included in this PR?
.claude/skills/r-cran-release/SKILL.mdwith step-by-step CRAN release instructions.claude/*todev/release/rat_exclude_files.txtr/PACKAGING.md(covered by later steps)Are these changes tested?
No code changes to test.
Are there any user-facing changes?
No.