Skip to content

Conversation

@Judahmeek
Copy link
Contributor

@Judahmeek Judahmeek commented Nov 16, 2025

This change is Reviewable

Summary by CodeRabbit

  • New Features

    • New configuration options for automatic bundle loading and component subdirectory organization.
  • Chores

    • Optimized CI/CD workflows with improved matrix strategy generation and job organization.
    • Enhanced code quality and formatting across tests and configuration files.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 16, 2025

Walkthrough

This PR refactors GitHub Actions workflows across the repository by introducing dynamic matrix translation layers, standardizing job naming conventions with descriptive prefixes and names, and updating React on Rails Pro library code with improved syntax patterns. The changes replace static matrix references with computed outputs from a centralized detect-changes job and modernize internal implementation details in request handling and block invocation patterns.

Changes

Cohort / File(s) Summary
CI Matrix Translation & Dynamic Configuration
.github/workflows/examples.yml, integration-tests.yml, package-js-tests.yml, gem-tests.yml
Introduced Determine matrix strategy steps outputting matrix_array and Translate matrix steps producing ruby-version/node-version outputs; replaced static matrix definitions with dynamic fromJson(needs.detect-changes.outputs.matrix_array) and updated all downstream references (ruby setup, cache keys, artifact naming) to consume translated outputs instead of direct matrix references.
CI Workflow Job Renames
.github/workflows/lint-js-and-ruby.yml, pro-integration-tests.yml, pro-lint.yml, pro-test-package-and-gem.yml
Renamed jobs for clarity and consistency: buildlint-js-and-ruby, build-dummy-app-webpack-test-bundlespro-build-dummy-app-webpack-test-bundles, rspec-dummy-app-node-rendererpro-dummy-app-node-renderer, dummy-app-node-renderer-e2e-testsnode-renderer-e2e-tests, rspec-package-specspro-gem-tests, and renamed the public test job from rspec-package-tests to basic-gem-tests. Added --ignore-parent-exclusion flag to the lint Ruby step in pro-lint.yml.
React on Rails Pro Library Refactoring
react_on_rails_pro/lib/react_on_rails_pro/request.rb, stream_request.rb, license_public_key.rb
Refactored retry_after handler from shorthand to explicit lambda block syntax, replaced block.call(...) with yield(...) in stream chunk processing, renamed exception variables from err to e, and re-indented PEM public key block (no content changes). Added RuboCop disable comment to create_connection method.
Spec & Test Updates
react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb, spec/dummy/spec/system/integration_spec.rb, spec/react_on_rails_pro/configuration_spec.rb, license_validator_spec.rb, stream_decorator_spec.rb, support/mock_block_helper.rb
Added RuboCop suppression comments for class/module length checks, corrected regex escape sequences in integration tests, refactored error object instantiation to use parenthesized syntax, updated raise statements to keyword-argument form, changed block invocation from block.call(...) to safe navigation block&.call(...), and minor test description formatting adjustments.
Rake & Generator Configuration
rakelib/shakapacker_examples.rake, react_on_rails_pro/rakelib/public_key_management.rake, lib/generators/react_on_rails/templates/.../react_on_rails.rb.tt
Modified example generator execution to batch commands with REACT_ON_RAILS_SKIP_VALIDATION=true prefix and invoke react_on_rails:generate_packs afterward; added RuboCop inline comments; updated string quoting styles; uncommented test build command configuration and added auto_load_bundle and components_subdirectory initialization options.

Sequence Diagram(s)

sequenceDiagram
    participant detect-changes
    participant job[downstream job]
    participant steps[steps in job]

    detect-changes->>detect-changes: Determine matrix strategy
    activate detect-changes
    detect-changes->>detect-changes: Output matrix_array
    deactivate detect-changes

    Note over detect-changes: matrix_array = ["latest"] or<br/>["latest","minimum"]

    job->>job: matrix computed from<br/>fromJson(needs.detect-changes.outputs.matrix_array)
    activate job
    job->>steps: Translate matrix for Ruby<br/>and Node versions
    activate steps
    alt dependency-level: "latest"
        steps->>steps: ruby-version = 3.4
    else dependency-level: "minimum"
        steps->>steps: ruby-version = 3.2
    end
    steps->>steps: Output ruby-version<br/>and node-version
    deactivate steps

    steps->>steps: Setup Ruby using<br/>steps.translate-matrix.outputs.ruby-version
    steps->>steps: Update cache key with<br/>translated ruby-version
    steps->>steps: Name artifacts/results with<br/>translated ruby-version
    deactivate job
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Matrix translation logic: Verify the fromJson() conversions and output wiring across four workflow files; ensure translated outputs correctly map to ruby/node versions across all downstream references
  • Job naming consistency: Confirm all cross-job dependencies (needs.*) are updated to match renamed job identifiers in workflows (particularly in pro-* workflows and matrix-dependent jobs)
  • Ruby library refactoring: Review block invocation pattern changes (block.call()yield()) and lambda syntax updates for correctness; verify exception variable renames preserve logging intent
  • Generator template activation: Confirm uncommented config options (build_test_command, auto_load_bundle, components_subdirectory) align with generator behavior expectations
  • Spec syntax consistency: Validate error object and raise statement refactoring across test files maintains identical assertion outcomes

Possibly related PRs

Suggested reviewers

  • alexeyr-ci
  • justin808
  • AbanoubGhadban

Poem

🐰 Matrices dance in dynamic flow,
Jobs renamed bright, now all aglow,
Blocks yield kindly, translations reign,
From chaos of refs, order's gained!
CI workflows shine, refactored with care,

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'WIP - Fix Pro Rubocop and other CI - will split up' is vague and uses non-descriptive language. It indicates work-in-progress status and references multiple unrelated concerns (Pro Rubocop fixes and general CI issues) without clearly identifying the primary change. The phrase 'will split up' suggests incomplete work. Replace with a more specific, descriptive title that clearly identifies the main change. Examples: 'Refactor GitHub Actions workflows for matrix translation' or 'Update CI configuration for Ruby/Node version handling' once the changes are finalized.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch judahmeek/pro-rubocop

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Nov 16, 2025

Code Review for PR #2034: Fix Pro Rubocop Linting

I've reviewed the changes in this PR. Here's my comprehensive feedback:

Overall Assessment

This PR successfully fixes RuboCop linting issues in the Pro package. The changes are well-structured and focused on code quality improvements.


Code Quality & Best Practices

Positives:

  • Consistent formatting improvements: Indentation fixes in license_public_key.rb improve readability
  • Better variable naming: Changed generic err to e for exception variables (consistent with Ruby conventions)
  • Improved code clarity: Multi-line lambda formatting in request.rb makes complex retry logic more readable
  • Proper RuboCop disabling: Uses targeted rubocop:disable comments with specific cop names rather than blanket disables
  • Better block usage: Changed block.call to yield in stream_request.rb:61 which is more idiomatic Ruby
  • RSpec improvements: Better context naming (when prefix) and proper expect { }.to raise_error blocks

Suggestions:

  1. license_public_key.rb:19-27: The indentation change is good, but the PEM key is now indented. Verify this doesn't affect key parsing (OpenSSL should handle it, but worth confirming)
  2. request.rb:220: The rubocop:disable Metrics/MethodLength, Metrics/AbcSize suggests this method could be refactored in a future PR

Potential Issues

Minor Concerns:

  1. public_key_management.rake:71: String quote change is fine, but ensure consistency with project's string literal style
  2. integration_spec.rb:399,406: The regex escape change is correct but ensure the tests still pass
  3. pages_controller.rb:88: Changed close_err to e - while more concise, close_error might be clearer

Critical:

  • .github/workflows/pro-lint.yml:151: The addition of --ignore-parent-exclusion flag is the CORRECT FIX since the Pro package has its own RuboCop config. This makes RuboCop ignore exclusions from parent .rubocop.yml (which excludes react_on_rails_pro/**/*). Ensure this doesn't cause issues if someone runs RuboCop from the root directory.

Security & Performance

  • No security concerns identified
  • No performance impact - all changes are formatting/linting related

Test Coverage

Observations:

  1. Spec file improvements: Better RSpec style with expect { }.to raise_error blocks
  2. Skipped test: integration_spec.rb:435 - Properly annotated with skip and RSpec/NoExpectationExample disable
  3. Test naming: Context names improved with when prefix

Additional Notes

GitHub Actions Renaming:
Excellent improvements for clarity:

  • build → lint-js-and-ruby
  • examples → build-examples-and-test-generators
  • dummy-app-integration-tests → spec-dummy-integration-tests
  • Pro-specific jobs now have pro- prefix

This makes CI logs much easier to navigate!


Recommendations Before Merge

  1. Run full lint check: cd react_on_rails_pro && bundle exec rubocop
  2. Verify tests pass: Especially the regex-related specs
  3. Confirm CI passes: The --ignore-parent-exclusion fix should make Pro linting work correctly
  4. Consider future refactoring: The create_connection method is still complex (65 lines)

Summary

Approve with minor observations. This is a solid cleanup PR that:

  • Fixes legitimate RuboCop violations
  • Improves code readability
  • Corrects CI configuration for Pro package linting
  • Follows Ruby and RSpec best practices

The --ignore-parent-exclusion flag is the key fix that allows the Pro package to be linted independently, which is the correct architectural approach for a monorepo with separate linting configs.

Great work!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37f5894 and e47b626.

📒 Files selected for processing (17)
  • .github/workflows/examples.yml (1 hunks)
  • .github/workflows/integration-tests.yml (1 hunks)
  • .github/workflows/lint-js-and-ruby.yml (1 hunks)
  • .github/workflows/package-js-tests.yml (1 hunks)
  • .github/workflows/pro-integration-tests.yml (3 hunks)
  • .github/workflows/pro-lint.yml (2 hunks)
  • .github/workflows/pro-test-package-and-gem.yml (3 hunks)
  • react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb (1 hunks)
  • react_on_rails_pro/lib/react_on_rails_pro/request.rb (2 hunks)
  • react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb (1 hunks)
  • react_on_rails_pro/rakelib/public_key_management.rake (3 hunks)
  • react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb (2 hunks)
  • react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb (2 hunks)
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb (3 hunks)
  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb (6 hunks)
  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb (5 hunks)
  • react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • react_on_rails_pro/lib/react_on_rails_pro/request.rb
  • .github/workflows/pro-test-package-and-gem.yml
  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/rakelib/public_key_management.rake
  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • .github/workflows/pro-test-package-and-gem.yml
  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/rakelib/public_key_management.rake
  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
📚 Learning: 2024-10-08T20:53:47.076Z
Learnt from: theforestvn88
Repo: shakacode/react_on_rails PR: 1620
File: spec/dummy/client/app/startup/HelloTurboStream.jsx:3-3
Timestamp: 2024-10-08T20:53:47.076Z
Learning: The `RailsContext` import in `spec/dummy/client/app/startup/HelloTurboStream.jsx` is used later in the project, as clarified by the user theforestvn88.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
📚 Learning: 2025-02-13T16:50:47.848Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/clientStartup.ts:18-21
Timestamp: 2025-02-13T16:50:47.848Z
Learning: In the react_on_rails module, the `reactOnRailsPageUnloaded` function in clientStartup.ts is intentionally kept private as it's only used internally as a callback for `onPageUnloaded`.

Applied to files:

  • react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb
  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/rakelib/public_key_management.rake
📚 Learning: 2025-02-13T14:29:49.267Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: spec/react_on_rails/utils_spec.rb:218-218
Timestamp: 2025-02-13T14:29:49.267Z
Learning: In RSpec tests, prefer using local variables over constants within test blocks to avoid constant redefinition warnings and maintain better test isolation.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb
  • react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb
  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
  • react_on_rails_pro/rakelib/public_key_management.rake
  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation is handled in deeper level calls of the React on Rails Pro codebase, so it doesn't need to be validated again in the `rsc_payload_react_component` helper method.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
📚 Learning: 2024-10-08T20:53:47.076Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1622
File: spec/dummy/spec/rake/assets_precompile_rake_spec.rb:12-12
Timestamp: 2024-10-08T20:53:47.076Z
Learning: When stubbing environment variables in RSpec tests, use `before` and `after` hooks to ensure that the original values are restored after the tests, preventing any side effects on other tests. Example provided by justin808:
```ruby
describe "My test" do
  before do
    original_value = ENV["VARIABLE_NAME"]
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_return("stubbed_value")
  end

  after do
    allow(ENV).to receive(:[]).with("VARIABLE_NAME").and_call_original
    ENV["VARIABLE_NAME"] = original_value
  end

  it "tests something" do
    # Your test code here
  end
end
```
This practice ensures test isolation and reliability.

Applied to files:

  • react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb
📚 Learning: 2025-04-09T13:02:16.009Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1696
File: node_package/src/transformRSCNodeStream.ts:3-31
Timestamp: 2025-04-09T13:02:16.009Z
Learning: In the React Server Components (RSC) stream processing implementation, all chunks end with a newline character (`\n`), so the `lastIncompleteChunk` variable is expected to be empty by the time the stream ends, making a flush handler unnecessary in the Transform stream.

Applied to files:

  • react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb
🧬 Code graph analysis (4)
react_on_rails_pro/lib/react_on_rails_pro/request.rb (2)
react_on_rails_pro/packages/node-renderer/tests/htmlStreaming.test.js (1)
  • request (25-29)
packages/react-on-rails-pro/tests/testUtils.js (1)
  • stream (14-21)
react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb (1)
react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb (1)
  • mock_block (12-21)
react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb (1)
react_on_rails_pro/lib/react_on_rails_pro/configuration.rb (1)
  • configuration (9-38)
react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb (2)
react_on_rails_pro/lib/react_on_rails_pro/utils.rb (1)
  • validated_license_data! (58-60)
react_on_rails_pro/lib/react_on_rails_pro/license_validator.rb (2)
  • validated_license_data! (6-187)
  • validated_license_data! (15-40)
🪛 GitHub Actions: Lint JS and Ruby
.github/workflows/pro-integration-tests.yml

[error] 150-150: job "pro-dummy-app-node-renderer" needs job "build-dummy-app-webpack-test-bundles" which does not exist in this workflow

🪛 GitHub Check: actionlint
.github/workflows/pro-test-package-and-gem.yml

[failure] 150-150:
job "pro-package-js-tests" needs job "build-dummy-app-webpack-test-bundles" which does not exist in this workflow

.github/workflows/pro-integration-tests.yml

[failure] 150-150:
job "pro-dummy-app-node-renderer" needs job "build-dummy-app-webpack-test-bundles" which does not exist in this workflow


[failure] 327-327:
job "node-renderer-e2e-tests" needs job "build-dummy-app-webpack-test-bundles" which does not exist in this workflow

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: claude-review
🔇 Additional comments (32)
.github/workflows/examples.yml (1)

60-60: LGTM!

Job identifier rename is clear and self-contained. No downstream references to update in this file.

.github/workflows/lint-js-and-ruby.yml (1)

61-61: LGTM!

Job identifier rename improves clarity. Self-contained change with no downstream references to update in this file.

.github/workflows/package-js-tests.yml (1)

66-66: LGTM!

Job identifier rename is clear and improves readability. Self-contained change with no downstream references to update.

.github/workflows/integration-tests.yml (1)

144-144: LGTM!

Job identifier rename aligns with the spec/dummy directory naming convention. Self-contained change with no downstream references.

.github/workflows/pro-lint.yml (2)

64-64: LGTM!

Job rename from lint-js-and-ruby to pro-lint-js-and-ruby is descriptive and follows the Pro-specific naming convention.


151-151: Verify the RuboCop --ignore-parent-exclusion flag addition.

The flag is now added to the RuboCop lint step. Verify that this flag is:

  1. Appropriate for Pro-specific linting within the react_on_rails_pro directory (set at line 30: working-directory)
  2. The intended behavior to ignore parent .rubocop.yml configurations

This change makes sense contextually but confirm the linting behavior is as expected, especially if shared .rubocop.yml configurations should or should not apply to Pro linting.

.github/workflows/pro-test-package-and-gem.yml (2)

65-65: LGTM!

Job identifier rename to pro-build-dummy-app-webpack-test-bundles aligns with Pro-specific naming convention.


230-230: LGTM!

Job rename from rspec-package-specs to pro-gem-tests is descriptive and aligns with Pro-specific naming. No downstream dependencies to update in this file.

.github/workflows/pro-integration-tests.yml (2)

65-65: LGTM!

Job identifier rename to pro-build-dummy-app-webpack-test-bundles aligns with Pro-specific naming convention.


327-327: LGTM!

Job rename from dummy-app-node-renderer-e2e-tests to node-renderer-e2e-tests simplifies naming. This aligns with the E2E test focus and removes redundancy.

react_on_rails_pro/lib/react_on_rails_pro/license_public_key.rb (1)

19-27: LGTM! Formatting change doesn't affect key value.

The re-indentation of the PEM key block is a cosmetic change for RuboCop compliance. Since the heredoc uses .strip.strip_heredoc, the indentation changes won't affect the actual public key value used at runtime.

react_on_rails_pro/rakelib/public_key_management.rake (5)

16-16: Appropriate RuboCop directive for Rake namespace.

The Metrics/BlockLength disable is justified here, as Rake namespaces legitimately contain multiple tasks and naturally result in longer blocks.


18-18: Appropriate RuboCop directive for Rake task.

The Metrics/BlockLength disable is justified for this task, which performs multiple operations (fetching, parsing, updating files) that warrant a longer method body.


71-71: Good style improvement: single quotes for non-interpolated strings.

Changing to single quotes follows Ruby best practices, as the format string doesn't require interpolation.


89-90: LGTM! Formatting improvement for readability.

Splitting the path construction across multiple lines improves readability without affecting functionality.


95-95: Good style improvement: consistent quote usage.

Matching the change at line 71, this follows Ruby best practices for non-interpolated strings.

react_on_rails_pro/spec/dummy/spec/system/integration_spec.rb (2)

399-399: LGTM! Regex pattern corrected.

The unnecessary backslash escape before the double quote inside the character class has been properly removed. Inside a character class [...], double quotes don't need escaping.

Also applies to: 406-406


435-435: LGTM! Appropriate RuboCop suppression.

The RuboCop disable comment for RSpec/NoExpectationExample is correctly placed on this skipped test that intentionally has no expectations.

react_on_rails_pro/spec/react_on_rails_pro/support/mock_block_helper.rb (1)

15-15: LGTM! Idiomatic Ruby safe navigation.

The safe navigation operator (&.) is the preferred modern Ruby idiom for conditional method calls, replacing the trailing if condition.

react_on_rails_pro/spec/react_on_rails_pro/license_validator_spec.rb (2)

78-157: LGTM! Test formatting improvements.

The context descriptions and multi-line expectations have been reformatted for better readability and RuboCop compliance. No behavioral changes to the test assertions.


180-202: LGTM! Consistent multi-line formatting.

The expectation blocks have been consistently formatted across all error test cases, improving readability while preserving test behavior.

react_on_rails_pro/spec/dummy/app/controllers/pages_controller.rb (2)

3-3: LGTM! Appropriate suppression for test controller.

The Metrics/ClassLength suppression is reasonable for this dummy test controller that implements numerous endpoints for comprehensive integration testing.


88-89: LGTM! Standard exception variable naming.

Renaming the rescue variable to e follows Ruby conventions for exception handling. The log message remains unchanged and functional.

react_on_rails_pro/lib/react_on_rails_pro/request.rb (2)

220-220: LGTM! Justified metric suppressions.

The create_connection method configures complex HTTP client behavior with retries, timeouts, and connection pooling. The metric suppressions are appropriate for this initialization code.


232-262: LGTM! Explicit lambda improves readability.

The refactor from shorthand to explicit lambda block with proper indentation and comments makes the retry logic clearer, especially given the complexity of handling streaming errors versus connection errors.

react_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb (2)

5-5: LGTM! Appropriate suppression for comprehensive test module.

The Metrics/ModuleLength suppression is justified for this configuration spec that comprehensively tests all ReactOnRailsPro configuration options.


208-209: LGTM! Improved expectation readability.

The multi-line formatting for long configuration key expectations improves readability while preserving the assertions.

Also applies to: 233-234

react_on_rails_pro/spec/react_on_rails_pro/stream_decorator_spec.rb (2)

68-68: LGTM! Consistent error instantiation syntax.

The error objects are instantiated with proper parentheses: StandardError.new("message") and ArgumentError.new("message").

Also applies to: 83-83, 99-99, 118-118, 132-132


122-122: LGTM! Preferred raise syntax.

The keyword argument form raise ArgumentError, "message" is the Ruby style guide's preferred syntax over raise ArgumentError.new "message".

Also applies to: 137-137

react_on_rails_pro/lib/react_on_rails_pro/stream_request.rb (3)

54-54: LGTM! Justified complexity suppression.

The each_chunk method handles streaming with position tracking, chunk processing, and multi-level error rescue chains. The complexity suppression is appropriate for this critical streaming logic.


61-61: LGTM! Idiomatic block invocation.

Using yield is more idiomatic than block.call when the method signature explicitly accepts a block with &block. The guard clause at Line 55 ensures the block is present, making yield safe.

Also applies to: 68-68


69-70: LGTM! Improved variable naming.

The rename from err to e follows Ruby exception naming conventions, and current_error better describes the variable's role in the rescue loop that chains through multiple rescue blocks.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
.github/workflows/integration-tests.yml (1)

72-82: Refactor: Consolidate duplicated "Translate matrix" step logic.

The "Translate matrix for Ruby and Node versions" step is defined identically at lines 72–82 and 159–168. This violates DRY and creates maintenance burden if the translation logic needs to change (it would need to be updated in multiple places).

Consider extracting this step into a reusable GitHub Action at .github/actions/translate-matrix to eliminate duplication across jobs and workflows. This will also make it easier to maintain and share logic across all three workflows (gem-tests.yml, integration-tests.yml, examples.yml).

Example action structure:

# .github/actions/translate-matrix/action.yml
name: Translate matrix for Ruby and Node versions
description: Derive Ruby and Node versions from dependency-level
inputs:
  dependency-level:
    description: 'Dependency level (latest or minimum)'
    required: true
outputs:
  ruby-version:
    value: ${{ steps.compute.outputs.ruby-version }}
  node-version:
    value: ${{ steps.compute.outputs.node-version }}
runs:
  using: composite
  steps:
    - id: compute
      shell: bash
      run: |
        if [ "${{ inputs.dependency-level }}" == "latest" ]; then
          echo "ruby-version=3.4" >> "$GITHUB_OUTPUT"
          echo "node-version=22" >> "$GITHUB_OUTPUT"
        else
          echo "ruby-version=3.2" >> "$GITHUB_OUTPUT"
          echo "node-version=20" >> "$GITHUB_OUTPUT"
        fi

Then replace both inline steps with:

- uses: ./.github/actions/translate-matrix
  id: translate-matrix
  with:
    dependency-level: ${{ matrix.dependency-level }}

Also applies to: 159-168

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e47b626 and 1cb3a3a.

📒 Files selected for processing (6)
  • .github/workflows/examples.yml (3 hunks)
  • .github/workflows/gem-tests.yml (4 hunks)
  • .github/workflows/integration-tests.yml (6 hunks)
  • .github/workflows/package-js-tests.yml (1 hunks)
  • .github/workflows/pro-integration-tests.yml (3 hunks)
  • .github/workflows/pro-test-package-and-gem.yml (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/pro-test-package-and-gem.yml
  • .github/workflows/pro-integration-tests.yml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • .github/workflows/integration-tests.yml
🪛 GitHub Actions: Lint JS and Ruby
.github/workflows/examples.yml

[error] 68-68: GitHub Actions workflow parsing error: unexpected token '[' while parsing variable access, function call, null, bool, int, float or string. expecting IDENT, (, INTEGER, FLOAT, STRING

🪛 GitHub Check: actionlint
.github/workflows/gem-tests.yml

[failure] 72-72:
unexpected token "[" while parsing variable access, function call, null, bool, int, float or string. expecting "IDENT", "(", "INTEGER", "FLOAT", "STRING"


[failure] 83-83:
property "translate-matrix" is not defined in object type {}


[failure] 101-101:
property "translate-matrix" is not defined in object type {}


[failure] 123-123:
property "translate-matrix" is not defined in object type {}


[failure] 118-118:
property "translate-matrix" is not defined in object type {}

.github/workflows/integration-tests.yml

[failure] 69-69:
unexpected token "[" while parsing variable access, function call, null, bool, int, float or string. expecting "IDENT", "(", "INTEGER", "FLOAT", "STRING"


[failure] 156-156:
unexpected token "[" while parsing variable access, function call, null, bool, int, float or string. expecting "IDENT", "(", "INTEGER", "FLOAT", "STRING"

.github/workflows/examples.yml

[failure] 68-68:
unexpected token "[" while parsing variable access, function call, null, bool, int, float or string. expecting "IDENT", "(", "INTEGER", "FLOAT", "STRING"

.github/workflows/package-js-tests.yml

[failure] 74-74:
unexpected token "[" while parsing variable access, function call, null, bool, int, float or string. expecting "IDENT", "(", "INTEGER", "FLOAT", "STRING"

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
🔇 Additional comments (4)
.github/workflows/package-js-tests.yml (2)

66-66: Job rename approved.

Renaming build to package-js-tests improves clarity and aligns with standardization objectives.


72-72: Addition of fail-fast: false is reasonable.

This allows other test matrix jobs to continue even if one fails, improving observability across Node versions.

.github/workflows/examples.yml (1)

60-60: No external references found—the job rename is safe.

Comprehensive search across the repository confirms there are no dependencies on the old job name examples. Specifically:

  • No workflows contain needs: examples patterns
  • No workflow_run triggers reference the old job name
  • No documentation or CI configurations reference the old job name

The rename from examples to build-examples-and-test-generators poses no risk of breaking CI dependencies.

.github/workflows/integration-tests.yml (1)

148-148: Update documentation reference to reflect job rename: SWITCHING_CI_CONFIGS.md

The search results confirm that dummy-app-integration-tests only appears once outside the integration-tests workflow—in SWITCHING_CI_CONFIGS.md as an example CI failure scenario. No other workflow files reference the old job name, so the rename won't break CI dependencies. However, the documentation should be updated to use the new job name spec-dummy-integration-tests (3.2, 20, minimum) for consistency and accuracy.

⛔ Skipped due to learnings
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Comment on lines +74 to +83
- name: Translate matrix for Ruby and Node versions
id: translate-matrix
run: |
if [ "${{ matrix.dependency-level }}" == "latest" ]; then
echo "ruby-version=3.4" >> "$GITHUB_OUTPUT"
echo "node-version=22" >> "$GITHUB_OUTPUT"
else
echo "ruby-version=3.2" >> "$GITHUB_OUTPUT"
echo "node-version=20" >> "$GITHUB_OUTPUT"
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Inconsistency: Translate matrix step computes node-version but it's ignored on line 95.

The "Translate matrix for Ruby and Node versions" step (lines 74–83) outputs both ruby-version and node-version based on the dependency-level. Ruby version is correctly consumed at line 90 (ruby-version: ${{ steps.translate-matrix.outputs.ruby-version }}), but Node setup at line 95 hardcodes node-version: 20 instead of using the translated output.

This is problematic because:

  • For dependency-level == 'latest', the step sets node-version=22 (line 79), but line 95 forces Node 20
  • For dependency-level == 'minimum', the step sets node-version=20 (line 82), which accidentally matches the hardcoded value
  • This makes the node-version translation output dead code and reduces maintainability

Apply this diff to use the translated node-version:

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
-         node-version: 20
+         node-version: ${{ steps.translate-matrix.outputs.node-version }}
          # TODO: Re-enable yarn caching once Node.js V8 cache crash is fixed
          # Tracking: https://github.com/actions/setup-node/issues/1028
          # cache: yarn
          # cache-dependency-path: '**/yarn.lock'

Also applies to: 95-95

🤖 Prompt for AI Agents
.github/workflows/examples.yml lines 74-95: the translate-matrix step writes
both ruby-version and node-version outputs but the Node setup at line 95 is
hardcoded to 20; change the Node setup to consume the generated output by
replacing the hardcoded node-version: 20 with node-version: ${{
steps.translate-matrix.outputs.node-version }} so the workflow respects the
dependency-level translation (ensure spacing/indentation matches the surrounding
YAML).

@Judahmeek Judahmeek force-pushed the judahmeek/pro-rubocop branch from c2c6f67 to b34c1de Compare November 16, 2025 22:06
@claude
Copy link

claude bot commented Nov 16, 2025

Code Review - PR #2034: Fix Pro Rubocop Linting

I've reviewed this PR which fixes Pro RuboCop linting and refactors the CI workflows. Here's my feedback:


Strengths

1. CI Workflow Improvements

  • Centralized matrix strategy: The new determine-matrix step centralizes the logic for deciding which dependency levels to test, making the workflow more maintainable.
  • Translation step: The translate-matrix step that maps dependency-level to specific Ruby/Node versions is a cleaner approach than the previous include/exclude matrix setup.
  • Job naming: Renaming jobs (e.g., examplesbuild-examples-and-test-generators, buildlint-js-and-ruby) provides better clarity in CI dashboards.
  • Fail-fast disabled: Setting fail-fast: false on integration test jobs ensures all matrix configurations run even if one fails, which is good for comprehensive testing.

2. RuboCop Fix

  • --ignore-parent-exclusion flag: This is the correct solution for Pro package linting. Since the root .rubocop.yml excludes react_on_rails_pro/**/*, the Pro package needs this flag to use its own configuration independently.

3. Code Formatting Fixes

  • License public key indentation and comment formatting changes in request.rb and stream_request.rb properly align with RuboCop's layout rules.
  • All formatting changes follow the project's established conventions.

🔍 Observations & Questions

1. Removed Node 22 Cache Workaround

-          cache: ${{ matrix.node-version \!= '22' && 'yarn' || '' }}
+          cache: yarn

Question: The original code disabled caching for Node 22 due to a V8 bug (nodejs/node#56010). Has this bug been resolved, or is this change intentional? If the bug still exists, this could cause CI failures.

Recommendation: Verify the Node.js issue status. If it's still open, consider keeping the conditional caching or documenting why it's safe to remove.

2. Matrix Strategy Complexity

The new approach uses:

  1. determine-matrix step to create a JSON array
  2. fromJson() to parse it into the matrix
  3. translate-matrix step to convert to versions

While this works, it's a bit complex. Consider documenting this pattern in CLAUDE.md or adding inline comments explaining the approach.

3. Missing Translation Step in gem-tests.yml

In .github/workflows/gem-tests.yml, the matrix uses dependency-level and references steps.translate-matrix.outputs.ruby-version, but I don't see the translate-matrix step added to this workflow in the diff. This would cause the workflow to fail.

Critical Issue: Please verify this file has the translation step added.


🐛 Potential Issues

1. RuboCop Disable Comments

def create_connection # rubocop:disable Metrics/MethodLength, Metrics/AbcSize

While these disable comments fix the immediate linting issue, consider refactoring this method to reduce complexity. The method is 77 lines long with multiple responsibilities:

  • Connection setup
  • Plugin configuration
  • Retry logic
  • Error handling

Suggestion: Extract the retry configuration into a separate method for better maintainability.

2. Test Expectations Using all()

expect(chunks).to all(match(/^CHUNK\d$/))
expect(chunks[1..-2]).to all(match(/^CHUNK\d$/))

The regex pattern /^CHUNK\d$/ only matches single-digit chunk numbers (CHUNK0-CHUNK9). If you have 10+ chunks in tests, this will fail.

Recommendation: Use /^CHUNK\d+$/ to match one or more digits.


🔒 Security Considerations

No security issues identified. The changes are primarily CI configuration and code formatting.


🧪 Test Coverage

Positive

  • Existing RSpec tests ensure the Pro package functionality remains intact
  • CI workflow changes will be validated automatically when this PR runs

Gaps

  • No new tests added for the refactored code (though this is a linting fix, so that's acceptable)
  • Consider adding a test case with 10+ chunks to verify the regex pattern works correctly

Performance Considerations

  • The CI refactoring should have minimal performance impact
  • Running both latest and minimum dependency levels in parallel on PRs (when not on master) is good for early detection
  • The new matrix approach may be slightly slower to parse but the difference is negligible

📝 Documentation & Conventions

Per CLAUDE.md:

  • ✅ RuboCop must pass before commits - this PR addresses that
  • ✅ Files should end with newlines - verified in formatting changes
  • ✅ Prettier/RuboCop handle formatting - all changes appear to be auto-formatted
  • ⚠️ Consider updating CLAUDE.md to document the new CI matrix pattern

🎯 Recommendations

Must Fix (Blocking)

  1. ✅ Verify gem-tests.yml has the translate-matrix step (might be present but not visible in diff)
  2. ⚠️ Confirm Node 22 cache bug status and document the decision

Should Fix (High Priority)

  1. Fix regex pattern in test expectations: /^CHUNK\d$//^CHUNK\d+$/
  2. Consider refactoring create_connection method to reduce complexity

Nice to Have

  1. Add inline comments explaining the matrix translation pattern
  2. Extract retry configuration to separate methods for better readability

Overall Assessment

This is a solid PR that accomplishes its goals:

  • ✅ Fixes Pro RuboCop linting
  • ✅ Improves CI workflow maintainability
  • ✅ Applies consistent formatting across Pro package
  • ✅ Makes job names more descriptive

The CI refactoring is well-thought-out and addresses the complexity of the previous include/exclude matrix approach. The main concerns are:

  1. Verifying the Node 22 cache change is intentional
  2. Ensuring all workflows have the necessary translation steps
  3. Minor test regex pattern issue

Recommendation: Address the critical items above, then this should be good to merge! 🚀

@claude
Copy link

claude bot commented Nov 16, 2025

Code Review - PR #2034: Fix Pro Rubocop Linting

I've reviewed this PR and here's my comprehensive feedback:

✅ Positive Changes

1. GitHub Actions Workflow Improvements

  • Matrix Strategy Refactoring: The shift from include/exclude patterns to dynamic fromJson matrices is cleaner and more maintainable
  • Runtime Version Translation: The new translate-matrix step centralizes version mapping logic, reducing duplication across jobs
  • Job Naming: Better descriptive job names (e.g., build-examples-and-test-generators, spec-dummy-integration-tests) improve CI pipeline readability
  • Consistent Artifact Naming: Artifact names now use translated versions consistently, making it easier to track artifacts across different dependency levels

2. Ruby Code Formatting (RuboCop Fixes)

license_public_key.rb:18-28

  • Fixed heredoc indentation - the PEM key content is now properly indented relative to the heredoc delimiter
  • This aligns with RuboCop's Layout/HeredocIndentation cop

request.rb:220

  • Added rubocop:disable Metrics/MethodLength, Metrics/AbcSize for create_connection method
  • Method complexity is justified due to extensive HTTPX configuration needs
  • Good inline comment explaining the complex retry_after lambda logic (lines 232-262)

request.rb:232-242

  • Improved code readability with proper indentation and line breaks
  • Comments now explain the HTTPx retry behavior edge case clearly

🔍 Issues & Concerns

1. Pro Lint Workflow Change (Critical)

.github/workflows/pro-lint.yml:151

- run: bundle exec rubocop --ignore-parent-exclusion

Concern: The addition of --ignore-parent-exclusion flag suggests the Pro package may be inheriting exclusions from the parent .rubocop.yml that need to be bypassed.

Questions:

  • Why is this flag needed? Are there specific files in the Pro package that were incorrectly excluded by parent config?
  • Could this mask legitimate exclusions and allow violations in files that should be skipped?
  • Is this a temporary workaround or permanent solution?

Recommendation:

  • Document why --ignore-parent-exclusion is necessary in CLAUDE.md
  • Consider creating a dedicated .rubocop.yml in react_on_rails_pro/ to explicitly define its own exclusions rather than using this flag

2. Node 22 Cache Re-enabled

.github/workflows/integration-tests.yml:108

# Disable cache for Node 22 due to V8 bug in 22.21.0
# https://github.com/nodejs/node/issues/56010
- cache: yarn
+ cache: yarn

Concern: The comment about Node 22 V8 bug was removed, but the conditional logic was also removed.

Questions:

  • Has the V8 bug in Node 22.21.0 been resolved?
  • Is the project now using a newer Node 22 version that fixes this issue?
  • If not, re-enabling cache could reintroduce the bug

Recommendation:

  • Verify the current Node 22 version being used
  • If the bug is fixed, update comments to indicate which version resolved it
  • If not fixed, restore the conditional caching

3. Test Coverage Gaps

No new tests were added for:

  • The new matrix determination logic in workflows
  • The runtime version translation logic
  • The --ignore-parent-exclusion flag impact

Recommendation:

  • Consider adding integration tests that verify the correct dependency levels run in different scenarios (PR vs master, with/without labels)

4. Complexity in HTTP Retry Logic

request.rb:242-262
The retry_after lambda is quite complex with instance variable inspection:

retry_after: lambda do |request, response|
  if request.stream.instance_variable_get(:@react_on_rails_received_first_chunk)
    # raise error...
  end
  # ...
end

Concerns:

  • Using instance_variable_get couples code to HTTPx internal implementation details
  • If HTTPx changes how streams work, this could break silently
  • The logic depends on stream_request.rb:157 setting this instance variable

Recommendation:

  • Consider wrapping the stream in a custom class that exposes received_first_chunk? as a public API
  • Add integration tests that specifically verify streaming error handling doesn't cause duplication

📊 Code Quality Metrics

Changed Files: 18 files (+210, -160)

  • Workflow files: 8 files (mostly structural improvements)
  • Ruby Pro package: 10 files (formatting + logic fixes)

RuboCop Compliance: The changes appear to fix formatting violations, but without running RuboCop locally, I cannot confirm all violations are resolved.

🔒 Security Considerations

No security concerns identified

  • License key changes are formatting only (no key material changed)
  • HTTP timeout/retry changes don't introduce new attack vectors
  • Workflow changes don't expose secrets or reduce security

📝 Recommendations Summary

  1. High Priority: Document the reason for --ignore-parent-exclusion flag in pro-lint workflow
  2. High Priority: Verify Node 22 cache re-enablement is safe (check if V8 bug is fixed)
  3. Medium Priority: Consider reducing coupling with HTTPx internals in retry logic
  4. Low Priority: Add comments explaining the matrix determination strategy for future maintainers

✅ Approval Status

The code quality improvements and CI refactoring are excellent. However, I'd recommend addressing the --ignore-parent-exclusion and Node 22 cache concerns before merging to ensure we're not introducing subtle issues.

Overall: Strong improvements to CI/CD infrastructure and code formatting. Minor concerns should be addressed for completeness.


Review generated by Claude Code

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
rakelib/shakapacker_examples.rake (1)

39-43: Improve the TODO comment with tracking information.

The TODO lacks specific tracking details that would help ensure it's addressed. Consider adding:

  • An issue/ticket number for tracking
  • The specific version or release when this can be removed
  • A brief explanation of WHY validation needs to be skipped

Apply this diff to enhance the TODO:

-      # TODO: Remove REACT_ON_RAILS_SKIP_VALIDATION after generators start using next release
+      # TODO(#ISSUE_NUMBER): Remove REACT_ON_RAILS_SKIP_VALIDATION after generators start using vX.Y.Z
+      # Skipping validation temporarily because [brief reason - e.g., "generators in current release don't support the new validation checks"]
       generator_commands = example_type.generator_shell_commands.map do |cmd|
         "REACT_ON_RAILS_SKIP_VALIDATION=true #{cmd}"
       end
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ad8d84 and 1155e30.

📒 Files selected for processing (2)
  • .github/workflows/gem-tests.yml (5 hunks)
  • rakelib/shakapacker_examples.rake (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/gem-tests.yml
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • rakelib/shakapacker_examples.rake
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: spec-dummy-integration-tests (latest)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: build-examples-and-test-generators (latest)
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: basic-gem-tests (latest)

@claude
Copy link

claude bot commented Nov 17, 2025

Code Review for PR #2034: Fix Pro Rubocop Linting

I've reviewed the changes in this PR. Overall, this is a well-structured refactoring that improves CI configuration and addresses linting issues. Here's my detailed feedback:


Strengths

1. CI/CD Improvements

  • Excellent refactoring of the matrix strategy across all workflows. The new approach using matrix_array output and dynamic translation is much cleaner than the previous include/exclude pattern.
  • Consistency: All workflows now follow the same pattern for determining which dependency levels to test, reducing maintenance burden.
  • Better naming: Job names like build-examples-and-test-generators, spec-dummy-integration-tests, and package-js-tests are more descriptive than generic names.
  • Proper fail-fast configuration: Setting fail-fast: false allows all matrix jobs to complete, providing more complete feedback.

2. Ruby Code Quality

  • Proper RuboCop compliance: All Pro package Ruby files have been properly formatted with correct indentation and line length.
  • Test improvements: Test specs like license_validator_spec.rb show good coverage of edge cases.

3. Documentation

  • The build_test_command uncomment in the generator template is a good improvement.

🔍 Potential Issues & Concerns

1. Node 22 Cache Re-enabled

The original code disabled caching for Node 22 due to a documented V8 bug. The PR removes this workaround entirely. Please verify the bug status and add a comment explaining why it's safe to remove this check.

2. REACT_ON_RAILS_SKIP_VALIDATION Flag

This adds a validation skip flag to all generator commands, which could mask real issues during testing. The TODO suggests this is temporary, but there's no tracking issue. Consider adding a GitHub issue number for tracking.

3. Public Key Formatting Changes

The indentation appears inconsistent in the PEM key. Verify that the key still works correctly after RuboCop's formatting changes.

4. build_test_command Uncommented

The generator now uncomments build_test_command by default. This could cause test failures for users who haven't configured the test helper. Ensure the upgrade guide documents this change.


🔒 Security

No security concerns identified. The license validation logic appears sound with proper JWT signature verification, expiration checking, and grace period handling.


🚀 Performance

The CI changes should actually improve performance through better matrix determination and parallel execution.


📝 Recommendations

Before merging:

  1. Verify all CI checks pass
  2. Verify Node 22 caching issue is resolved
  3. Create tracking issue for REACT_ON_RAILS_SKIP_VALIDATION removal
  4. Test that the public key still works after indentation changes
  5. Document the build_test_command change in CHANGELOG if user-facing

Future improvements:

  1. Refactor high-complexity methods in request.rb
  2. Consider extracting matrix translation to a reusable GitHub Action

🎯 Overall Assessment

Rating: ✅ Approve with minor concerns

This PR makes valuable improvements to CI infrastructure and fixes legitimate linting issues. The code quality is good, test coverage appears adequate, and the changes align with the project's guidelines in CLAUDE.md.

Great work on improving the CI infrastructure! 🚀

@claude
Copy link

claude bot commented Nov 17, 2025

Code Review: Fix Pro Rubocop Linting

I've reviewed this PR and overall it looks good! The changes successfully address RuboCop linting issues in the Pro package and improve the CI workflow matrix strategy. Here's my detailed feedback:


✅ Strengths

1. CI Workflow Matrix Improvements

  • The new matrix strategy using fromJson() and dynamic outputs is much cleaner than the previous include/exclude pattern
  • Centralizing the matrix determination logic in determine-matrix step reduces duplication across workflows
  • The translation step that maps latest/minimum to actual Ruby/Node versions is a smart abstraction
  • Job naming improvements make CI runs easier to understand

2. Pro Package RuboCop Fixes

  • All fixes appear to be standard style improvements
  • No functional changes detected - purely cosmetic/linting improvements
  • The --ignore-parent-exclusion flag correctly handles the Pro package's separate linting configuration

3. Generator Template Change

  • Re-enabling build_test_command is good - the comment explains this is now supported since generators configure TestHelper

🔍 Observations & Minor Concerns

1. Rake Task Generator Command Workaround
The TODO comment in rakelib/shakapacker_examples.rake says Remove REACT_ON_RAILS_SKIP_VALIDATION after generators start using next release

  • Question: Is there a GitHub issue tracking this? Should we create one to ensure this workaround is removed?
  • This is a temporary fix, which is fine, but we should ensure it doesn't become permanent

2. Node 22 Cache Re-enabled
The old code disabled cache for Node 22 due to V8 bug in 22.21.0, but cache is now unconditionally enabled

  • Question: Has this V8 bug been resolved? The comment is still present but cache is now unconditionally enabled
  • If the bug is fixed, the comment should be updated or removed

3. Method Complexity Annotations
Several methods were annotated with rubocop:disable Metrics/MethodLength, Metrics/AbcSize

  • While disabling cops is acceptable for complex methods, consider whether these could be refactored in a future PR
  • The create_connection method in particular has significant logic that might benefit from extraction

4. License Public Key Formatting

  • The indentation change appears to be a RuboCop auto-fix
  • The key itself is unchanged, which is critical for security
  • Good: No functional change to the cryptographic key

🧪 Test Coverage

This PR doesn't add or modify any tests, which is appropriate since:

  • CI workflow changes are tested by running CI itself
  • RuboCop fixes are style-only with no functional changes
  • The generator template change is covered by existing generator tests

However: For the REACT_ON_RAILS_SKIP_VALIDATION workaround, ensure that when it's removed, the generators still work correctly.


🔒 Security Considerations

License Public Key:

  • ✅ The actual key content is unchanged (only formatting)
  • ✅ The TODO comment about adding a prepublish check is still present - this should be implemented
  • Recommendation: Create a GitHub issue for the prepublish check if one doesn't exist

📊 Performance Considerations

CI Performance:

  • Setting fail-fast: false means failures won't cancel other jobs
  • This increases CI resource usage but provides better visibility
  • Good trade-off for debugging matrix builds

Node 22 Cache:

  • If the V8 bug is truly fixed, re-enabling cache will improve CI performance significantly
  • If not fixed, builds may fail intermittently

📝 Recommendations

  1. High Priority: Verify the Node 22 V8 bug status and update/remove the comment accordingly
  2. Medium Priority: Create/link GitHub issue for removing REACT_ON_RAILS_SKIP_VALIDATION workaround
  3. Medium Priority: Create/link GitHub issue for implementing the public key prepublish check
  4. Low Priority: Consider future refactoring of complex methods that required cop disabling
  5. Low Priority: Verify that all artifact names using translated matrix outputs work correctly in CI

✅ Approval Status

This PR is ready to merge once the following is confirmed:

  • CI passes with the new matrix strategy
  • Node 22 cache issue is verified as resolved (or comment updated if still present)
  • Confirmation that REACT_ON_RAILS_SKIP_VALIDATION workaround is tracked for removal

The RuboCop fixes are all standard style improvements with no functional changes. The CI workflow improvements are a significant enhancement to maintainability.

Great work on cleaning up the linting and improving the CI infrastructure! 🎉


Note: Review conducted following repository's CLAUDE.md guidelines for code quality, best practices, and conventions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 961d778 and 209d3e2.

📒 Files selected for processing (1)
  • rakelib/shakapacker_examples.rake (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • rakelib/shakapacker_examples.rake
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: spec-dummy-integration-tests (latest)
  • GitHub Check: build-examples-and-test-generators (latest)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: basic-gem-tests (latest)
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: claude-review
🔇 Additional comments (2)
rakelib/shakapacker_examples.rake (2)

45-45: Consider whether pack generation should also skip validation.

The new explicit pack generation step is a good addition to ensure packs are created consistently. However, note that this step doesn't include REACT_ON_RAILS_SKIP_VALIDATION=true like the generator commands above.

Is this intentional? Should pack generation use the same validation-skipping as the generators, or is it safe for pack generation to run with validation enabled?


39-42: The review comment is based on incomplete understanding of the codebase.

The REACT_ON_RAILS_SKIP_VALIDATION pattern is not an undocumented or risky workaround—it's a well-documented, necessary practice already established in the gem's official generators and templates.

From the codebase evidence:

  1. Documented necessity: lib/generators/react_on_rails/install_generator.rb lines 53–55 explicitly document why validation must be skipped: "The npm package isn't installed until midway through the generator, so validation would fail."

  2. Already in use: This pattern is employed in:

    • lib/generators/react_on_rails/install_generator.rb (line 62—the gem's own generator sets this ENV)
    • lib/generators/react_on_rails/templates/base/base/bin/shakapacker-precompile-hook (line 19—official template)
    • lib/react_on_rails/engine.rb (lines 49–51—managed with debug logging)
  3. Not masking bugs: Skipping validation here prevents false validation failures due to missing npm packages, not bugs in generators.

  4. Array handling is valid: sh_in_dir correctly accepts and flattens array parameters (task_helpers.rb line 23).

The TODO comment suggests this may become unnecessary in a future release when generators handle it internally—a reasonable temporal marker, not a sign of risk.

Likely an incorrect or invalid review comment.

Comment on lines +40 to +43
generator_commands = example_type.generator_shell_commands.map do |cmd|
"REACT_ON_RAILS_SKIP_VALIDATION=true #{cmd}"
end
sh_in_dir(example_type.dir, generator_commands)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify that sh_in_dir supports array arguments.

The code passes generator_commands (an array) to sh_in_dir, but all other invocations in this file pass single string commands (lines 32, 34-36, 38, 44).

Run the following script to check the sh_in_dir implementation and verify it can handle array arguments:

If sh_in_dir doesn't support arrays, the commands may need to be executed individually:

generator_commands.each do |cmd|
  sh_in_dir(example_type.dir, cmd)
end

🏁 Script executed:

#!/bin/bash
# Description: Check sh_in_dir implementation to verify array support

# Find and display the sh_in_dir method definition
ast-grep --pattern $'def sh_in_dir($$$)
  $$$
end'

Length of output: 1099


Use the splat operator to pass array elements as individual arguments.

While sh_in_dir technically supports array parameters due to its flatten call, the reviewed code at line 43 passes an array as a single argument—inconsistent with all other invocations in the file which pass individual strings (lines 32, 34–36, 38, 44).

Change:

sh_in_dir(example_type.dir, generator_commands)

To:

sh_in_dir(example_type.dir, *generator_commands)

This follows the established pattern and makes the intent explicit.

🤖 Prompt for AI Agents
In rakelib/shakapacker_examples.rake around lines 40 to 43, the call
sh_in_dir(example_type.dir, generator_commands) passes the command array as a
single argument instead of individual arguments; change the call to pass each
command as its own argument using the splat operator (i.e., pass
*generator_commands) so it matches other invocations and clearly expresses the
intent.

@justin808 justin808 changed the title Fix Pro Rubocop Linting WIP - Fix Pro Rubocop and other CI - will split up Nov 17, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
lib/generators/react_on_rails/dev_tests_generator.rb (1)

53-53: Good fix: Using yarn to run yalc ensures local binary resolution.

Verification complete:

  1. yalc is confirmed as a devDependency in react_on_rails_pro/package.json (version: ^1.0.0-pre.53)
  2. ✅ Multiple other yalc usages exist across the codebase, but they use bare yalc commands without the yarn prefix

The change on line 53 is correct and follows best practices. However, for consistency and reliability, consider updating other yalc usages to also use the yarn prefix:

  • react_on_rails_pro/package.json:107 - "yalc publish"
  • spec/dummy/package.json:70–71 - "yalc add", "yalc publish"
  • react_on_rails_pro/spec/dummy/package.json:101–102 - "yalc add", "yalc publish"
  • react_on_rails_pro/spec/execjs-compatible-dummy/package.json:42–43 - "yalc add", "yalc publish"
  • packages/react-on-rails/package.json:16–17 and packages/react-on-rails-pro/package.json:17–18 - npm script definitions
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 209d3e2 and 25c43da.

📒 Files selected for processing (1)
  • lib/generators/react_on_rails/dev_tests_generator.rb (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • lib/generators/react_on_rails/dev_tests_generator.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/generators/react_on_rails/dev_tests_generator.rb
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • lib/generators/react_on_rails/dev_tests_generator.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: spec-dummy-integration-tests (latest)
  • GitHub Check: basic-gem-tests (latest)
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles

@claude
Copy link

claude bot commented Nov 17, 2025

Code Review - PR #2034

Thank you for working on this PR! I've reviewed the changes and have the following feedback:

🎯 Overview

This PR addresses RuboCop linting issues in the Pro package and refactors the CI workflow configuration to use a more maintainable matrix strategy. The title indicates this is a WIP that will be split up.


Positive Changes

1. CI Workflow Improvements

  • DRY matrix configuration: The new approach using matrix_array and a translation step is much cleaner than the previous include/exclude pattern
  • Centralized version mapping: The translation step that maps dependency-level to actual Ruby/Node versions reduces duplication
  • Better job naming: Renamed jobs like build-examples-and-test-generators, basic-gem-tests, etc. are more descriptive
  • Added fail-fast: false: Good for seeing all test failures at once instead of stopping at the first failure

2. Pro Package RuboCop Fixes

  • Fixed alignment issues in license_public_key.rb (lines 18-28)
  • Improved code formatting in request.rb
  • Updated test files with proper formatting

3. Generator Improvements

  • Enabled build_test_command by default in the generator template (line 29 of react_on_rails.rb.tt)
  • Added bin/rake react_on_rails:generate_packs to example generation workflow

🔍 Issues & Concerns

Critical Issues

  1. Temporary Skip Validation Flag (rakelib/shakapacker_examples.rake:40-42)

    # TODO: Remove REACT_ON_RAILS_SKIP_VALIDATION after generators start using next release
    generator_commands = example_type.generator_shell_commands.map do |cmd|
      "REACT_ON_RAILS_SKIP_VALIDATION=true \#{cmd}"
    end
    • ⚠️ This is a workaround that bypasses validation during generator testing
    • The TODO indicates this should be removed after the next release
    • Recommendation: Track this technical debt - consider adding a task/issue to ensure it gets removed
  2. Pro Lint Workflow Change (.github/workflows/pro-lint.yml:151)

    - bundle exec rubocop --ignore-parent-exclusion
    • The --ignore-parent-exclusion flag was added, which means the Pro package is now ignoring some exclusions from the parent config
    • Question: Is this intentional? This could mask issues that should be fixed instead
    • Recommendation: Document why this flag is necessary, or better yet, fix the root cause

Medium Priority Issues

  1. Removed Node 22 Cache Workaround

    • In integration-tests.yml, removed conditional cache logic for Node 22
    • The comment mentions a V8 bug in Node 22.21.0: sqlite: deps include sqlite3ext.h nodejs/node#56010
    • Question: Has this bug been resolved, or should this workaround remain?
    • Recommendation: Verify the bug status before removing this safeguard
  2. Inconsistent Formatting in license_public_key.rb

    • Line 18: KEY = OpenSSL::PKey::RSA.new(<<~PEM.strip.strip_heredoc)
    • The double .strip.strip_heredoc looks redundant (strip_heredoc already handles leading/trailing whitespace)
    • Recommendation: Remove the extra .strip call
  3. Comment Formatting in request.rb

    • Line 89: # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
    • Missing space after comma (should be , )
    • RuboCop typically formats these as Metrics/AbcSize, Metrics/CyclomaticComplexity

Minor Issues

  1. Test File Formatting

    • license_validator_spec.rb has some minor alignment improvements
    • stream_decorator_spec.rb has consistent formatting
    • These look good overall
  2. Yalc Command Change (examples.yml:133)

    • Changed from yalc publish to yarn yalc publish
    • This is more consistent with using yarn throughout, though functionally equivalent

🧪 Test Coverage

Strengths:

  • No changes to actual test logic, only formatting
  • Test coverage appears comprehensive for license validation
  • Good edge case coverage (expired licenses, grace periods, missing fields, etc.)

Concerns:

  • Since this fixes RuboCop issues, ensure all Pro tests are passing
  • The REACT_ON_RAILS_SKIP_VALIDATION flag means generators aren't fully validated during CI

🔒 Security Considerations

  • No security concerns identified
  • License validation logic remains unchanged
  • Public key update mechanism is properly documented

Performance Considerations

  • CI improvements should result in clearer failure reporting
  • fail-fast: false may increase CI time slightly but provides better visibility
  • No runtime performance impacts

📋 Recommendations

Before Merging:

  1. ✅ Run bundle exec rubocop in react_on_rails_pro/ to verify all issues are fixed
  2. ⚠️ Reconsider the --ignore-parent-exclusion flag - document or fix the root cause
  3. ⚠️ Verify the Node 22 cache workaround can safely be removed
  4. 🔧 Clean up the double .strip.strip_heredoc in license_public_key.rb
  5. 📝 Create a follow-up issue to remove REACT_ON_RAILS_SKIP_VALIDATION

After Merging:

  1. Split this PR as indicated in the title (separate CI changes from RuboCop fixes)
  2. Update CHANGELOG.md if any user-visible behavior changes (the build_test_command enablement might qualify)

📚 CLAUDE.md Compliance

Based on the project's CLAUDE.md guidelines:

Followed:

  • RuboCop fixes address mandatory linting requirements
  • Test file changes maintain proper formatting
  • CI improvements align with project testing practices

⚠️ Needs Attention:

  • Ensure bundle exec rubocop passes with zero offenses before commit
  • Verify all files end with newlines
  • The REACT_ON_RAILS_SKIP_VALIDATION workaround seems contrary to the strict CI requirements

🎬 Conclusion

This is a solid refactoring of the CI matrix logic and fixes important RuboCop issues in the Pro package. The main concerns are:

  1. The --ignore-parent-exclusion flag needs justification
  2. The validation skip workaround should be tracked and removed
  3. Minor cleanup items (double strip, Node 22 cache)

Overall, this improves the codebase, but I recommend addressing the critical issues before merging, especially since this will be split into multiple PRs.

Rating: 7/10 - Good improvements with some concerns that should be addressed.


Review generated by Claude Code - let me know if you need clarification on any points!

@claude
Copy link

claude bot commented Nov 17, 2025

Code Review - PR #2034

Thank you for working on this PR! Here's my review of the changes:


🎯 Overview

This PR makes two main types of changes:

  1. CI/CD workflow refactoring - Improves the build matrix strategy across all workflows
  2. RuboCop fixes for Pro package - Addresses linting violations in the Pro codebase

✅ Positive Aspects

1. CI Matrix Strategy Improvements

The refactoring from include/exclude to fromJson with dynamic matrix is a significant improvement:

  • Better readability: The logic is centralized in determine-matrix step
  • More maintainable: Single source of truth for matrix decisions
  • Clearer intent: Easier to understand when minimum vs latest runs

2. Job Naming Consistency

Renaming jobs to be more descriptive is excellent:

  • examples → build-examples-and-test-generators
  • rspec-package-tests → basic-gem-tests
  • dummy-app-integration-tests → spec-dummy-integration-tests
  • Adding pro- prefix to Pro workflow jobs

This makes CI logs much easier to navigate.

3. RuboCop Compliance

The Pro package now passes RuboCop with --ignore-parent-exclusion flag, which is the correct approach for the monorepo structure mentioned in CLAUDE.md.


⚠️ Issues and Concerns

1. CRITICAL: Generator Template Changes (react_on_rails.rb.tt)

The following lines were uncommented in lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt:

  • config.build_test_command = "RAILS_ENV=test bin/shakapacker"
  • config.auto_load_bundle = true
  • config.components_subdirectory = "ror_components"

Problems:

  • These lines should remain commented by default per the template's own documentation
  • The comments explicitly state build_test_command is an "ALTERNATIVE APPROACH" that requires additional setup
  • Users who generate new apps will get unexpected behavior without configuring ReactOnRails::TestHelper
  • The auto_load_bundle and components_subdirectory settings are advanced configuration that shouldn't be in the default template uncommented

Impact: This will affect all new React on Rails installations going forward.

Recommendation: Keep these commented in the template as they were before.

2. MEDIUM: Inconsistent Matrix Logic

In package-js-tests.yml, the matrix uses Node versions directly (22, 20) instead of dependency levels (latest, minimum) like other workflows.

Why this matters: Other workflows use dependency-level which is then translated to specific versions. This creates inconsistency.

Recommendation: Consider using the same pattern (dependency-level → version translation) for consistency across all workflows.

3. MINOR: Removed Node 22 Cache Workaround

The original code had a workaround for a V8 bug in Node 22.21.0 (nodejs/node#56010). The cache was conditionally disabled for Node 22.

Question: Has this bug been resolved? If not, removing this could cause cache issues.

4. MINOR: Validation Skip in Examples

The TODO comment mentions removing REACT_ON_RAILS_SKIP_VALIDATION after generators start using next release. This is a temporary workaround that's fine, but make sure there's a plan to remove it.


🔍 Code Quality Observations

RuboCop Fixes in Pro Package

The changes to request.rb, license_public_key.rb, and test files look good:

  • Proper string formatting (using strip_heredoc)
  • Appropriate use of receive_messages in specs
  • Good code organization

Workflow Improvements

  • The translate-matrix step is a clean solution
  • Proper use of fail-fast: false added where needed
  • Cache keys updated to use translated versions correctly

🧪 Testing Considerations

Missing validation:

  • No test coverage for the generator template changes
  • Consider testing that generated apps work with default settings

Recommended pre-merge testing:

  1. Generate a new app with the modified template and verify tests work
  2. Run CI on all matrix combinations (latest + minimum)
  3. Verify the REACT_ON_RAILS_SKIP_VALIDATION workaround in examples

🎯 Recommendations

Before merging:

  1. MUST FIX: Revert the uncommented config lines in react_on_rails.rb.tt template
  2. SHOULD FIX: Document or verify the Node 22 cache issue is resolved
  3. CONSIDER: Make matrix strategy consistent across all workflows

After merging:

  1. Remove REACT_ON_RAILS_SKIP_VALIDATION workaround in next release
  2. Consider documenting the new CI matrix strategy in developer docs

📋 Checklist Reminder (from CLAUDE.md)

Per the project's CLAUDE.md requirements:

  • ✅ RuboCop passes (with --ignore-parent-exclusion for Pro)
  • ❓ Files end with newlines (please verify)
  • ✅ Proper formatting applied
  • ❓ CI tested locally before push

📝 Summary

Overall: This is a valuable improvement to the CI infrastructure. The matrix refactoring is well-thought-out and the RuboCop fixes are appropriate.

Critical issue: The generator template changes need to be reverted to keep the default configuration commented.

Suggested next steps:

  1. Fix the template file to keep advanced config commented
  2. Verify Node 22 cache workaround removal is safe
  3. Test end-to-end with both matrix configurations
  4. Split this PR as mentioned in the title if it helps with review

Happy to answer any questions about this review!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
rakelib/shakapacker_examples.rake (1)

39-43: Use the splat operator for consistency with other sh_in_dir calls.

Line 43 passes generator_commands as a single array argument, while all other sh_in_dir invocations in this file (lines 32, 34-36, 38, 44) pass individual string arguments.

Apply this diff to use the splat operator:

-      sh_in_dir(example_type.dir, generator_commands)
+      sh_in_dir(example_type.dir, *generator_commands)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb3f4be and bcf3156.

📒 Files selected for processing (2)
  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt (1 hunks)
  • rakelib/shakapacker_examples.rake (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • rakelib/shakapacker_examples.rake
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
  • rakelib/shakapacker_examples.rake
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: spec-dummy-integration-tests (latest)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: basic-gem-tests (latest)
  • GitHub Check: build-examples-and-test-generators (latest)
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: pro-build-dummy-app-webpack-test-bundles
  • GitHub Check: claude-review
🔇 Additional comments (2)
lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt (1)

31-32: Add clarifying comments to explain why these advanced options are enabled by default in the generator template, or reconsider enabling them.

The current template sets auto_load_bundle = true and components_subdirectory = "ror_components" on lines 31-32, immediately followed by an "Advanced Configuration" section stating these are optional advanced options. This creates confusion since:

  1. The documented runtime default for auto_load_bundle is false
  2. Generator philosophy is that "defaults for options are such that the default is for the flag to be off"
  3. Yet new projects inherit these explicitly enabled

Either add a comment explaining why these are enabled by default for new projects (since they're recommended for modern setups), or move these to the optional section below with instructions for users to opt-in if desired.

rakelib/shakapacker_examples.rake (1)

45-45: ****

The react_on_rails:generate_packs task exists and is correctly invoked. The task is defined in lib/tasks/generate_packs.rake, auto-discovers React components in the configured subdirectory, cleans out existing generated directories, and generates new pack files for discovered components. The workflow in shakapacker_examples.rake is correct: generators run with validation skipped (as noted in the TODO), npm install provisions dependencies, and then pack generation runs after to generate bundles based on the installed packages. When the TODO on line 39 is addressed, this step will be revisited as part of that work.

# - See: https://github.com/shakacode/react_on_rails/blob/master/docs/guides/testing-configuration.md
#
# config.build_test_command = "RAILS_ENV=test bin/shakapacker"
config.build_test_command = "RAILS_ENV=test bin/shakapacker"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Uncommenting this line contradicts the documented guidance.

The comments above (lines 18-28) explicitly state there are "Two mutually exclusive approaches - use ONLY ONE" and that the RECOMMENDED APPROACH is to set compile: true in config/shakapacker.yml. By uncommenting this line in the generator template, you're forcing the ALTERNATIVE APPROACH on all generated projects, preventing users from easily following the recommended approach without manually modifying this file.

Consider one of the following solutions:

  1. Keep this line commented out and let users uncomment it if they choose the alternative approach
  2. Add a generator option/prompt to let users choose which approach they prefer
  3. Document why the alternative approach is now the default (if that's the intent)

Apply this diff to keep the line commented:

-  config.build_test_command = "RAILS_ENV=test bin/shakapacker"
+  # config.build_test_command = "RAILS_ENV=test bin/shakapacker"
📝 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.

Suggested change
config.build_test_command = "RAILS_ENV=test bin/shakapacker"
# config.build_test_command = "RAILS_ENV=test bin/shakapacker"
🤖 Prompt for AI Agents
In
lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb.tt
around line 29, the template currently uncomments the build_test_command which
contradicts the file's comments that recommend the compile:true approach; revert
this change so the build_test_command remains commented out in the template (or
alternatively implement a generator option/prompt to let the user choose the
alternative approach and generate the line uncommented only when explicitly
selected, or add a clear comment explaining why the alternative is now the
default if that is the intended behavior).

@justin808 justin808 closed this Nov 17, 2025
@justin808 justin808 deleted the judahmeek/pro-rubocop branch November 17, 2025 03:55
justin808 added a commit that referenced this pull request Nov 17, 2025
…2036)

## Summary

Fixes the GitHub Actions error where matrix exclude keys didn't match
any keys within the matrix for the
`build-dummy-app-webpack-test-bundles` job.

## Changes

- Added missing `exclude` section to
`build-dummy-app-webpack-test-bundles` job in
`.github/workflows/integration-tests.yml`
- The exclude section matches the structure used in
`dummy-app-integration-tests` job
- This ensures the minimum dependency matrix (Ruby 3.2, Node 20) only
runs on master, workflow_dispatch, force_run, or when full-ci label is
present

## Test Plan

- ✅ Verified workflow syntax with actionlint
- ✅ Checked that the exclude section matches the pattern used in
dummy-app-integration-tests job
- CI will validate the matrix configuration works correctly

## Related

- Follows the pattern established in PR #2034

## Summary by CodeRabbit

* **Chores**
* Refined GitHub Actions workflow configuration to optimize test matrix
execution conditions across integration and webpack test bundles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants