Skip to content

Fix scheduled CI: RuboCop drift, latent test failures, and dependency rot#88

Open
28Pollux28 wants to merge 5 commits into
mainfrom
fix/rubocop-1.87-offenses
Open

Fix scheduled CI: RuboCop drift, latent test failures, and dependency rot#88
28Pollux28 wants to merge 5 commits into
mainfrom
fix/rubocop-1.87-offenses

Conversation

@28Pollux28

@28Pollux28 28Pollux28 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Why

The scheduled Tests run failed at Run rubocop with no code change. Fixing that surfaced further pre-existing failures that had been masked by the rubocop step + fail-fast. This PR gets the entire matrix green (18 Ruby × ActiveRecord combos + a lint job).

Root cause throughout: a gem testing EOL Ruby (2.5–3.0) × EOL Rails (5.0–7.0) against the latest transitive dependencies, with no lockfile, on a 6-hour schedule — so dependency drift accumulates silently until something breaks.

Changes

1. RuboCop offenses (the reported failure). Bundler resolved the unpinned rubocop ~> 1 to 1.87.0 on Ruby 2.7/3.0, which (with NewCops: enable) introduced new cops and renamed a config key.

  • Style/SuperArguments → bare super (forwards identical args; behavior-neutral)
  • Lint/UselessConstantScopingprivate_constant (the private modifier is a no-op for constants)
  • Gemspec/DevelopmentDependencies → disabled (dev deps intentionally in the gemspec)
  • IgnoredMethodsAllowedMethods (the old key had silently stopped applying the Metrics exclusions)

2. RuboCop runs in a dedicated lint job, not the test matrix. A single pinned rubocop can't satisfy a Ruby 2.5–3.0 matrix (1.87 needs ≥ 2.7; the version bundler picks for 2.5 rejects newer config keys as a fatal error). Linting now runs once on a modern Ruby via gemfiles/rubocop.gemfile (rubocop only — no gemspec, so no mysql2 native build), pinned so future releases are deliberate upgrades. This permanently defuses the scheduled rubocop drift.

3. Latent test failure — Mysql2::Client double. Current ActiveRecord patches probe the raw connection's liveness (ping/closed?/close) while building statements; the real client answers these, so the test double now does too.

4. Dependency rot — concurrent-ruby 1.3.5. It dropped its transitive require 'logger', breaking ActiveSupport < 7.1 at load (uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger). AR 7.0 got the upstream fix; the EOL 6.0/6.1 lines did not, so those gemfiles pin concurrent-ruby < 1.3.5.

5. fail-fast: false on the matrix so independent compat failures surface together instead of one-per-run.

Verification

All 19 jobs green (18 matrix combos + lint). RuboCop (1.87.0) locally: 24 files, no offenses.

🤖 Generated with Claude Code

@28Pollux28 28Pollux28 force-pushed the fix/rubocop-1.87-offenses branch 2 times, most recently from cb3c2ad to 6194d0d Compare June 17, 2026 09:18
@28Pollux28 28Pollux28 changed the title Fix RuboCop 1.87 offenses and pin rubocop version Fix RuboCop 1.87 offenses and a latent test-double gap Jun 17, 2026
The scheduled CI run failed at the `rubocop` step. With the failure
fixed, the test step (which never ran before, due to fail-fast) surfaced
a second, pre-existing failure from dependency drift.

RuboCop (on Ruby 2.7/3.0, bundler resolved `rubocop ~> 1` to 1.87.0,
which with `NewCops: enable` added new cops and renamed `IgnoredMethods`):
- Style/SuperArguments: use bare `super` (forwards identical args)
- Lint/UselessConstantScoping: mark the private constants with
  `private_constant` instead of the (no-op) `private` modifier
- Gemspec/DevelopmentDependencies: disable; dev deps are intentionally
  declared in the gemspec
- Rename obsolete `IgnoredMethods` -> `AllowedMethods` in .rubocop.yml

Tests:
- Stub `closed?`/`close` on the Mysql2::Client double. Current
  ActiveRecord patches probe the raw connection state while building
  statements; the real client responds to these, so the double must too.

rubocop is left unpinned (`~> 1`): the test matrix spans Ruby 2.5-3.0 and
no single rubocop version installs across all of them (1.87 needs Ruby
>= 2.7). Permanently defusing the scheduled breakage requires a dedicated
lint job on one modern Ruby - proposed as a follow-up.

Co-Authored-By: Claude <noreply@anthropic.com>
@28Pollux28 28Pollux28 force-pushed the fix/rubocop-1.87-offenses branch from 6194d0d to 11ad517 Compare June 17, 2026 09:21
28Pollux28 and others added 3 commits June 17, 2026 11:27
Cancelling the whole matrix on the first failure masks independent
failures across the Ruby/ActiveRecord compatibility combos (it is how the
pre-existing test failures stayed hidden behind the rubocop step). Run
every combo to completion so the full surface is visible.

Co-Authored-By: Claude <noreply@anthropic.com>
RuboCop's version is tied to the Ruby it runs on, which conflicts with the
Ruby 2.5-3.0 test matrix: a version new enough for current cops (1.87
needs Ruby >= 2.7) cannot install on 2.5/2.6, while the version bundler
picks for 2.5 rejects newer config keys as fatal errors.

Move linting out of the matrix into a single job on a modern Ruby, using a
dedicated gemfiles/rubocop.gemfile that pulls only RuboCop (no gemspec, so
no activerecord/mysql2 native build). RuboCop is pinned there so new
releases land as deliberate upgrades rather than breaking scheduled runs.

- Remove rubocop from the gemspec dev dependencies
- Drop the per-matrix `Run rubocop` step; add a `rubocop` job
- Make the Rakefile's rubocop task optional so `rake` works without it

Co-Authored-By: Claude <noreply@anthropic.com>
concurrent-ruby 1.3.5 dropped its transitive `require 'logger'`, breaking
ActiveSupport < 7.1 at load time (uninitialized constant
ActiveSupport::LoggerThreadSafeLevel::Logger). These EOL ActiveRecord
lines never received the upstream fix (7.0 did), so pin the dependency
below 1.3.5 in their gemfiles.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread .github/workflows/tests.yml Fixed
@28Pollux28 28Pollux28 changed the title Fix RuboCop 1.87 offenses and a latent test-double gap Fix scheduled CI: RuboCop drift, latent test failures, and dependency rot Jun 18, 2026
The workflow only checks out and tests/lints the repo, so it needs no
write scopes. Addresses the CodeQL "workflow does not contain
permissions" finding.

Co-Authored-By: Claude <noreply@anthropic.com>
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