Skip to content

Conversation

@jfitzgerald1126
Copy link

TL;DR

Briefly describe what this PR does and why it is needed. Include any relevant background or context.

This PR introduces Sorbet and Tapioca to the codebase to enable gradual static type checking in Ruby.


What is this PR trying to achieve?

Explain the main goal or problem this PR addresses. What functionality, bug fix, or improvement does it introduce?

This PR introduces static type checking to the codebase using Sorbet and Tapioca, laying the groundwork for gradually adding type safety across the application. The goal is to improve code reliability, catch type errors earlier in development, and provide better tooling support as the project grows. It also replaces outdated RBI sources with automatically generated, framework-accurate RBIs to reduce maintenance overhead.


How did you achieve it?

Describe the approach, implementation details, or key changes made. Mention any libraries, refactors, or design choices involved.

Included in this PR

  • Added Sorbet (sorbet + sorbet-runtime) and Tapioca gems
  • Initialized Sorbet and created the sorbet/ directory
  • Generated RBI files using Tapioca (tapioca gem + tapioca dsl)
  • Ensured bundle exec srb tc runs with 0 errors

Follow-up Work

  • Add Sorbet type checking to CI (bundle exec srb tc)
  • Add tapioca check to CI to ensure RBIs stay up-to-date
  • Gradually add typing strictness to the codebase (typed: true, typed: strict)
  • Begin adding typing to service objects, then models, then controllers/helpers
  • Increase file strictness levels over time as type coverage improves

Checklist

  • Changes have been top-hatted locally
  • Tests have been added or updated
  • Documentation has been updated (if applicable)
  • Linked related issues

Copilot AI review requested due to automatic review settings December 6, 2025 16:08
@jfitzgerald1126 jfitzgerald1126 linked an issue Dec 6, 2025 that may be closed by this pull request
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces static type checking to the Ruby codebase using Sorbet and Tapioca, enabling gradual adoption of type safety to improve code reliability and catch type errors earlier in development.

Key Changes:

  • Added Sorbet and Tapioca gems with necessary configuration
  • Initialized Sorbet directory structure with generated RBI files
  • Updated documentation with type checking workflow and commands

Reviewed changes

Copilot reviewed 5 out of 316 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Gemfile Added sorbet, sorbet-runtime, tapioca, and openssl dependencies
README.md Added comprehensive documentation for Sorbet type checking workflow
sorbet/config Created Sorbet configuration with directory settings and ignore patterns
sorbet/rbi/dsl/.gitattributes Configured linguist to mark DSL RBI files as generated
sorbet/rbi/annotations/.gitattributes Configured linguist to mark annotation RBI files as vendored
Files not reviewed (131)
  • sorbet/rbi/annotations/actionmailer.rbi: Language not supported
  • sorbet/rbi/annotations/actionpack.rbi: Language not supported
  • sorbet/rbi/annotations/actionview.rbi: Language not supported
  • sorbet/rbi/annotations/activejob.rbi: Language not supported
  • sorbet/rbi/annotations/activemodel.rbi: Language not supported
  • sorbet/rbi/annotations/activerecord.rbi: Language not supported
  • sorbet/rbi/annotations/activesupport.rbi: Language not supported
  • sorbet/rbi/annotations/globalid.rbi: Language not supported
  • sorbet/rbi/annotations/minitest.rbi: Language not supported
  • sorbet/rbi/annotations/railties.rbi: Language not supported
  • sorbet/rbi/annotations/rainbow.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/caching.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/caching/fragments.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/helpers.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/rendering.rbi: Language not supported
  • sorbet/rbi/dsl/abstract_controller/url_for.rbi: Language not supported
  • sorbet/rbi/dsl/action_cable/channel/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/action_cable/channel/periodic_timers.rbi: Language not supported
  • sorbet/rbi/dsl/action_cable/connection/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/action_cable/connection/identification.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/api_rendering.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/caching.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/conditional_get.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/content_security_policy.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/data_streaming.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/etag_with_flash.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/etag_with_template_digest.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/flash.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/form_builder.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/helpers.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/params_wrapper.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/redirecting.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/renderers.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/renderers/all.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/request_forgery_protection.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/rescue.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/test_case/behavior.rbi: Language not supported
  • sorbet/rbi/dsl/action_controller/url_for.rbi: Language not supported
  • sorbet/rbi/dsl/action_dispatch/assertions.rbi: Language not supported
  • sorbet/rbi/dsl/action_dispatch/integration_test.rbi: Language not supported
  • sorbet/rbi/dsl/action_dispatch/routing/route_set/mounted_helpers.rbi: Language not supported
  • sorbet/rbi/dsl/action_dispatch/routing/url_for.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailbox/inbound_email.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailbox/incineration_job.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailbox/routing_job.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/delivery_methods.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/form_builder.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/mail_delivery_job.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/queued_delivery.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/rescuable.rbi: Language not supported
  • sorbet/rbi/dsl/action_mailer/test_case/behavior.rbi: Language not supported
  • sorbet/rbi/dsl/action_text/encrypted_rich_text.rbi: Language not supported
  • sorbet/rbi/dsl/action_text/rich_text.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/helpers.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/helpers/form_helper.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/helpers/form_tag_helper.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/helpers/text_helper.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/layouts.rbi: Language not supported
  • sorbet/rbi/dsl/action_view/rendering.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/concurrency_controls.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/enqueuing.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/exceptions.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/execution.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/logging.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/queue_adapter.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/queue_name.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/queue_priority.rbi: Language not supported
  • sorbet/rbi/dsl/active_job/test_helper/test_queue_adapter.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/api.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/attribute_methods.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/attributes.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/attributes/normalization.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/conversion.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/dirty.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/model.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/serializers/json.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/validations.rbi: Language not supported
  • sorbet/rbi/dsl/active_model/validations/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/attribute_methods.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/attribute_methods/dirty.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/attribute_methods/serialization.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/attribute_methods/time_zone_conversion.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/attributes.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/core.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/counter_cache.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/encryption/encryptable_record.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/inheritance.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/integration.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/locking/optimistic.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/model_schema.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/nested_attributes.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/readonly_attributes.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/reflection.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/scoping.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/scoping/default.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/secure_password.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/serialization.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/signed_id.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/timestamp.rbi: Language not supported
  • sorbet/rbi/dsl/active_record/token_for.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/analyze_job.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/attachment.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/blob.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/current.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/mirror_job.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/preview_image_job.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/purge_job.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/reflection/active_record_extensions.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/streaming.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/transform_job.rbi: Language not supported
  • sorbet/rbi/dsl/active_storage/variant_record.rbi: Language not supported
  • sorbet/rbi/dsl/active_support/actionable_error.rbi: Language not supported
  • sorbet/rbi/dsl/active_support/callbacks.rbi: Language not supported
  • sorbet/rbi/dsl/active_support/rescuable.rbi: Language not supported
  • sorbet/rbi/dsl/active_support/testing/file_fixtures.rbi: Language not supported
  • sorbet/rbi/dsl/application_controller.rbi: Language not supported
  • sorbet/rbi/dsl/application_mailer.rbi: Language not supported
  • sorbet/rbi/dsl/generated_path_helpers_module.rbi: Language not supported
  • sorbet/rbi/dsl/generated_url_helpers_module.rbi: Language not supported
  • sorbet/rbi/dsl/journal.rbi: Language not supported
  • sorbet/rbi/dsl/log_entry.rbi: Language not supported
  • sorbet/rbi/dsl/project.rbi: Language not supported
  • sorbet/rbi/dsl/rails/application_controller.rbi: Language not supported
  • sorbet/rbi/dsl/rails/conductor/base_controller.rbi: Language not supported
  • sorbet/rbi/dsl/region.rbi: Language not supported
  • sorbet/rbi/dsl/report.rbi: Language not supported
  • sorbet/rbi/dsl/snapshot.rbi: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

# OpenSSL for tapioca support - https://github.com/Shopify/tapioca/issues/2156#issuecomment-3605679933
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

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

The comment references a GitHub issue comment ID that appears to be in the future (3605679933 is an unusually high number). Please verify this URL is correct and accessible, as it may be a typo or placeholder.

Suggested change
# OpenSSL for tapioca support - https://github.com/Shopify/tapioca/issues/2156#issuecomment-3605679933
# OpenSSL for tapioca support - see https://github.com/Shopify/tapioca/issues/2156

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@ch-iv ch-iv left a comment

Choose a reason for hiding this comment

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

Thank you for tackling this issue. This PR looks great!

One thing we also need is a monkey patch that would allow all modules to access sorbet methods used for type annotation (e.g., sig, params, returns) without having to explicitly extend T::Sig. There is more information about it on the sorbet docs: https://sorbet.org/docs/sigs#can-i-skip-writing-extend-tsig-everywhere.

On a second thought, we should migrate to RBS style comments. Since they are just comments, we actually wouldn't need to extend T::Sig for it to work (hence the monkey patch is not needed.) Let's enable RBS in this PR and set it as the standard for all type annotations in this project.

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.

Implement type checking with Sorbet and Tapioca for Ruby files

3 participants