Skip to content

Upgrade: Rails 7.2 → 8.1 & Ruby 3.2.9 → 4.0.1#86

Open
kaysiz wants to merge 10 commits intomainfrom
ks-rails-8-upgrade
Open

Upgrade: Rails 7.2 → 8.1 & Ruby 3.2.9 → 4.0.1#86
kaysiz wants to merge 10 commits intomainfrom
ks-rails-8-upgrade

Conversation

@kaysiz
Copy link
Copy Markdown
Member

@kaysiz kaysiz commented Apr 1, 2026

Purpose

closes: Add github issue that originated this PR

Approach

Open Questions and Pre-Merge TODOs

Learning

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

  • New feature (non-breaking change which adds functionality)

  • Breaking change (fix or feature that would cause existing functionality to change)

Reviewer, please remember our guidelines:

  • Be humble in the language and feedback you give, ask don't tell.
  • Consider using positive language as opposed to neutral when offering feedback. This is to avoid the negative bias that can occur with neutral language appearing negative.
  • Offer suggestions on how to improve code e.g. simplification or expanding clarity.
  • Ensure you give reasons for the changes you are proposing.

Summary by CodeRabbit

  • Chores

    • Upgraded Ruby to 4.0.1 and Rails to 8.1
    • Migrated search client to Elasticsearch v8
    • Bumped many gems for compatibility and security
    • Added environment-driven build/version tagging support
    • Enhanced CI with automated security scans (bundler-audit, brakeman) and CI task orchestration
  • Bug Fixes

    • Improved masking of card payment parameters (:cvv, :cvc) in logs

@kaysiz kaysiz self-assigned this Apr 1, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 86e8cc02-ffcd-4dae-8f9f-06cf08de56ef

📥 Commits

Reviewing files that changed from the base of the PR and between da02b32 and 7f95854.

📒 Files selected for processing (1)
  • .github/workflows/parallel_ci.yml

📝 Walkthrough

Walkthrough

Upgrade Ruby to 4.0.1 and Rails to 8.1; bump many gems and adapt Elasticsearch to v8; add GIT_TAG build arg and use it for runtime VERSION; introduce CI scripts and security checks; adjust Docker base image, initializers, environment configs, and several bin scripts.

Changes

Cohort / File(s) Summary
Ruby & Rails core
\.ruby-version, Gemfile, config/application.rb
Bumped Ruby 3.2.10 → 4.0.1 and Rails 7.2 → 8.1; updated many gem constraints (including Rails, Elasticsearch gems) and set config.load_defaults(8.1).
Docker & build args
Dockerfile, .github/workflows/build.yml
Base image to phusion/passenger-ruby40, RVM default to ruby-4.0.1; added ARG GIT_TAG and ENV GIT_TAG=${GIT_TAG}; CI Docker build now passes GIT_TAG build-arg.
CI / Workflows
.github/workflows/parallel_ci.yml, .github/workflows/rubocop.yml, config/ci.rb
Updated CI Ruby versions to 4.0.1; added security job (brakeman, bundler-audit); created config/ci.rb pipeline with setup, lint, security, tests, and seed steps.
Elasticsearch / OpenSearch
config/initializers/opensearch.rb, app/jobs/event_index_job.rb, spec/jobs/event_index_job_spec.rb
Switched exception classes to Elastic::Transport::...; added ElasticsearchV8OpenSearchBypass prepended to Elasticsearch::Client to bypass product verification; updated job and spec to new transport namespace.
Versioning initializer
config/initializers/_version.rb
Removed Git-based tag/sha discovery and git dependency; set VERSION = ENV.fetch("GIT_TAG", "1.0.0"); removed REVISION.
Environments
config/environments/development.rb, config/environments/test.rb
Adjusted caching behavior (conditional memory store), changed cache header key to lowercase, removed deprecation enforcement, enabled query log tags and verbose redirect logs, and simplified test mail/caching settings.
Framework defaults
config/initializers/new_framework_defaults_7_2.rb, config/initializers/new_framework_defaults_8_1.rb
Removed 7.2 defaults file; added commented 8.1 defaults initializer (no active changes).
Bin scripts
bin/setup, bin/dev, bin/ci, bin/bundler-audit, bin/rubocop
Added bin/dev, bin/ci, bin/bundler-audit; modified bin/setup (removed APP_NAME, optional --reset, --skip-server, exec "bin/dev"); tiny comment change in bin/rubocop.
Tests & tooling
spec/rails_helper.rb, spec/jobs/event_index_job_spec.rb, .rubocop.yml
Consolidated SimpleCov start/formatter; updated job specs for new transport errors; removed global require: entry for rubocop-factory_bot.
Security / Logging
config/initializers/filter_parameter_logging.rb
Added :cvv and :cvc to filtered parameters for logs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main change: upgrading Rails from 7.2 to 8.1 and Ruby from 3.2.9 to 4.0.1, which aligns with the comprehensive changeset across Gemfile, Dockerfile, workflow files, and configuration files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ks-rails-8-upgrade

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
Copy Markdown

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

Caution

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

⚠️ Outside diff range comments (1)
spec/jobs/event_index_job_spec.rb (1)

86-106: ⚠️ Potential issue | 🟡 Minor

Test uses SocketError instead of Elastic::Transport::Transport::Error.

The describe block names Elastic::Transport::Transport::Error, but line 87 creates a SocketError instance. This test doesn't actually verify that the job rescues from Elastic::Transport::Transport::Error — it passes coincidentally because SocketError is also in the rescue list.

🔧 Proposed fix to use the correct exception class
   describe "Elastic::Transport::Transport::Error" do
-    let(:error) { SocketError.allocate }
+    let(:error) { Elastic::Transport::Transport::Error.allocate }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/jobs/event_index_job_spec.rb` around lines 86 - 106, The test is
instantiating SocketError instead of the intended
Elastic::Transport::Transport::Error; change the let(:error) to create an
instance of Elastic::Transport::Transport::Error (e.g., construct or allocate
that class) and keep the existing stubbing of error.message and the
allow(...).to(receive(:index_document).and_raise(error)) so the job actually
raises and rescues the Elastic::Transport::Transport::Error when
described_class.perform_now(event) is called; update only the error creation
(referenced by let(:error)) so the rest of the spec (event.__elasticsearch__,
index_document, described_class.perform_now) stays the same.
🧹 Nitpick comments (3)
config/initializers/new_framework_defaults_8_1.rb (1)

5-7: This staged-upgrade initializer is now misleading.

config/application.rb Line 22 already opts the app into 8.1 defaults, so this file reads like the 8.1 switches are still pending when the global flip has already happened. Either delete it, or keep the app on the older load_defaults target until you actually roll these settings out one by one. (api.rubyonrails.org)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/initializers/new_framework_defaults_8_1.rb` around lines 5 - 7, The
staged-upgrade initializer new_framework_defaults_8_1.rb is misleading because
the application is already opting into Rails 8.1 via config.load_defaults in
your application configuration; either remove this initializer to avoid
confusion or revert the global opt-in by changing the config.load_defaults call
(the Application.config.load_defaults setting) back to the previous target so
you can truly roll the individual switches in new_framework_defaults_8_1.rb
one-by-one.
bin/dev (1)

2-2: Anchor the bin/rails path to the script directory.

exec "./bin/rails" depends on the caller's current working directory, so this wrapper breaks if bin/dev is invoked outside the repo root. Use __dir__ here to make it location-independent.

♻️ Suggested change
-exec "./bin/rails", "server", *ARGV
+exec File.expand_path("rails", __dir__), "server", *ARGV
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/dev` at line 2, The exec call currently uses a relative path ("exec
\"./bin/rails\", \"server\", *ARGV") which breaks when bin/dev is run outside
the repo root; change the exec invocation to use an anchored path built from
__dir__ so it always resolves to the script's directory (i.e., construct the
absolute path to bin/rails using __dir__ and pass that to exec in place of
"./bin/rails") and keep the remaining arguments ("server", *ARGV) unchanged.
bin/bundler-audit (1)

5-5: Don't append a second --config when one was supplied explicitly.

With the current guard, bin/bundler-audit check --config other.yml ends up with two config flags, so callers can't cleanly override the default config.

♻️ Suggested change
-ARGV.concat %w[ --config config/bundler-audit.yml ] if ARGV.empty? || ARGV.include?("check")
+if (ARGV.empty? || ARGV.include?("check")) && !ARGV.include?("--config")
+  ARGV.concat %w[--config config/bundler-audit.yml]
+end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/bundler-audit` at line 5, The current ARGV.concat line appends the
default --config even when the caller already passed --config, producing
duplicate flags; change the condition so the default is only appended when ARGV
is empty or contains just "check" and no existing --config argument. Update the
guard around ARGV.concat %w[ --config config/bundler-audit.yml ] to also verify
no element in ARGV starts_with?("--config") (or equals "--config"), e.g., only
concat when (ARGV.empty? || ARGV == ["check"]) && ARGV.none? { |a|
a.start_with?("--config") }, so calls like bin/bundler-audit check --config
other.yml do not get a second --config.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/parallel_ci.yml:
- Around line 36-39: Replace the direct invocation of bundler-audit with the
repo wrapper so the project's ignore list is respected: update the Security
Check step to call the wrapper (bin/bundler-audit) instead of running "bundle
exec bundler-audit check --update" so config/bundler-audit.yml is applied; keep
the rest of the step (and brakeman call) unchanged.

In `@config/application.rb`:
- Line 22: The RuboCop offense is caused by an unparenthesized method call to
config.load_defaults; update the call to use parentheses (i.e., change
config.load_defaults 8.1 to config.load_defaults(8.1)) so the
Style/MethodCallWithArgsParentheses rule is satisfied and CI will pass; edit the
config.load_defaults usage in application.rb accordingly.

In `@config/bundler-audit.yml`:
- Around line 1-5: The CI workflow is invoking bundler-audit directly (bundle
exec bundler-audit check --update) so it bypasses the wrapper that appends
config/bundler-audit.yml; update the parallel_ci.yml job to run the wrapper
(bin/bundler-audit check --update) instead of calling bundler-audit directly, or
alternatively modify the wrapper script referenced by bin/bundler-audit to be
invoked by the workflow; ensure the command change causes the ignore list in
config/bundler-audit.yml to be applied during CI.

In `@config/environments/development.rb`:
- Around line 20-24: The dev:cache toggle only sets public_file_server.headers
but never enables Action Controller caching; update the if branch to set
config.action_controller.perform_caching = true (and typically also set a dev
cache store, e.g. config.cache_store = :memory_store) alongside
config.public_file_server.headers so that tmp/caching-dev.txt actually turns on
controller/fragment caching; leave the else branch as-is where
config.action_controller.perform_caching = false.

In `@config/initializers/_version.rb`:
- Line 3: The line defining the VERSION constant has incorrect indentation width
(1 space) causing a RuboCop offense; update the indentation to use 2 spaces
before the assignment so the file follows the project's 2-space indentation rule
(ensure the line with VERSION = ENV.fetch("GIT_TAG", "1.0.0") and any
surrounding lines in this initializer use two spaces consistently).

In `@config/initializers/filter_parameter_logging.rb`:
- Around line 6-8: The array assigned to
Rails.application.config.filter_parameters is missing the trailing comma on the
last element, triggering Style/TrailingCommaInArrayLiteral; update the array
literal used in the filter_parameters assignment (the
Rails.application.config.filter_parameters array) to include a trailing comma
after the final symbol so the linter stops failing.

In `@config/initializers/opensearch.rb`:
- Around line 8-15: The module ElasticsearchV8OpenSearchBypass has RuboCop
indentation offenses; reformat so Ruby style is followed: indent the private
keyword and the verify_elasticsearch method two spaces inside the module, with
the method body lines (response = `@transport.perform_request`(*args, &block),
`@verified` = true, response) indented two additional spaces, and ensure the
closing end keywords line up with their openings; locate the module name
ElasticsearchV8OpenSearchBypass and the verify_elasticsearch method to apply
these changes.

In `@Dockerfile`:
- Around line 3-9: The Dockerfile sets ARG GIT_TAG and ENV GIT_TAG early which
makes ENV GIT_TAG a cache invalidation point and forces expensive layers
(apt-get, bundle install) to rebuild; move the ARG GIT_TAG=1.0 and the ENV
GIT_TAG=${GIT_TAG} block to the end of the Dockerfile after all expensive build
steps so GIT_TAG is only applied at runtime, ensuring earlier layers keep their
cache; specifically remove or relocate the existing ARG GIT_TAG/ENV GIT_TAG near
the top and add them as a final block "ARG GIT_TAG=1.0" followed by "ENV
GIT_TAG=${GIT_TAG}" after the bundle install and other heavy RUN instructions.

---

Outside diff comments:
In `@spec/jobs/event_index_job_spec.rb`:
- Around line 86-106: The test is instantiating SocketError instead of the
intended Elastic::Transport::Transport::Error; change the let(:error) to create
an instance of Elastic::Transport::Transport::Error (e.g., construct or allocate
that class) and keep the existing stubbing of error.message and the
allow(...).to(receive(:index_document).and_raise(error)) so the job actually
raises and rescues the Elastic::Transport::Transport::Error when
described_class.perform_now(event) is called; update only the error creation
(referenced by let(:error)) so the rest of the spec (event.__elasticsearch__,
index_document, described_class.perform_now) stays the same.

---

Nitpick comments:
In `@bin/bundler-audit`:
- Line 5: The current ARGV.concat line appends the default --config even when
the caller already passed --config, producing duplicate flags; change the
condition so the default is only appended when ARGV is empty or contains just
"check" and no existing --config argument. Update the guard around ARGV.concat
%w[ --config config/bundler-audit.yml ] to also verify no element in ARGV
starts_with?("--config") (or equals "--config"), e.g., only concat when
(ARGV.empty? || ARGV == ["check"]) && ARGV.none? { |a| a.start_with?("--config")
}, so calls like bin/bundler-audit check --config other.yml do not get a second
--config.

In `@bin/dev`:
- Line 2: The exec call currently uses a relative path ("exec \"./bin/rails\",
\"server\", *ARGV") which breaks when bin/dev is run outside the repo root;
change the exec invocation to use an anchored path built from __dir__ so it
always resolves to the script's directory (i.e., construct the absolute path to
bin/rails using __dir__ and pass that to exec in place of "./bin/rails") and
keep the remaining arguments ("server", *ARGV) unchanged.

In `@config/initializers/new_framework_defaults_8_1.rb`:
- Around line 5-7: The staged-upgrade initializer new_framework_defaults_8_1.rb
is misleading because the application is already opting into Rails 8.1 via
config.load_defaults in your application configuration; either remove this
initializer to avoid confusion or revert the global opt-in by changing the
config.load_defaults call (the Application.config.load_defaults setting) back to
the previous target so you can truly roll the individual switches in
new_framework_defaults_8_1.rb one-by-one.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2c6bfae9-3f2a-4313-89e8-80b108dda4b6

📥 Commits

Reviewing files that changed from the base of the PR and between 14434ea and e7d3e1a.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • .github/workflows/build.yml
  • .github/workflows/parallel_ci.yml
  • .github/workflows/rubocop.yml
  • .ruby-version
  • Dockerfile
  • Gemfile
  • app/jobs/event_index_job.rb
  • bin/bundler-audit
  • bin/ci
  • bin/dev
  • bin/rubocop
  • bin/setup
  • config/application.rb
  • config/bundler-audit.yml
  • config/ci.rb
  • config/environments/development.rb
  • config/environments/test.rb
  • config/initializers/_version.rb
  • config/initializers/filter_parameter_logging.rb
  • config/initializers/new_framework_defaults_7_2.rb
  • config/initializers/new_framework_defaults_8_1.rb
  • config/initializers/opensearch.rb
  • spec/jobs/event_index_job_spec.rb
  • spec/rails_helper.rb
💤 Files with no reviewable changes (1)
  • config/initializers/new_framework_defaults_7_2.rb

Comment thread .github/workflows/parallel_ci.yml Outdated
Comment thread config/application.rb Outdated
Comment thread config/bundler-audit.yml Outdated
Comment on lines +1 to +5
# Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit.
# CVEs that are not relevant to the application can be enumerated on the ignore list below.

ignore:
- CVE-THAT-DOES-NOT-APPLY
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

This config is skipped by the GitHub Actions path.

The ignore list is only appended when callers go through bin/bundler-audit, but .github/workflows/parallel_ci.yml invokes bundle exec bundler-audit check --update directly. That means this file is silently ignored in that workflow, and any CVEs listed here won't actually be suppressed there.

💡 Align the workflow with the configured wrapper
-          bundle exec bundler-audit check --update
+          bin/bundler-audit check --update
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/bundler-audit.yml` around lines 1 - 5, The CI workflow is invoking
bundler-audit directly (bundle exec bundler-audit check --update) so it bypasses
the wrapper that appends config/bundler-audit.yml; update the parallel_ci.yml
job to run the wrapper (bin/bundler-audit check --update) instead of calling
bundler-audit directly, or alternatively modify the wrapper script referenced by
bin/bundler-audit to be invoked by the workflow; ensure the command change
causes the ignore list in config/bundler-audit.yml to be applied during CI.

Comment thread config/environments/development.rb
Comment thread config/initializers/filter_parameter_logging.rb
Comment thread config/initializers/opensearch.rb
Comment thread Dockerfile Outdated
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/initializers/_version.rb`:
- Line 3: Replace the unconditional default fallback when setting VERSION so
deploys fail fast in stage/production: change the assignment that currently uses
VERSION = ENV.fetch("GIT_TAG", "1.0.0") to conditionally require GIT_TAG in
production/stage (e.g., if Rails.env.production? || Rails.env.staging? then
VERSION = ENV.fetch("GIT_TAG") else VERSION = ENV.fetch("GIT_TAG", "1.0.0") ),
so missing GIT_TAG raises in stage/prod but preserves the local/dev fallback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ebffb128-63c8-4ade-92e2-7584b0e4af37

📥 Commits

Reviewing files that changed from the base of the PR and between e7d3e1a and b705620.

📒 Files selected for processing (5)
  • .rubocop.yml
  • config/application.rb
  • config/initializers/_version.rb
  • config/initializers/filter_parameter_logging.rb
  • config/initializers/opensearch.rb
💤 Files with no reviewable changes (1)
  • .rubocop.yml
✅ Files skipped from review due to trivial changes (1)
  • config/initializers/filter_parameter_logging.rb
🚧 Files skipped from review as they are similar to previous changes (2)
  • config/application.rb
  • config/initializers/opensearch.rb

Comment thread config/initializers/_version.rb
@kaysiz kaysiz changed the title Ks rails 8 upgrade Upgrade: Rails 7.2 → 8.1 & Ruby 3.2.9 → 4.0.1 Apr 2, 2026
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
Gemfile (1)

14-14: Move dotenv to development and test groups.

Currently, dotenv is loaded as a production dependency, but it should only be used in development and test environments. The code in config/application.rb already guards the require with a file existence check, making this change safe—if no .env file exists in production, dotenv is never required.

♻️ Proposed change
-gem "dotenv", "~> 3.2"

 group :development, :test do
+  gem "dotenv", "~> 3.2"
   gem "debug", "~> 1.11", ">= 1.11.1", platforms: [:mri, :windows]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Gemfile` at line 14, The Gemfile currently lists the dotenv gem as a general
dependency; move gem "dotenv", "~> 3.2" into a development and test group so
it’s only loaded in those environments—wrap it in group :development, :test do
... end (remove the top-level declaration) and then run bundle install to update
the lockfile; this change targets the dotenv entry in the Gemfile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Gemfile`:
- Line 14: The Gemfile currently lists the dotenv gem as a general dependency;
move gem "dotenv", "~> 3.2" into a development and test group so it’s only
loaded in those environments—wrap it in group :development, :test do ... end
(remove the top-level declaration) and then run bundle install to update the
lockfile; this change targets the dotenv entry in the Gemfile.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d7a0761-dc69-4ed0-baf9-b639d8f46208

📥 Commits

Reviewing files that changed from the base of the PR and between b705620 and ba3d362.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • Gemfile

@kaysiz kaysiz requested a review from a team April 14, 2026 08:42
@jrhoads
Copy link
Copy Markdown

jrhoads commented Apr 15, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 15, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

2 participants