Add shakapacker version update command; bump to 9.6.1#2569
Conversation
WalkthroughAdds a new rake task to update shakapacker across the monorepo and bumps shakapacker from 9.6.0 → 9.6.1 in multiple Gemfiles and package.json files; also updates docs with usage and testing guidance. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Rake as Rake Task
participant FS as Repo Files
participant Bundler as Bundler
participant PNPM as pnpm
Dev->>Rake: rake shakapacker:update_version[9.6.1]
Rake->>FS: scan for Gemfiles, package.json, lockfiles
Rake->>FS: replace shakapacker pins in matched files
Rake->>Bundler: run per-dir bundle update (handles ruby version managers)
Bundler-->>Rake: per-dir success / error
Rake->>PNPM: run pnpm install at monorepo root
PNPM-->>Rake: success / error
Rake->>Dev: summary logs and guidance
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review: Add shakapacker version update command; bump to 9.6.1The version bump changes themselves look correct and consistent. The new rake task is a useful maintenance tool, but a few implementation issues are worth addressing. 1. Top-level method definitions pollute Object (main concern)
2. Unused require
3. No version format validation Any string is accepted as a version. A malformed input like 4. npm range prefixes silently skipped (worth documenting) The package.json regex only matches bare version strings. Minor: Hyphen in Note on lock files: The PR merges before 9.6.1 is published to RubyGems/npm. Any CI job that runs |
| @@ -0,0 +1,69 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| require "json" | |||
There was a problem hiding this comment.
This require "json" is unused — the implementation uses regex instead of JSON parsing. Remove it.
| end | ||
| end | ||
|
|
||
| def update_gemfiles(version) |
There was a problem hiding this comment.
Defining update_gemfiles, update_package_jsons, and relative_path at the top level (outside the namespace) makes them private instance methods on Object, polluting the global method namespace for the entire Ruby process.
The pattern used by every other rake file in this repo is to call methods from ReactOnRails::TaskHelpers (included in the namespace block). The helper logic here should either be inlined into the task body, or the methods should be moved into TaskHelpers / a private module.
| def update_gemfiles(version) | |
| def update_gemfiles(version) |
Note: the suggestion above keeps the line as-is — the real fix is to move all three method definitions inside a
moduleor intoTaskHelpersrather than at the top level.
| desc "Update shakapacker version across all Gemfiles and package.json files. " \ | ||
| "Usage: rake shakapacker:update_version[9.6.1]" | ||
| task :update_version, [:version] do |_t, args| | ||
| version = args[:version] |
There was a problem hiding this comment.
No validation of the version format is performed. A caller could accidentally pass v9.6.1 (with a v prefix) or any other malformed string and the task would silently write it into every file.
| version = args[:version] | |
| version = args[:version] | |
| raise "Version argument required. Usage: rake shakapacker:update_version[9.6.1]" unless version | |
| raise "Invalid version format '#{version}'. Expected semver like '9.6.1'" unless version.match?(/\A\d+\.\d+\.\d+/) |
Greptile SummaryThis PR introduces a new Key observations:
All 6 version-bump changes are clean single-line diffs with no functional issues. Confidence Score: 4/5
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["rake shakapacker:update_version VERSION"] --> B{version provided?}
B -- No --> C["raise error"]
B -- Yes --> D["update_gemfiles(version)"]
D --> E["Dir.glob Gemfile* \nexclude .lock and gen-examples"]
E --> F["regex gsub gem shakapacker version"]
F --> G{changed?}
G -- Yes --> H["File.write updated content"]
G -- No --> I["skip"]
H --> J["update_package_jsons(version)"]
I --> J
J --> K["Dir.glob package.json\nexclude node_modules and gen-examples"]
K --> L["regex gsub shakapacker version"]
L --> M{changed?}
M -- Yes --> N["File.write updated content"]
M -- No --> O["skip"]
N --> P["Done: remind to run bundle update and pnpm install"]
O --> P
Last reviewed commit: 82f47a8 |
| @@ -0,0 +1,69 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| require "json" | |||
There was a problem hiding this comment.
The require "json" on this line is imported but never used. The implementation correctly relies on regex substitution to avoid JSON reformatting artifacts, so this dependency can be safely removed.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON, but it could not run because Privacy Mode (Legacy) is turned on. To enable Bugbot Autofix, switch your privacy mode in the Cursor dashboard.
| @@ -0,0 +1,69 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| require "json" | |||
There was a problem hiding this comment.
Unused require "json" import in rake file
Low Severity
require "json" is imported but never used anywhere in the file. The implementation deliberately uses regex-based replacement (as noted in comments) instead of JSON parsing to preserve formatting. The JSON module is never referenced. This appears to be a leftover from an earlier implementation approach that was switched to regex.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 82f47a8abe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "sass-loader": "^12.3.0", | ||
| "sass-resources-loader": "^2.1.0", | ||
| "shakapacker": "9.6.0", | ||
| "shakapacker": "9.6.1", |
There was a problem hiding this comment.
Regenerate pnpm lockfile after shakapacker bump
This version bump updates workspace package.json files to 9.6.1 but does not update pnpm-lock.yaml (which still pins these importers to 9.6.0), so CI jobs that run pnpm install --frozen-lockfile (for example in .github/workflows/lint-js-and-ruby.yml and other frozen-lockfile workflows) will fail before tests run.
Useful? React with 👍 / 👎.
| eval_gemfile File.expand_path("../Gemfile.shared_dev_dependencies", __dir__) | ||
|
|
||
| gem "shakapacker", "9.6.0" | ||
| gem "shakapacker", "9.6.1" |
There was a problem hiding this comment.
Update Gemfile.lock when changing shakapacker Gemfile pin
The Gemfile pin is changed to 9.6.1 while the corresponding lockfiles still resolve shakapacker (9.6.0), and Ruby CI runs with BUNDLE_FROZEN=true for the latest matrix (see .github/workflows/gem-tests.yml), so bundle install in react_on_rails will fail due to frozen lockfile mismatch.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
react_on_rails/rakelib/shakapacker_version.rake (1)
3-3: Unused import:require "json"is not used.The file uses regex-based string replacement rather than JSON parsing. This import can be removed.
🧹 Proposed fix
# frozen_string_literal: true -require "json" - require_relative "task_helpers"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/rakelib/shakapacker_version.rake` at line 3, Remove the unused JSON import by deleting the top-level require "json" statement; locate the require "json" token in the rake file (it is currently the only require in shakapacker_version.rake) and remove it so the file uses its existing regex/string-replacement logic without importing the json library.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/rakelib/shakapacker_version.rake`:
- Around line 54-58: The current package.json regex in the shakapacker updater
silently fails for npm prefixes like ^ or ~; update the pattern used when
building updated (the regex passed to content.gsub and the replacement using
Regexp.last_match) to capture and preserve an optional npm prefix (e.g., ^ or ~,
and optionally = if desired) before the numeric version, and include that
captured prefix in the replacement so the new version string keeps the original
prefix instead of skipping files that used it.
In `@react_on_rails/spec/dummy/package.json`:
- Line 56: The package.json manifest was bumped to "shakapacker": "9.6.1" but
pnpm-lock.yaml still pins 9.6.0, causing CI failures with pnpm install
--frozen-lockfile; to fix, run pnpm install (or pnpm install --lockfile-only)
locally to regenerate pnpm-lock.yaml so it matches the new shakapacker 9.6.1
entry, verify the lockfile changes, and commit the updated pnpm-lock.yaml
alongside the package.json change (alternatively revert the manifest bump if you
prefer to wait).
---
Nitpick comments:
In `@react_on_rails/rakelib/shakapacker_version.rake`:
- Line 3: Remove the unused JSON import by deleting the top-level require "json"
statement; locate the require "json" token in the rake file (it is currently the
only require in shakapacker_version.rake) and remove it so the file uses its
existing regex/string-replacement logic without importing the json library.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b8bed09f-0b47-4bc3-90d5-c176668e621f
📒 Files selected for processing (7)
react_on_rails/Gemfile.development_dependenciesreact_on_rails/rakelib/shakapacker_version.rakereact_on_rails/spec/dummy/package.jsonreact_on_rails_pro/Gemfile.development_dependenciesreact_on_rails_pro/spec/dummy/package.jsonreact_on_rails_pro/spec/execjs-compatible-dummy/Gemfilereact_on_rails_pro/spec/execjs-compatible-dummy/package.json
82f47a8 to
dadc652
Compare
| cmd = case version_manager | ||
| when "rvm" then "rvm #{version} do bundle update shakapacker" | ||
| when "rbenv" then "RBENV_VERSION=#{version} bundle update shakapacker" | ||
| when "asdf" then "asdf shell ruby #{version} && bundle update shakapacker" |
There was a problem hiding this comment.
asdf shell ruby #{version} sets the Ruby version in the current shell session, but when the command is executed as a subprocess via sh, it runs in a child shell that exits immediately — the environment change never takes effect for the subsequent bundle update shakapacker call in the same string.
The reliable approach for asdf is to use either asdf exec or the env var directly:
| when "asdf" then "asdf shell ruby #{version} && bundle update shakapacker" | |
| when "asdf" then "ASDF_RUBY_VERSION=#{version} bundle update shakapacker" |
Note the same issue exists in task_helpers.rb's bundle_install_with_ruby_version.
| # gem "shakapacker", "9.6.0" | ||
| # gem "shakapacker", "= 9.6.0" | ||
| updated = content.gsub( | ||
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ |
There was a problem hiding this comment.
The regex only matches double-quoted gem "shakapacker" declarations. Gemfiles that use single quotes (gem 'shakapacker', '9.6.0') will be silently skipped.
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ | |
| /gem ['"]shakapacker['"]/,\s*['"](?:=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)['"]/ |
Or more simply, extend the character class to match both quote styles:
/gem ["']shakapacker["'],\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/(Full fix would also handle single-quoted version strings, but the Gemfiles in this repo appear to use double quotes consistently, so this may be acceptable as a known limitation — worth documenting with a comment.)
| end | ||
| end | ||
|
|
||
| def bundle_update_with_ruby_version(dir, version) |
There was a problem hiding this comment.
This duplicates the version-manager case logic from task_helpers.rb's bundle_install_with_ruby_version, but with two differences:
- It adds
misesupport (whichtask_helpers.rbis missing). - It raises immediately on an unknown manager, whereas
task_helpers.rbprints a user-friendly warning before raising.
Consider extracting the shared "build the switch command for manager X" logic into a single method in TaskHelpers (e.g., ruby_version_switch_command(version, cmd)) that both bundle_install_with_ruby_version and bundle_update_with_ruby_version can call. This would also let you add mise support to bundle_install_in in one place.
| .reject { |f| f.include?("gen-examples") } | ||
| .select { |f| File.read(f).include?("shakapacker") } | ||
|
|
||
| gemfile_locks.each do |lockfile| |
There was a problem hiding this comment.
The rescue here is attached to the do..end block (implicit begin), which is valid Ruby but can be surprising: it catches errors from all code in the block, including File.dirname and shakapacker_relative_path, not just bundle_update_shakapacker_in.
Also note that if bundle_update_shakapacker_in raises, rel will have already been set, so the rescue message is correct — but it's still worth an explicit begin/rescue/end around just the call you intend to be fallible:
gemfile_locks.each do |lockfile|
dir = File.dirname(lockfile)
rel = shakapacker_relative_path(dir)
puts " bundle update shakapacker in #{rel}"
begin
bundle_update_shakapacker_in(dir)
rescue StandardError => e
puts " WARNING: Failed to update #{rel}: #{e.message}"
puts " You may need to update this lock file manually."
end
end| task :update_version, [:version] do |_t, args| | ||
| version = args[:version] | ||
| raise "Version argument required. Usage: rake shakapacker:update_version[9.6.1]" unless version | ||
| unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/) |
There was a problem hiding this comment.
Minor: the outer capture group with ? is redundant since * already allows zero matches. This is harmless but slightly confusing:
/\A\d+\.\d+\.\d+[.\-a-zA-Z0-9]*\z/Also, the . inside the character class is a literal dot (which is correct), but - should be placed first or last to avoid being interpreted as a range in some contexts — though \- works fine here.
Review: Add shakapacker version update command + bump to 9.6.1The version bump changes look correct and comprehensive — all 13 files updated consistently. The new rake task is a good addition for keeping version references in sync. A few issues worth addressing: Bugs / Behavioral Issues
Code Quality
Overall The PR is a solid improvement — the automated update task is the right abstraction for a monorepo with 13+ version references. The version bump itself is clean. The issues above are mostly minor quality items; the asdf fix is the only one with real behavioral impact. |
size-limit report 📦
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
react_on_rails/rakelib/shakapacker_version.rake (1)
19-21: Separate manifest rewrites from lockfile refresh.This always jumps straight from the text replacements into lockfile resolution. Making
update_shakapacker_lock_filesopt-in, or moving it to a second task, would keep the command usable for manifest-only updates and let maintainers run the resolver step later.🔧 One way to split the phases
- desc "Update shakapacker version in all Gemfiles, package.json, and lock files. " \ - "Usage: rake shakapacker:update_version[9.6.1]" - task :update_version, [:version] do |_t, args| + desc "Update shakapacker version references. " \ + "Usage: rake shakapacker:update_version[9.6.1,true]" + task :update_version, %i[version update_locks] do |_t, args| version = args[:version] + update_locks = args[:update_locks] == "true" raise "Version argument required. Usage: rake shakapacker:update_version[9.6.1]" unless version unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/) raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'" end puts "Updating shakapacker to #{version} across the monorepo..." update_shakapacker_gemfiles(version) update_shakapacker_package_jsons(version) - update_shakapacker_lock_files + update_shakapacker_lock_files if update_locks end🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/rakelib/shakapacker_version.rake` around lines 19 - 21, The current rake task unconditionally calls update_shakapacker_lock_files after doing text replacements, which forces lockfile resolution; change this so lockfile refresh is opt-in or moved to a separate task: remove the direct call to update_shakapacker_lock_files from the manifest-update task and either (a) create a new rake task (e.g., shakapacker:refresh_lockfiles) that invokes update_shakapacker_lock_files, or (b) guard the call with an environment flag (e.g., run only when ENV['REFRESH_LOCKFILES']=='true') so update_shakapacker_gemfiles and update_shakapacker_package_jsons can run independently of update_shakapacker_lock_files.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/rakelib/shakapacker_version.rake`:
- Around line 13-14: The version validation regex in the unless block (the
version.match? check) is too permissive and allows trailing or repeated
separators like "9.6.1-" or "9.6.1...."; replace the existing pattern with a
stricter one that requires an initial MAJOR.MINOR.PATCH and only allows
additional prerelease/build segments that begin with a dot or dash followed by
at least one alphanumeric token (no empty tokens, no trailing separators).
Update the regex used in the unless condition (the version.match? call) to
enforce the pattern so only valid semver-like strings such as "9.6.1",
"9.6.0.beta.0", or "9.6.1-rc1" pass.
- Around line 74-82: The task iterates over Gemfile* variants but only targets
Gemfile.lock files; update the loop and the bundle_update_shakapacker_in helper
so it accepts the originating Gemfile basename (e.g.,
"Gemfile.development_dependencies") and uses that to set BUNDLE_GEMFILE when
invoking Bundler; specifically, when iterating in the block that computes rel
via shakapacker_relative_path and calls bundle_update_shakapacker_in(dir), also
determine the matching Gemfile basename for that lockfile and pass it into
bundle_update_shakapacker_in(dir, gemfile_basename), and modify
bundle_update_shakapacker_in to export ENV["BUNDLE_GEMFILE"]=gemfile_basename
(or the full path) before running bundle update so Bundler regenerates the
correct lockfile for non-default manifests.
---
Nitpick comments:
In `@react_on_rails/rakelib/shakapacker_version.rake`:
- Around line 19-21: The current rake task unconditionally calls
update_shakapacker_lock_files after doing text replacements, which forces
lockfile resolution; change this so lockfile refresh is opt-in or moved to a
separate task: remove the direct call to update_shakapacker_lock_files from the
manifest-update task and either (a) create a new rake task (e.g.,
shakapacker:refresh_lockfiles) that invokes update_shakapacker_lock_files, or
(b) guard the call with an environment flag (e.g., run only when
ENV['REFRESH_LOCKFILES']=='true') so update_shakapacker_gemfiles and
update_shakapacker_package_jsons can run independently of
update_shakapacker_lock_files.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 90e29845-2e5d-426b-aa27-5019351d364b
⛔ Files ignored due to path filters (6)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlreact_on_rails/Gemfile.lockis excluded by!**/*.lockreact_on_rails/spec/dummy/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/spec/dummy/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/spec/execjs-compatible-dummy/Gemfile.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
react_on_rails/Gemfile.development_dependenciesreact_on_rails/rakelib/shakapacker_version.rakereact_on_rails/spec/dummy/package.jsonreact_on_rails_pro/Gemfile.development_dependenciesreact_on_rails_pro/spec/dummy/package.jsonreact_on_rails_pro/spec/execjs-compatible-dummy/Gemfilereact_on_rails_pro/spec/execjs-compatible-dummy/package.json
🚧 Files skipped from review as they are similar to previous changes (4)
- react_on_rails/spec/dummy/package.json
- react_on_rails_pro/spec/dummy/package.json
- react_on_rails_pro/spec/execjs-compatible-dummy/package.json
- react_on_rails_pro/Gemfile.development_dependencies
| unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/) | ||
| raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'" |
There was a problem hiding this comment.
Tighten the version validator.
/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/ also accepts malformed inputs like 9.6.1- and 9.6.1...., so a typo can rewrite multiple manifests before anything fails.
🔧 Proposed fix
- unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/)
+ unless version.match?(/\A\d+\.\d+\.\d+(?:[-.][0-9A-Za-z]+)*\z/)
raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'"
end📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/) | |
| raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'" | |
| unless version.match?(/\A\d+\.\d+\.\d+(?:[-.][0-9A-Za-z]+)*\z/) | |
| raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@react_on_rails/rakelib/shakapacker_version.rake` around lines 13 - 14, The
version validation regex in the unless block (the version.match? check) is too
permissive and allows trailing or repeated separators like "9.6.1-" or
"9.6.1...."; replace the existing pattern with a stricter one that requires an
initial MAJOR.MINOR.PATCH and only allows additional prerelease/build segments
that begin with a dot or dash followed by at least one alphanumeric token (no
empty tokens, no trailing separators). Update the regex used in the unless
condition (the version.match? call) to enforce the pattern so only valid
semver-like strings such as "9.6.1", "9.6.0.beta.0", or "9.6.1-rc1" pass.
| gemfile_locks = Dir.glob(File.join(monorepo_root, "**", "Gemfile.lock")) | ||
| .reject { |f| f.include?("gen-examples") } | ||
| .select { |f| File.read(f).include?("shakapacker") } | ||
|
|
||
| gemfile_locks.each do |lockfile| | ||
| dir = File.dirname(lockfile) | ||
| rel = shakapacker_relative_path(dir) | ||
| puts " bundle update shakapacker in #{rel}" | ||
| bundle_update_shakapacker_in(dir) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
python - <<'PY'
from pathlib import Path
for lockfile in sorted(Path('.').rglob('Gemfile*.lock')):
if lockfile.name == 'Gemfile.lock':
continue
if any(part in {'.git', 'node_modules'} for part in lockfile.parts):
continue
text = lockfile.read_text(errors='ignore')
if 'shakapacker' not in text:
continue
gemfile = lockfile.with_suffix('') # strip .lock
print(f"missed lockfile: {lockfile}")
print(f" matching gemfile: {gemfile} (exists={gemfile.exists()})")
PYRepository: shakacode/react_on_rails
Length of output: 50
🏁 Script executed:
fd -e development_dependenciesRepository: shakacode/react_on_rails
Length of output: 167
🏁 Script executed:
find . -name "*development_dependencies*" -type f | grep -v ".git" | head -20Repository: shakacode/react_on_rails
Length of output: 171
🏁 Script executed:
find . -name "Gemfile.development_dependencies.lock" -type f | grep -v ".git"Repository: shakacode/react_on_rails
Length of output: 50
🏁 Script executed:
grep -r "shakapacker" react_on_rails/Gemfile.development_dependencies react_on_rails_pro/Gemfile.development_dependencies 2>/dev/null || echo "shakapacker not found"Repository: shakacode/react_on_rails
Length of output: 221
🏁 Script executed:
cat react_on_rails/Gemfile.development_dependencies react_on_rails_pro/Gemfile.development_dependenciesRepository: shakacode/react_on_rails
Length of output: 3713
🏁 Script executed:
cat -n react_on_rails/rakelib/shakapacker_version.rakeRepository: shakacode/react_on_rails
Length of output: 5200
🏁 Script executed:
grep -n "bundle_update_shakapacker_in" react_on_rails/rakelib/shakapacker_version.rakeRepository: shakacode/react_on_rails
Length of output: 153
🏁 Script executed:
cat -n react_on_rails/rakelib/task_helpers.rbRepository: shakacode/react_on_rails
Length of output: 5432
🏁 Script executed:
grep -A5 "unbundled_sh_in_dir\|sh_in_dir" react_on_rails/rakelib/task_helpers.rb | head -30Repository: shakacode/react_on_rails
Length of output: 1057
Handle non-default lockfiles to maintain consistency with updated Gemfiles.
This task updates all Gemfile* variants including Gemfile.development_dependencies (lines 26–48), but only bundles Gemfile.lock files (line 74). If Gemfile.development_dependencies is bundled elsewhere, its lockfile will not be regenerated here, leaving dependencies inconsistent. The bundle_update_shakapacker_in helper needs to accept the originating Gemfile basename (e.g., Gemfile.development_dependencies) and pass it via BUNDLE_GEMFILE environment variable so Bundler processes the correct manifest.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@react_on_rails/rakelib/shakapacker_version.rake` around lines 74 - 82, The
task iterates over Gemfile* variants but only targets Gemfile.lock files; update
the loop and the bundle_update_shakapacker_in helper so it accepts the
originating Gemfile basename (e.g., "Gemfile.development_dependencies") and uses
that to set BUNDLE_GEMFILE when invoking Bundler; specifically, when iterating
in the block that computes rel via shakapacker_relative_path and calls
bundle_update_shakapacker_in(dir), also determine the matching Gemfile basename
for that lockfile and pass it into bundle_update_shakapacker_in(dir,
gemfile_basename), and modify bundle_update_shakapacker_in to export
ENV["BUNDLE_GEMFILE"]=gemfile_basename (or the full path) before running bundle
update so Bundler regenerates the correct lockfile for non-default manifests.
Review: Add shakapacker version update command; bump to 9.6.1The version bump itself (9.6.0 to 9.6.1) across all lock files, Gemfiles, and package.json files looks clean and consistent - all 13 files updated correctly. The new |
| update_shakapacker_lock_files | ||
| end | ||
|
|
||
| private |
There was a problem hiding this comment.
private has no effect here. Inside a Rake namespace block, def methods are defined on main (the top-level object), not inside a class or module body, so the private call does not restrict visibility. The methods remain publicly accessible globally. The existing shakapacker_examples.rake omits this marker entirely, which is the correct approach — the private call should be removed to avoid creating a false impression of encapsulation.
| # gem "shakapacker", "9.6.0" | ||
| # gem "shakapacker", "= 9.6.0" | ||
| updated = content.gsub( | ||
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ |
There was a problem hiding this comment.
This regex only matches double-quoted gem declarations. Single-quoted entries like gem 'shakapacker', '9.6.0' would be silently skipped, leaving that file stale with no warning. Consider expanding the pattern to handle both quote styles:
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ | |
| /gem ["']shakapacker["'],\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ |
Or more robustly, use a character class for the surrounding quotes:
/gem (["'])shakapacker\1,\s*(["'])(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)\2/| def bundle_update_with_ruby_version(dir, version) | ||
| version_manager = ENV.fetch("RUBY_VERSION_MANAGER", "rvm") | ||
| cmd = case version_manager | ||
| when "rvm" then "rvm #{version} do bundle update shakapacker" | ||
| when "rbenv" then "RBENV_VERSION=#{version} bundle update shakapacker" | ||
| when "asdf" then "asdf shell ruby #{version} && bundle update shakapacker" | ||
| when "mise" then "mise exec ruby@#{version} -- bundle update shakapacker" | ||
| else raise "Unsupported RUBY_VERSION_MANAGER: #{version_manager}" | ||
| end | ||
| unbundled_sh_in_dir(dir, cmd) | ||
| end |
There was a problem hiding this comment.
This method duplicates nearly all of bundle_install_with_ruby_version in task_helpers.rb, differing only in the bundler subcommand. It also introduces a silent inconsistency: this version supports mise but the original in task_helpers.rb does not, so users relying on mise will find that bundle_install_in fails while bundle_update_shakapacker_in succeeds.
Consider extracting a shared helper into task_helpers.rb that accepts the command:
def run_bundler_with_ruby_version(dir, version, bundler_cmd)
version_manager = ENV.fetch("RUBY_VERSION_MANAGER", "rvm")
cmd = case version_manager
when "rvm" then "rvm #{version} do #{bundler_cmd}"
when "rbenv" then "RBENV_VERSION=#{version} #{bundler_cmd}"
when "asdf" then "asdf shell ruby #{version} && #{bundler_cmd}"
when "mise" then "mise exec ruby@#{version} -- #{bundler_cmd}"
else raise "Unsupported RUBY_VERSION_MANAGER: #{version_manager}"
end
unbundled_sh_in_dir(dir, cmd)
endThen both callers become one-liners, and mise support is available everywhere.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@AGENTS.md`:
- Around line 65-67: The documentation overstates the rake task's scope; update
the phrasing around the shakapacker:update_version rake task (referenced in
react_on_rails/rakelib/shakapacker_version.rake and the task name
shakapacker:update_version) to reflect that it updates "all relevant shakapacker
references and associated lockfiles" rather than every Gemfile.lock — note that
it skips gen-examples and only modifies lockfiles that already contain
shakapacker; adjust the AGENTS.md text to use that narrower wording and keep the
rest of the usage/flags guidance unchanged.
| Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates all Gemfiles, package.json files, Gemfile.lock files, and pnpm-lock.yaml. Do **not** manually edit individual version references — always use the rake task to keep everything in sync. | ||
|
|
||
| The task handles Ruby version switching for apps that require a different Ruby version (set `RUBY_VERSION_MANAGER` to `rvm`, `rbenv`, `asdf`, or `mise` if needed; defaults to `rvm`). It continues gracefully if a single lock file update fails (e.g., due to a missing Ruby version). |
There was a problem hiding this comment.
Narrow the documented scope of lockfile updates.
react_on_rails/rakelib/shakapacker_version.rake:71-92 does not update all Gemfile.lock files: it skips gen-examples and only touches lockfiles that already contain shakapacker. Reword this to "all relevant shakapacker references and associated lockfiles" so the docs match the task behavior.
✏️ Suggested wording
-Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates all Gemfiles, package.json files, Gemfile.lock files, and pnpm-lock.yaml. Do **not** manually edit individual version references — always use the rake task to keep everything in sync.
+Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates shakapacker version references in Gemfiles and package.json files, refreshes the relevant Gemfile.lock files, and regenerates `pnpm-lock.yaml`. Do **not** manually edit individual version references — always use the rake task to keep everything in sync.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates all Gemfiles, package.json files, Gemfile.lock files, and pnpm-lock.yaml. Do **not** manually edit individual version references — always use the rake task to keep everything in sync. | |
| The task handles Ruby version switching for apps that require a different Ruby version (set `RUBY_VERSION_MANAGER` to `rvm`, `rbenv`, `asdf`, or `mise` if needed; defaults to `rvm`). It continues gracefully if a single lock file update fails (e.g., due to a missing Ruby version). | |
| Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates shakapacker version references in Gemfiles and package.json files, refreshes the relevant Gemfile.lock files, and regenerates `pnpm-lock.yaml`. Do **not** manually edit individual version references — always use the rake task to keep everything in sync. | |
| The task handles Ruby version switching for apps that require a different Ruby version (set `RUBY_VERSION_MANAGER` to `rvm`, `rbenv`, `asdf`, or `mise` if needed; defaults to `rvm`). It continues gracefully if a single lock file update fails (e.g., due to a missing Ruby version). |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@AGENTS.md` around lines 65 - 67, The documentation overstates the rake task's
scope; update the phrasing around the shakapacker:update_version rake task
(referenced in react_on_rails/rakelib/shakapacker_version.rake and the task name
shakapacker:update_version) to reflect that it updates "all relevant shakapacker
references and associated lockfiles" rather than every Gemfile.lock — note that
it skips gen-examples and only modifies lockfiles that already contain
shakapacker; adjust the AGENTS.md text to use that narrower wording and keep the
rest of the usage/flags guidance unchanged.
Add `rake shakapacker:update_version[VERSION]` which updates all shakapacker references in Gemfiles, package.json files, and lock files across the monorepo in one command. The task: - Validates version format (semver) - Updates Gemfiles preserving "= " pin prefixes - Updates package.json preserving ^ and ~ prefixes - Runs bundle update shakapacker for all Gemfile.lock files - Handles Ruby version switching for apps requiring different Ruby - Runs pnpm install to update pnpm-lock.yaml - Continues gracefully if a single lock file update fails Also bumps shakapacker from 9.6.0 to 9.6.1 using the new command. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add the new command to the Commands section and a short subsection explaining its usage, so agents and contributors know to use the rake task rather than manually editing version references. Co-Authored-By: Claude Opus 4.6 <[email protected]>
d1b10eb to
7472910
Compare
| # gem "shakapacker", "9.6.0" | ||
| # gem "shakapacker", "= 9.6.0" | ||
| updated = content.gsub( | ||
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ |
There was a problem hiding this comment.
This regex only matches double-quoted gem declarations. Gemfiles using single quotes (gem 'shakapacker', '9.6.0') will be silently skipped. Consider broadening the pattern to match either quote style:
| /gem "shakapacker",\s*"(=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)"/ | |
| /gem ["']shakapacker["'],\s*["'](=\s*)?[\d.]+(?:[a-zA-Z0-9.\-]*)["']/ |
Or, simpler to capture and replace correctly, use a capture group approach that handles both quote styles.
| def bundle_update_with_ruby_version(dir, version) | ||
| version_manager = ENV.fetch("RUBY_VERSION_MANAGER", "rvm") | ||
| cmd = case version_manager | ||
| when "rvm" then "rvm #{version} do bundle update shakapacker" | ||
| when "rbenv" then "RBENV_VERSION=#{version} bundle update shakapacker" | ||
| when "asdf" then "asdf shell ruby #{version} && bundle update shakapacker" | ||
| when "mise" then "mise exec ruby@#{version} -- bundle update shakapacker" | ||
| else raise "Unsupported RUBY_VERSION_MANAGER: #{version_manager}" | ||
| end | ||
| unbundled_sh_in_dir(dir, cmd) |
There was a problem hiding this comment.
This method duplicates bundle_install_with_ruby_version from task_helpers.rb with one meaningful difference: it adds mise support that task_helpers.rb lacks. This divergence means mise users get inconsistent behavior — it works here but not with bundle_install_in.
Consider refactoring task_helpers.rb to accept the bundle subcommand as a parameter and reuse it here, e.g.:
def bundle_run_with_ruby_version(dir, version, subcommand)
version_manager = ENV.fetch("RUBY_VERSION_MANAGER", "rvm")
cmd = case version_manager
when "rvm" then "rvm #{version} do bundle #{subcommand}"
when "rbenv" then "RBENV_VERSION=#{version} bundle #{subcommand}"
when "asdf" then "asdf shell ruby #{version} && bundle #{subcommand}"
when "mise" then "mise exec ruby@#{version} -- bundle #{subcommand}"
else raise "Unsupported RUBY_VERSION_MANAGER: #{version_manager}"
end
unbundled_sh_in_dir(dir, cmd)
endThis way both bundle install and bundle update shakapacker use the same logic, including mise.
| end | ||
|
|
||
| def shakapacker_relative_path(path) | ||
| Pathname.new(path).relative_path_from(Pathname.new(monorepo_root)).to_s |
There was a problem hiding this comment.
Pathname is used here without an explicit require 'pathname'. This works in most Rails/Rake contexts because it's loaded transitively, but it's fragile. Add require 'pathname' at the top of the file alongside require_relative "task_helpers".
| # CI/workflow linting | ||
| actionlint # GitHub Actions lint | ||
| yamllint .github/ # YAML lint (do NOT run RuboCop on .yml files) | ||
|
|
There was a problem hiding this comment.
Hardcoding 9.6.1 here will make this example stale after the next version bump. Prefer a placeholder:
| rake shakapacker:update_version[VERSION] # Update shakapacker across the monorepo |
|
Overall this is a well-structured automation PR. The rake task is a clean improvement over manually editing 13+ files, and the version bump itself looks correct. See inline comments for specific issues. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
react_on_rails/rakelib/shakapacker_version.rake (2)
13-14:⚠️ Potential issue | 🟡 MinorTighten the version validator before rewriting manifests.
Line 13 still accepts malformed inputs like
9.6.1-and9.6.1...., so a typo can rewrite multiple files before Bundler or pnpm fails later.🔧 Suggested fix
- unless version.match?(/\A\d+\.\d+\.\d+([.\-a-zA-Z0-9]*)?\z/) + unless version.match?(/\A\d+\.\d+\.\d+(?:[-.][0-9A-Za-z]+)*\z/) raise "Invalid version format '#{version}'. Expected semver like '9.6.1' or '9.6.0.beta.0'" end🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/rakelib/shakapacker_version.rake` around lines 13 - 14, The current version validation using version.match? allows trailing or repeated separators (e.g. "9.6.1-" or "9.6.1...."); update the regex used by version.match? in the rake task to a stricter pattern that only permits the core semver (MAJOR.MINOR.PATCH) optionally followed by prerelease/build identifiers where each identifier is an alphanumeric group separated by a single dot or hyphen (no trailing separators and no empty groups), so replace the existing version.match? check with a regex that enforces "digits.digits.digits" and, if present, only ".|-" followed by one or more alphanumerics (repeated as needed); keep the same raise "Invalid version format '#{version}'..." behavior when the new validation fails.
74-82:⚠️ Potential issue | 🟠 MajorNon-default Gemfiles still won’t get the right lockfile refresh.
Line 74 only enumerates
Gemfile.lock, and Line 101/Line 108-111 runbundle update shakapackerwithout binding Bundler to the originating Gemfile. That leaves manifests likeGemfile.development_dependenciesat risk of being updated while their corresponding lockfiles stay stale.🔧 Suggested direction
- gemfile_locks = Dir.glob(File.join(monorepo_root, "**", "Gemfile.lock")) - .reject { |f| f.include?("gen-examples") } - .select { |f| File.read(f).include?("shakapacker") } - - gemfile_locks.each do |lockfile| - dir = File.dirname(lockfile) + gemfiles = Dir.glob(File.join(monorepo_root, "**", "Gemfile*")) + .reject { |f| f.end_with?(".lock") } + .reject { |f| f.include?("gen-examples") } + .select { |f| File.read(f).include?('gem "shakapacker"') } + + gemfiles.each do |gemfile| + dir = File.dirname(gemfile) + gemfile_basename = File.basename(gemfile) rel = shakapacker_relative_path(dir) puts " bundle update shakapacker in #{rel}" - bundle_update_shakapacker_in(dir) + bundle_update_shakapacker_in(dir, gemfile_basename) rescue StandardError => e puts " WARNING: Failed to update #{rel}: #{e.message}" puts " You may need to update this lock file manually." end- def bundle_update_shakapacker_in(dir) + def bundle_update_shakapacker_in(dir, gemfile_basename) required_version = detect_bundler_ruby_version(dir) if required_version && required_version != RUBY_VERSION puts " Switching Ruby: #{RUBY_VERSION} -> #{required_version}" - bundle_update_with_ruby_version(dir, required_version) + bundle_update_with_ruby_version(dir, required_version, gemfile_basename) else - unbundled_sh_in_dir(dir, "bundle update shakapacker") + unbundled_sh_in_dir(dir, "BUNDLE_GEMFILE=#{gemfile_basename} bundle update shakapacker") end end#!/bin/bash # Verify whether the repo has non-default Gemfiles containing shakapacker # and whether they have their own lockfiles that the current Gemfile.lock glob misses. fd -HI -t f '^Gemfile(\..+)?$' | while read -r gemfile; do case "$gemfile" in *.lock|*gen-examples*) continue ;; esac if rg -n 'gem "shakapacker"' "$gemfile" >/dev/null; then lockfile="${gemfile}.lock" if [ -f "$lockfile" ]; then printf '%s -> %s\n' "$gemfile" "$lockfile" else printf '%s -> <no sibling lockfile>\n' "$gemfile" fi fi doneAlso applies to: 94-115
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@AGENTS.md`:
- Around line 59-65: Update the documented rake invocation to run under Bundler:
replace occurrences of "rake shakapacker:update_version[...]" (including the
example "rake shakapacker:update_version[9.6.1]") with "bundle exec rake
shakapacker:update_version[VERSION]" (or "bundle exec rake
shakapacker:update_version[9.6.1]" for the example) so the task is always run
via Bundler.
---
Duplicate comments:
In `@react_on_rails/rakelib/shakapacker_version.rake`:
- Around line 13-14: The current version validation using version.match? allows
trailing or repeated separators (e.g. "9.6.1-" or "9.6.1...."); update the regex
used by version.match? in the rake task to a stricter pattern that only permits
the core semver (MAJOR.MINOR.PATCH) optionally followed by prerelease/build
identifiers where each identifier is an alphanumeric group separated by a single
dot or hyphen (no trailing separators and no empty groups), so replace the
existing version.match? check with a regex that enforces "digits.digits.digits"
and, if present, only ".|-" followed by one or more alphanumerics (repeated as
needed); keep the same raise "Invalid version format '#{version}'..." behavior
when the new validation fails.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b1e431ed-dc75-45b0-9b29-00bbc14015f8
⛔ Files ignored due to path filters (6)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlreact_on_rails/Gemfile.lockis excluded by!**/*.lockreact_on_rails/spec/dummy/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/spec/dummy/Gemfile.lockis excluded by!**/*.lockreact_on_rails_pro/spec/execjs-compatible-dummy/Gemfile.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
AGENTS.mdreact_on_rails/Gemfile.development_dependenciesreact_on_rails/rakelib/shakapacker_version.rakereact_on_rails/spec/dummy/package.jsonreact_on_rails_pro/Gemfile.development_dependenciesreact_on_rails_pro/spec/dummy/package.jsonreact_on_rails_pro/spec/execjs-compatible-dummy/Gemfilereact_on_rails_pro/spec/execjs-compatible-dummy/package.json
🚧 Files skipped from review as they are similar to previous changes (4)
- react_on_rails_pro/spec/execjs-compatible-dummy/Gemfile
- react_on_rails_pro/Gemfile.development_dependencies
- react_on_rails_pro/spec/execjs-compatible-dummy/package.json
- react_on_rails/spec/dummy/package.json
| # Dependency version updates | ||
| rake shakapacker:update_version[9.6.1] # Update shakapacker across the monorepo | ||
| ``` | ||
|
|
||
| ### Updating Shakapacker | ||
|
|
||
| Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo. This single command updates all Gemfiles, package.json files, Gemfile.lock files, and pnpm-lock.yaml. Do **not** manually edit individual version references — always use the rake task to keep everything in sync. |
There was a problem hiding this comment.
Document this task with bundle exec rake.
Line 60 and Line 65 currently show a plain rake invocation even though this repo’s policy is to run Ruby commands through Bundler. Please document the new task as bundle exec rake shakapacker:update_version[...] so agents don’t run it against the wrong gem set.
✏️ Suggested wording
-# Dependency version updates
-rake shakapacker:update_version[9.6.1] # Update shakapacker across the monorepo
+# Dependency version updates
+bundle exec rake shakapacker:update_version[9.6.1] # Update shakapacker across the monorepo-Use `rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo.
+Use `bundle exec rake shakapacker:update_version[VERSION]` to update shakapacker across the entire monorepo.Based on learnings: Use bundle exec for Ruby commands.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@AGENTS.md` around lines 59 - 65, Update the documented rake invocation to run
under Bundler: replace occurrences of "rake shakapacker:update_version[...]"
(including the example "rake shakapacker:update_version[9.6.1]") with "bundle
exec rake shakapacker:update_version[VERSION]" (or "bundle exec rake
shakapacker:update_version[9.6.1]" for the example) so the task is always run
via Bundler.
## Summary - Add changelog entries for 6 user-visible PRs merged since v16.4.0.rc.6 that were missing from `[Unreleased]` - Update existing #2561 entry to include #2568 contributor credit ### New entries added | Section | PR | Description | |---|---|---| | Added | #2539 | Environment-variable-driven ports in Procfile templates | | Fixed | #2417 | Rspack generator config path fix | | Fixed | #2419 | Precompile hook load-based execution fix | | Fixed | #2577 | `create-react-on-rails-app` validation improvements | | Pro Fixed | #2416 | StreamResponse status fallback fix | | Pro Fixed | #2566 | Empty-string license plan mismatch fix | ### Skipped PRs (not user-visible) Docs (#2406, #2414, #2479, #2494, #2518, #2537, #2544), CI/internal (#2533, #2547, #2555, #2557, #2558, #2564), dependabot (#2387, #2541), dev dependencies (#2559, #2569, #2573). ## Test plan - [ ] Verify changelog formatting matches existing entries - [ ] Verify all user-visible PRs since v16.4.0.rc.6 are covered 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Documentation-only changelog updates with no runtime or build behavior changes. > > **Overview** > Updates `CHANGELOG.md`’s **[Unreleased]** section to include previously missing user-facing entries: Procfile templates now support env-driven ports, several generator/`bin/dev` precompile-hook and rspack-path fixes are documented, and `create-react-on-rails-app` validation improvements are noted. > > Also adds two Pro fix entries (StreamResponse status fallback and license plan empty-string validation) and updates the existing `bin/dev` precompile-hook entry to credit an additional PR/contributor. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e75d2b5. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.6 <[email protected]>


Summary
rake shakapacker:update_version[VERSION]to update all shakapacker version references and lock files across the monorepo in one command=pin prefixes), updates package.json (preserving^/~prefixes), runsbundle update shakapackerfor all Gemfile.lock files, and runspnpm installfor pnpm-lock.yamlTest plan
rake shakapacker:update_version[9.6.1]correctly updates all version references and lock files🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation