Skip to content

Add a Sorbet type check to CI - #573

Open
stefan-burke wants to merge 1 commit into
mainfrom
sorbet-type-check
Open

stefan-burke wants to merge 1 commit into
mainfrom
sorbet-type-check

Conversation

@stefan-burke

Copy link
Copy Markdown
Member

What this does

The repo has never typechecked: srb tc reports 919 errors in typed: true/strict files, so a bare gate would be permanently red. This adds the gradual-adoption gate Sorbet's docs recommend — bin/check-sorbet-errors compares the reported count against the committed sorbet/error-count-baseline and fails only when a change adds net errors. Lower the baseline as debt is paid down.

It reuses the existing setup-environment composite action, and the workflow is named Sorbet Type Check — the name bin/get-sorbet-results already looks for.

How the count got down from 1410

Measured on the CI checkout. (The very first local number, 1272, was inflated by the gems/chobble-forms submodule, which CI does not fetch — hence the --ignore=/gems/ and --ignore=/.gems/ entries in sorbet/config so local and CI agree.)

  • Tapioca DSL RBIs are generated and checked (the big one). The workflow prepares a scratch test database via DATABASE_URL and runs tapioca dsl; the per-model RBIs for columns, associations, enums and scopes resolve the largest error bucket. Tapioca also emits RBIs for Rails framework classes and gem engines (pg_query, solid_queue, mission_control, …) whose constants cannot resolve without gem RBIs, so those directories stay ignored while the app's own model RBIs are checked.
  • Manual RBIs gain I18n (the i18n gem ships none — 199 errors were just unresolved I18n), Object#present?/blank?, String/NilClass#presence, Inspection#id, and the Rails internals the generated DSL files reference (ActiveRecord::Relation, ActiveStorage::Attached::One, Boolean, …).

Testing

  • From-scratch reproduction locally: db:prepare → tapioca dsl → srb tc = 919, matching the baseline (deterministic; regenerated twice).
  • Gate fail-path verified: with the baseline lowered by one, the script exits 1 and dumps the newest errors.
  • The RBIs and sorbet/config are static-only — no runtime code changes; srb tc itself cannot run on this NixOS checkout because sorbet-static ships a dynamically linked binary (a patched copy was used to measure), which is exactly why the check lives in CI.
  • CLAUDE.md documents the local reproduction steps.

Notes

  • Advisory to nothing else: the check is a required-style CI job only; nothing local or pre-commit depends on it.
  • Errors in sorbet/rbi/dsl/ and sorbet/rbi/gems/ remain gitignored artifacts, generated in CI. Rails gem RBIs are the known gap: tapioca gems emits empty RBIs for Rails (lazy-loaded constants), which is why the framework DSL directories stay scoped out for now.

The repo has never typechecked: srb tc reports 919 errors in
typed:true/strict files, so a bare gate would be permanently red.
bin/check-sorbet-errors compares the reported count against
sorbet/error-count-baseline and fails when a change adds net errors -
the gradual-adoption gate Sorbet's docs recommend. Lower the baseline
as debt is paid down.

- Reuse the setup-environment composite action, and keep the workflow
  named 'Sorbet Type Check' so bin/get-sorbet-results finds it again
- Generate Tapioca DSL RBIs in CI against a scratch test database
  (DATABASE_URL sidesteps both the stale dev database and the
  per-process test database); the per-model RBIs for columns,
  associations, enums and scopes resolve the largest error bucket
- Scope the generated RBIs: Tapioca also emits files for Rails
  framework classes and gem engines (pg_query, solid_queue,
  mission_control, ...) whose constants cannot resolve without gem
  RBIs, so those directories stay ignored
- Ignore the nix devshell's in-repo GEM_HOME (.gems) and the
  chobble-forms submodule tree (/gems/) so local and CI counts agree
- Declare the missing pieces in sorbet/rbi/manual: I18n (the gem ships
  no RBI), Object#present?/blank?, String/NilClass#presence,
  Inspection#id, and the Rails internals the generated DSL files
  reference
- Document the flow in CLAUDE.md
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 4 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 110 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: d1aaae98-ba64-4b5e-acbb-2e7b28610e5c

📥 Commits

Reviewing files that changed from the base of the PR and between cd0c8e0 and 2d290ff.

📒 Files selected for processing (11)
  • .github/workflows/sorbet.yml
  • .github/workflows/status-check.yml
  • CLAUDE.md
  • bin/check-sorbet-errors
  • sorbet/config
  • sorbet/error-count-baseline
  • sorbet/rbi/manual/active_support_extensions.rbi
  • sorbet/rbi/manual/i18n.rbi
  • sorbet/rbi/manual/model_associations.rbi
  • sorbet/rbi/manual/rails_internals.rbi
  • sorbet/rbi/manual/view_helper_modules.rbi

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

Comment on lines +10 to +34
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7

- name: Setup environment
uses: ./.github/actions/setup-environment

# Tapioca's DSL RBIs describe model columns, associations and scopes.
# They are gitignored, so generate them against a scratch test database
# before typechecking.
- name: Prepare scratch database
env:
RAILS_ENV: test
DATABASE_URL: sqlite3:tmp/tapioca-scratch.sqlite3
run: bundle exec rails db:prepare

- name: Generate Tapioca DSL RBIs
env:
RAILS_ENV: test
DATABASE_URL: sqlite3:tmp/tapioca-scratch.sqlite3
run: bundle exec tapioca dsl

- name: Run Sorbet
run: bin/check-sorbet-errors
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