Skip to content

Conversation

justin808
Copy link
Member

@justin808 justin808 commented Sep 28, 2025

Summary

Adds automated release rake tasks to streamline the release process, eliminating the need for manual version bump PRs.

Rake Tasks Added

rake release:prepare[VERSION]

Prepares a new release by:

  • Validating version format (semantic versioning)
  • Updating lib/cypress_on_rails/version.rb
  • Updating CHANGELOG.md with date and compare link
  • Prompting for confirmation

rake release:publish

Publishes the release by:

  • Verifying on master branch with clean working directory
  • Running the test suite
  • Creating and pushing git tag
  • Building the gem
  • Publishing to RubyGems

rake release:full[VERSION]

Combines both prepare and publish for one-command releases.

Documentation

Added RELEASING.md with:

  • Complete step-by-step release process
  • Version numbering guidelines
  • Pre-release checklist
  • Troubleshooting guide
  • Rollback procedures
  • Example release flow

Usage Example

# Prepare release (updates files)
rake release:prepare[1.19.0]

# Review and commit changes
git diff
git add -A
git commit -m "Bump version to 1.19.0"
git push origin master

# Publish to RubyGems
rake release:publish

Benefits

  • No manual PRs needed for version bumps
  • Consistent process every release
  • Prevents errors with validation and checks
  • Clear workflow with guided next steps
  • Automated CHANGELOG updates

Changes From Original PR

This PR now focuses on infrastructure rather than a one-time version bump:

  • Removed manual version changes
  • Added reusable rake tasks
  • Added comprehensive documentation

The actual v1.19.0 release will be performed by running:

rake release:prepare[1.19.0]

After this PR is merged.

Next Steps After Merge

  1. Merge this PR to add the release tooling
  2. Run rake release:prepare[1.19.0] on master
  3. Commit and push the version bump
  4. Run rake release:publish to release v1.19.0

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive release guide covering prerequisites, versioning, checklists, troubleshooting, rollback, and an example release flow.
  • Chores
    • Introduced automation to prepare and publish releases with safety checks and test execution.
    • Improved changelog handling during release.
    • Added a development dependency to support release tooling.

Copy link

coderabbitai bot commented Sep 28, 2025

Walkthrough

Adds release documentation, introduces two rake tasks (release:prepare and release:publish) with a changelog update helper, and includes the gem-release tool as a development dependency.

Changes

Cohort / File(s) Summary
Release Documentation
RELEASING.md
New guide detailing prerequisites, versioning, release steps, validation, troubleshooting, rollback, and example flow.
Release Automation Tasks
Rakefile
Adds namespace with release:prepare(version) and release:publish tasks; includes update_changelog helper to transform [Unreleased] into a dated version entry; integrates tests, branch/clean checks, and gem-release commands.
Development Dependency
cypress-on-rails.gemspec
Adds development dependency on gem-release; no runtime dependency changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant Rake as Rake Tasks
  participant V as Version/Changelog
  participant GR as gem-release
  participant GH as Git (Tags/GitHub)
  participant RG as RubyGems

  rect rgb(235, 245, 255)
  note over Dev,Rake: Prepare
  Dev->>Rake: rake release:prepare[1.2.3]
  Rake->>V: Read current version
  Rake->>V: Update CHANGELOG [Unreleased] -> 1.2.3 (dated)
  Rake-->>Dev: Output next steps (diff/commit/push)
  end

  rect rgb(240, 255, 240)
  note over Dev,Rake: Publish
  Dev->>Rake: rake release:publish
  Rake->>Rake: Ensure on master & clean
  Rake->>Rake: Run test suite
  alt tests pass
    Rake->>GR: gem release --tag --push
    GR->>GH: Create tag / push commits
    GR->>RG: Build & push gem
    Rake-->>Dev: Link for GitHub release & comms
  else tests fail
    Rake-->>Dev: Abort with failure
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

I twitch my whiskers at version three,
Two tasks hop forward, neat as can be.
Changelog blooms where notes once slept,
Tags and gems are softly kept.
With gem-release I bound and cheer—
Ship it clean, then disappear! 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Add automated release rake tasks” succinctly and accurately captures the primary change introduced by this pull request, which is the addition of reusable rake tasks for automating the release process. It is clear, concise, and directly reflects the main functionality being added without extraneous detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prepare-v1.19.0-release

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 RuboCop (1.80.2)
Rakefile

Could not find gem 'rspec' in locally installed gems.
/usr/lib/ruby/3.1.0/bundler/resolver.rb:269:in block in verify_gemfile_dependencies_are_found!' /usr/lib/ruby/3.1.0/bundler/resolver.rb:252:in map!'
/usr/lib/ruby/3.1.0/bundler/resolver.rb:252:in verify_gemfile_dependencies_are_found!' /usr/lib/ruby/3.1.0/bundler/resolver.rb:48:in start'
/usr/lib/ruby/3.1.0/bundler/resolver.rb:23:in resolve' /usr/lib/ruby/3.1.0/bundler/definition.rb:269:in resolve'
/usr/lib/ruby/3.1.0/bundler/definition.rb:468:in materialize' /usr/lib/ruby/3.1.0/bundler/definition.rb:190:in specs'
/usr/lib/ruby/3.1.0/bundler/runtime.rb:85:in block in definition_method' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:296:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:167:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:49:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:87:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:45:in run' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/exe/rubocop:15:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

cypress-on-rails.gemspec

Could not find gem 'rspec' in locally installed gems.
/usr/lib/ruby/3.1.0/bundler/resolver.rb:269:in block in verify_gemfile_dependencies_are_found!' /usr/lib/ruby/3.1.0/bundler/resolver.rb:252:in map!'
/usr/lib/ruby/3.1.0/bundler/resolver.rb:252:in verify_gemfile_dependencies_are_found!' /usr/lib/ruby/3.1.0/bundler/resolver.rb:48:in start'
/usr/lib/ruby/3.1.0/bundler/resolver.rb:23:in resolve' /usr/lib/ruby/3.1.0/bundler/definition.rb:269:in resolve'
/usr/lib/ruby/3.1.0/bundler/definition.rb:468:in materialize' /usr/lib/ruby/3.1.0/bundler/definition.rb:190:in specs'
/usr/lib/ruby/3.1.0/bundler/runtime.rb:85:in block in definition_method' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:296:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:167:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:49:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:87:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.80.2/lib/rubocop/cli.rb:45:in run' /var/lib/gems/3.1.0/gems/rubocop-1.80.2/exe/rubocop:15:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'


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.

Copy link

claude bot commented Sep 28, 2025

Code Review for PR #182: Prepare for v1.19.0 release

Thank you for this comprehensive release preparation! I've reviewed the changes and here's my feedback:

Strengths

  1. Excellent Documentation: The addition of 2000+ lines of documentation (TROUBLESHOOTING.md, PLAYWRIGHT_GUIDE.md, VCR_GUIDE.md, etc.) directly addresses user pain points from multiple issues. This is a fantastic improvement for developer experience.

  2. Feature Completeness: The new rake tasks (cypress:open, cypress:run, playwright:open, playwright:run) with automatic server management significantly improves the testing workflow and achieves cypress-rails parity.

  3. Well-Structured Release Process: The RELEASE_CHECKLIST.md and RELEASE_NOTES_1.19.0.md demonstrate professional release management.

🔍 Code Quality Observations

1. Error Handling in Server Management (lib/cypress_on_rails/server.rb)

The new Server class should have more robust error handling:

  • Consider adding timeout handling for server startup
  • Add cleanup in case of unexpected failures
  • Consider what happens if the port is already in use

2. Configuration Validation (lib/cypress_on_rails/configuration.rb)

The new configuration options should validate input:

  • Port numbers should be validated (1-65535)
  • Callbacks should verify they're callable
  • Consider adding type checking for configuration values

3. State Reset Middleware (lib/cypress_on_rails/state_reset_middleware.rb)

Security consideration: Ensure this endpoint is properly protected and only accessible in test environment.

🐛 Potential Issues

  1. Race Conditions: In the server lifecycle hooks, there might be race conditions between after_server_start and when the server is actually ready to accept connections. Consider adding a health check mechanism.

  2. Transaction Handling: The transactional_server mode needs careful consideration for tests that spawn background jobs or use multiple database connections.

  3. Memory Leaks: With the new state reset mechanism, ensure that all caches and in-memory data structures are properly cleared to avoid memory growth during long test runs.

🚀 Performance Considerations

  1. Port Selection: The dynamic port selection in Server class could benefit from a more robust algorithm to avoid conflicts in CI environments with parallel jobs.

  2. Documentation Loading: With the extensive new documentation, consider if these should be excluded from the gem build to reduce package size.

🔒 Security Concerns

  1. Test Endpoint Exposure: The /cypress_rails_reset_state endpoint must be absolutely certain it's disabled in production. Consider adding multiple safeguards.

  2. Callback Execution: The configuration callbacks (before_server_start, etc.) execute arbitrary code. Consider documenting security implications.

📋 Test Coverage

The PR would benefit from:

  • Unit tests for the new Server class
  • Integration tests for the rake tasks
  • Tests for the state reset middleware
  • Tests for configuration validation

💡 Suggestions

  1. Add deprecation warnings for any older patterns that users should migrate away from.

  2. Consider adding a --dry-run option to the rake tasks for debugging server startup issues.

  3. Add logging configuration to help users debug issues with the automatic server management.

  4. Version compatibility matrix in the README showing which Rails versions are tested.

Minor Improvements

  1. In CHANGELOG.md, the comparison link format [Compare]: should be [1.19.0]: for consistency.

  2. Consider adding a timeout to the server startup wait loop to prevent infinite waiting.

  3. The RELEASE_CHECKLIST.md could benefit from automated checks via a GitHub Action.


Overall Assessment: This is a solid release that significantly improves the developer experience. The cypress-rails compatibility and comprehensive documentation address real user needs. The main areas for improvement are around error handling, validation, and test coverage for the new features.

Great work on making the gem more accessible and user-friendly! 🎉

Copy link

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/TROUBLESHOOTING.md (1)

386-409: Correct the Cypress helper name for VCR cassette recording

The surrounding snippets define the helper as Cypress.Commands.add('vcrInsert', ...), so the usage here should be cy.vcrInsert(...)/cy.vcrEject(...). Calling cy.vcr_insert_cassette will throw “is not a function” at runtime, so the troubleshooting guidance currently sends users down a broken path. Please fix this section (and the similar examples lower in the file) to match the actual command names.

-```js
-cy.vcr_insert_cassette('my_cassette', { record: 'new_episodes' });
-```
+```js
+cy.vcrInsert('my_cassette', { record: 'new_episodes' });
+```
🧹 Nitpick comments (3)
RELEASE_NOTES_1.19.0.md (1)

98-98: Wrap bare URL to keep markdownlint happy

markdownlint flags the bare GitHub URL (MD034). Converting it to a markdown link resolves the lint failure.

-Please report issues at: https://github.com/shakacode/cypress-playwright-on-rails/issues
+Please report issues at: [github.com/shakacode/cypress-playwright-on-rails/issues](https://github.com/shakacode/cypress-playwright-on-rails/issues)

Based on static analysis hints.

RELEASE_CHECKLIST.md (1)

40-40: Format the bare URL to avoid markdownlint errors

Same MD034 warning here—wrapping the release page URL fixes the lint complaint.

-- [ ] Go to https://github.com/shakacode/cypress-playwright-on-rails/releases/new
+- [ ] Go to [github.com/shakacode/cypress-playwright-on-rails/releases/new](https://github.com/shakacode/cypress-playwright-on-rails/releases/new)

Based on static analysis hints.

docs/PLAYWRIGHT_GUIDE.md (1)

48-63: Add a fenced code language specifier.

Line 48 opens a fenced block without a language tag, tripping markdownlint (MD040) and hurting consistency with the rest of the guide. Please annotate it (e.g., ```text) so tooling stays quiet and formatting is predictable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d50de89 and 41be34e.

📒 Files selected for processing (16)
  • CHANGELOG.md (1 hunks)
  • README.md (4 hunks)
  • RELEASE_CHECKLIST.md (1 hunks)
  • RELEASE_NOTES_1.19.0.md (1 hunks)
  • docs/BEST_PRACTICES.md (1 hunks)
  • docs/DX_IMPROVEMENTS.md (1 hunks)
  • docs/PLAYWRIGHT_GUIDE.md (1 hunks)
  • docs/TROUBLESHOOTING.md (1 hunks)
  • docs/VCR_GUIDE.md (1 hunks)
  • lib/cypress_on_rails/configuration.rb (2 hunks)
  • lib/cypress_on_rails/railtie.rb (1 hunks)
  • lib/cypress_on_rails/server.rb (1 hunks)
  • lib/cypress_on_rails/state_reset_middleware.rb (1 hunks)
  • lib/cypress_on_rails/version.rb (1 hunks)
  • lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1 hunks)
  • lib/tasks/cypress.rake (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
lib/cypress_on_rails/server.rb (2)
lib/cypress_on_rails/configuration.rb (2)
  • initialize (36-38)
  • configuration (76-78)
lib/cypress_on_rails/state_reset_middleware.rb (4)
  • initialize (2-44)
  • initialize (3-5)
  • run_hook (41-43)
  • call (7-14)
lib/cypress_on_rails/state_reset_middleware.rb (2)
lib/cypress_on_rails/configuration.rb (1)
  • configuration (76-78)
lib/cypress_on_rails/server.rb (1)
  • run_hook (190-194)
🪛 markdownlint-cli2 (0.18.1)
RELEASE_CHECKLIST.md

40-40: Bare URL used

(MD034, no-bare-urls)

RELEASE_NOTES_1.19.0.md

98-98: Bare URL used

(MD034, no-bare-urls)

docs/BEST_PRACTICES.md

18-18: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/TROUBLESHOOTING.md

18-18: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


18-18: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


20-20: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


20-20: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


83-83: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


83-83: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


83-83: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


103-103: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


103-103: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


103-103: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


129-129: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


129-129: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


131-131: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


131-131: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


131-131: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


142-142: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


142-142: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


142-142: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


168-168: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


168-168: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


170-170: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


170-170: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


256-256: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


256-256: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


256-256: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


266-266: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


266-266: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


266-266: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


275-275: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


275-275: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


275-275: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


292-292: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


292-292: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


294-294: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


294-294: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)

docs/PLAYWRIGHT_GUIDE.md

48-48: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

CHANGELOG.md

13-13: Link and image reference definitions should be needed
Unused link or image reference definition: "compare"

(MD053, link-image-reference-definitions)

docs/DX_IMPROVEMENTS.md

79-79: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

docs/VCR_GUIDE.md

197-197: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


371-371: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


371-371: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


384-384: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


384-384: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


386-386: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


386-386: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


413-413: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


413-413: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


428-428: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


428-428: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


430-430: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


430-430: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


453-453: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


453-453: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


463-463: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


463-463: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


477-477: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


477-477: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


478-478: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


478-478: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


479-479: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


479-479: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


480-480: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


480-480: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


481-481: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


481-481: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


482-482: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


482-482: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


486-486: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


486-486: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


487-487: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


487-487: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


492-492: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


492-492: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


493-493: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)


493-493: Strong style
Expected: underscore; Actual: asterisk

(MD050, strong-style)

🪛 Brakeman (7.0.2)
lib/cypress_on_rails/server.rb

[medium] 187-187: Possible command injection
Type: Command Injection
Confidence: Medium
More info: https://brakemanscanner.org/docs/warning_types/command_injection/

(Command Injection)


[medium] 107-107: Possible command injection
Type: Command Injection
Confidence: Medium
More info: https://brakemanscanner.org/docs/warning_types/command_injection/

(Command Injection)

lib/cypress_on_rails/state_reset_middleware.rb

[medium] 30-30: Possible SQL injection
Type: SQL Injection
Confidence: Medium
More info: https://brakemanscanner.org/docs/warning_types/sql_injection/

(SQL Injection)

⏰ 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: rails_8
  • GitHub Check: rails_6_1
  • GitHub Check: rails_7_2
  • GitHub Check: claude-review
🔇 Additional comments (1)
CHANGELOG.md (1)

12-13: Verify the release date before tagging

The entry is dated 2025-09-27, but we’re preparing the release on 2025-09-28. Please double-check the actual tag date before merge so the changelog reflects the true release timeline.

Comment on lines 130 to 171
afterEach(() => {
cy.vcr_eject_cassette();
});

it('fetches weather data', () => {
// Start recording
cy.vcr_insert_cassette('weather_api', {
record: 'new_episodes'
});

cy.visit('/weather');
cy.contains('Current Temperature');

// Recording continues until ejected
});

it('handles API errors', () => {
// Use pre-recorded cassette
cy.vcr_insert_cassette('weather_api_error', {
record: 'none' // Only replay, don't record
});

cy.visit('/weather?city=invalid');
cy.contains('City not found');
});
});
```

### Advanced Options
```js
cy.vcr_insert_cassette('api_calls', {
record: 'new_episodes', // Recording mode
match_requests_on: ['method', 'uri', 'body'], // Request matching
erb: true, // Enable ERB in cassettes
allow_playback_repeats: true, // Allow multiple replays
exclusive: true, // Disallow other cassettes
serialize_with: 'json', // Use JSON format
preserve_exact_body_bytes: true, // For binary data
decode_compressed_response: true // Handle gzipped responses
});
```

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Align VCR usage examples with the defined Cypress commands

Earlier in this guide you add vcrInsert/vcrEject commands, but the examples here (and later in the file) switch to cy.vcr_insert_cassette / cy.vcr_eject_cassette, which aren’t defined and will break consumer suites. Please update all occurrences to the camelCase helpers that the guide tells readers to register.

-  afterEach(() => {
-    cy.vcr_eject_cassette();
+  afterEach(() => {
+    cy.vcrEject();
   });

   it('fetches weather data', () => {
     // Start recording
-    cy.vcr_insert_cassette('weather_api', { 
+    cy.vcrInsert('weather_api', { 
       record: 'new_episodes' 
     });
@@
-    cy.vcr_insert_cassette('weather_api_error', { 
+    cy.vcrInsert('weather_api_error', { 
       record: 'none'  // Only replay, don't record
     });
📝 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
afterEach(() => {
cy.vcr_eject_cassette();
});
it('fetches weather data', () => {
// Start recording
cy.vcr_insert_cassette('weather_api', {
record: 'new_episodes'
});
cy.visit('/weather');
cy.contains('Current Temperature');
// Recording continues until ejected
});
it('handles API errors', () => {
// Use pre-recorded cassette
cy.vcr_insert_cassette('weather_api_error', {
record: 'none' // Only replay, don't record
});
cy.visit('/weather?city=invalid');
cy.contains('City not found');
});
});
```
### Advanced Options
```js
cy.vcr_insert_cassette('api_calls', {
record: 'new_episodes', // Recording mode
match_requests_on: ['method', 'uri', 'body'], // Request matching
erb: true, // Enable ERB in cassettes
allow_playback_repeats: true, // Allow multiple replays
exclusive: true, // Disallow other cassettes
serialize_with: 'json', // Use JSON format
preserve_exact_body_bytes: true, // For binary data
decode_compressed_response: true // Handle gzipped responses
});
```
afterEach(() => {
cy.vcrEject();
});
it('fetches weather data', () => {
// Start recording
cy.vcrInsert('weather_api', {
record: 'new_episodes'
});
cy.visit('/weather');
cy.contains('Current Temperature');
// Recording continues until ejected
});
it('handles API errors', () => {
// Use pre-recorded cassette
cy.vcrInsert('weather_api_error', {
record: 'none' // Only replay, don't record
});
cy.visit('/weather?city=invalid');
cy.contains('City not found');
});
});
🤖 Prompt for AI Agents
In docs/VCR_GUIDE.md around lines 130 to 171, the examples use undefined
commands cy.vcr_insert_cassette and cy.vcr_eject_cassette; change those to the
previously defined camelCase helpers cy.vcrInsert and cy.vcrEject (update both
the test examples and the Advanced Options block occurrences) so all examples
match the registered Cypress commands and won’t break consumer suites.

Comment on lines 77 to 91
if @transactional && defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.begin_transaction(joinable: false)
run_hook(config.after_transaction_start)
end

yield

ensure
run_hook(config.before_server_stop)

if @transactional && defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.rollback_transaction if ActiveRecord::Base.connection.transaction_open?
end

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove the ineffective transactional wrapper.

Lines 78-89 attempt to wrap the run in a database transaction, but the Rails server is spawned in a separate process with its own connections. Any writes from the UI runner bypass this transaction, so the rollback never reverts test data, giving a false sense of isolation. Please drop the begin/rollback (and associated hook) until there’s a cross-process strategy—otherwise we quietly leave the database dirty.

-        if @transactional && defined?(ActiveRecord::Base)
-          ActiveRecord::Base.connection.begin_transaction(joinable: false)
-          run_hook(config.after_transaction_start)
-        end
-        
         yield
         
       ensure
-        run_hook(config.before_server_stop)
-        
-        if @transactional && defined?(ActiveRecord::Base)
-          ActiveRecord::Base.connection.rollback_transaction if ActiveRecord::Base.connection.transaction_open?
-        end
+        run_hook(config.before_server_stop)
📝 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
if @transactional && defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.begin_transaction(joinable: false)
run_hook(config.after_transaction_start)
end
yield
ensure
run_hook(config.before_server_stop)
if @transactional && defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.rollback_transaction if ActiveRecord::Base.connection.transaction_open?
end
yield
ensure
run_hook(config.before_server_stop)
🤖 Prompt for AI Agents
In lib/cypress_on_rails/server.rb around lines 77 to 90, remove the ineffective
cross-process transactional wrapper: delete the conditional block that calls
ActiveRecord::Base.connection.begin_transaction and the
run_hook(config.after_transaction_start) call before yield, and delete the
corresponding ensure-time rollback logic that checks transaction_open? and calls
rollback_transaction; keep the run_hook(config.before_server_stop) and the yield
intact. This removes the misleading @transactional begin/rollback behavior until
a proper cross-process strategy is implemented.

Comment on lines 54 to 55
gem 'cypress-on-rails', '~> 1.0'

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Update the Gemfile version constraint for the new release.

Line 55 still instructs users to install cypress-on-rails with ~> 1.0, which predates the rake tasks and lifecycle hooks we’re highlighting in this README. Following these updated instructions with the old constraint will pull in 1.0.x and the described features will be missing. Let’s bump the example to ~> 1.19 (or ~> 1.19.0) so Quick Start reflects the release we’re preparing.

- gem 'cypress-on-rails', '~> 1.0'
+ gem 'cypress-on-rails', '~> 1.19'
📝 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
gem 'cypress-on-rails', '~> 1.0'
gem 'cypress-on-rails', '~> 1.19'
🤖 Prompt for AI Agents
In README.md around lines 54 to 55, the Gemfile example pins cypress-on-rails to
"~> 1.0" which will pull an older release missing the rake tasks and lifecycle
hooks described; update the example line to use "~> 1.19" (or "~> 1.19.0") so
the Quick Start reflects the new release and its features.

@justin808 justin808 force-pushed the prepare-v1.19.0-release branch 2 times, most recently from e14fa03 to ac7d59a Compare September 30, 2025 10:01
@justin808 justin808 changed the title Prepare for v1.19.0 release Add automated release rake tasks Sep 30, 2025
@justin808 justin808 force-pushed the prepare-v1.19.0-release branch from ac7d59a to a31853c Compare September 30, 2025 10:04
Implements rake tasks for automating the release process, similar to Shakapacker.

New rake tasks:
- rake release:prepare[VERSION] - Bumps version and updates CHANGELOG
- rake release:publish - Tags, builds, and publishes gem to RubyGems
- rake release:full[VERSION] - Complete release in one command

Features:
- Validates semantic versioning format
- Confirms before making changes
- Updates version.rb automatically
- Updates CHANGELOG.md with date and compare link
- Runs test suite before publishing
- Creates and pushes git tags
- Builds and publishes to RubyGems
- Provides clear next steps after each phase

Documentation:
- RELEASING.md with complete release process guide
- Troubleshooting section for common issues
- Examples and pre-release checklist

This eliminates the need for a manual PR to bump versions.
Instead, maintainers can run: rake release:prepare[1.19.0]

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@justin808 justin808 force-pushed the prepare-v1.19.0-release branch from a31853c to e347083 Compare September 30, 2025 23:53
Copy link

@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

🧹 Nitpick comments (6)
RELEASING.md (3)

74-74: Format the URL as a markdown link.

The bare URL should be formatted as a markdown link for better readability and to comply with markdown best practices.

Apply this diff:

-   - Go to https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0
+   - Go to the [new release page](https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0)

Based on static analysis hints.


117-117: Consider removing release-specific issue reference.

The reference to "Issue #183" is specific to the current release and may confuse future maintainers using this checklist.

Apply this diff to make it more generic:

-- [ ] Issue #183 discussion is resolved (if applicable)
+- [ ] Related discussions are resolved

216-216: Format the URL as a markdown link.

Similar to line 74, this bare URL should be formatted as a markdown link.

Apply this diff:

-open "https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0"
+# Open the new release page
+open "https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0"

Or alternatively, document it as:

-# 7. Create GitHub release
-open "https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0"
+# 7. Create GitHub release (opens in browser)
+open "https://github.com/shakacode/cypress-playwright-on-rails/releases/new?tag=v1.19.0"

Based on static analysis hints.

Rakefile (2)

100-117: Add error handling for missing CHANGELOG.md file.

The function will raise an exception if CHANGELOG.md doesn't exist. While this is unlikely in normal operation, adding explicit error handling would make the code more robust.

Apply this diff:

 def update_changelog(version, current_version)
   changelog_file = 'CHANGELOG.md'
+  unless File.exist?(changelog_file)
+    puts "Warning: #{changelog_file} not found, skipping changelog update"
+    return
+  end
+  
   changelog = File.read(changelog_file)

108-111: Consider escaping version strings in regex for defense in depth.

Although versions are validated to match /^\d+\.\d+\.\d+$/, using Regexp.escape would provide additional safety against edge cases.

Apply this diff:

   if changelog.match?(/## \[Unreleased\]/)
     changelog.sub!(
       /## \[Unreleased\]/,
-      "## [Unreleased]\n\n---\n\n## [#{version}] — #{today}\n[Compare]: https://github.com/shakacode/cypress-playwright-on-rails/compare/v#{current_version}...v#{version}"
+      "## [Unreleased]\n\n---\n\n## [#{version}] — #{today}\n[Compare]: https://github.com/shakacode/cypress-playwright-on-rails/compare/v#{Regexp.escape(current_version)}...v#{Regexp.escape(version)}"
     )

Note: This is defensive programming; the current validation makes special characters impossible.

cypress-on-rails.gemspec (1)

24-24: Pin gem-release to latest stable version (2.2.4)
Pin the gem-release development dependency to the latest stable release to prevent unintentional breaking changes:

-  s.add_development_dependency 'gem-release'
+  s.add_development_dependency 'gem-release', '~> 2.2.4'

Latest stable version is 2.2.4 (released December 28, 2024). cite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 41be34e and e347083.

📒 Files selected for processing (3)
  • RELEASING.md (1 hunks)
  • Rakefile (1 hunks)
  • cypress-on-rails.gemspec (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
RELEASING.md

74-74: Bare URL used

(MD034, no-bare-urls)

⏰ 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: rails_8
  • GitHub Check: rails_7_2
  • GitHub Check: rails_6_1
🔇 Additional comments (1)
Rakefile (1)

85-90: Verify gem-release behavior manually

Ensure that running gem release --tag --push

  1. Creates a git tag in the expected v<version> format
  2. Builds and pushes the gem even if it was already built locally

Confirm these details against the official gem-release documentation or source.

Comment on lines +39 to +45
# Use gem bump to update version
puts "\n→ Bumping version with gem-release..."
unless system("gem bump --version #{version} --no-commit")
puts "Error: Failed to bump version"
exit 1
end
puts "✓ Updated version to #{version}"
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Use array form of system() to prevent shell injection.

Although the version is validated with a regex, using string interpolation in system() is a security risk. The array form of system() is safer as it avoids shell interpretation.

Apply this diff:

-    unless system("gem bump --version #{version} --no-commit")
+    unless system("gem", "bump", "--version", version, "--no-commit")
       puts "Error: Failed to bump version"
       exit 1
     end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Use gem bump to update version
puts "\n→ Bumping version with gem-release..."
unless system("gem bump --version #{version} --no-commit")
puts "Error: Failed to bump version"
exit 1
end
puts "✓ Updated version to #{version}"
# Use gem bump to update version
puts "\n→ Bumping version with gem-release..."
unless system("gem", "bump", "--version", version, "--no-commit")
puts "Error: Failed to bump version"
exit 1
end
puts "✓ Updated version to #{version}"
🤖 Prompt for AI Agents
In Rakefile around lines 39 to 45, the call system("gem bump --version
#{version} --no-commit") uses a single string which invokes a shell and risks
injection; replace it with the array form system("gem", "bump", "--version",
version, "--no-commit") so arguments are passed directly (no shell
interpolation), keep the existing conditional and error handling unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant