Project

General

Profile

Actions

Support #22920

closed

Upgrade Gemfile pins for Ruby 2.7→3.0

Added by Brett Smith 10 months ago. Updated 6 months ago.

Status:
Resolved
Priority:
Normal
Assigned To:
Category:
API
Target version:
Due date:
Story points:
-
Release relationship:
Auto

Description

Because Arvados 3.2.0 drops support for Debian 11 and Ubuntu 20.04, our minimum Ruby version goes from 2.7 to 3.0 (in Ubuntu 22.04).

In all of the following Gemfiles, review pins that note they're for Ruby 2.7 compatibility, and update them to the latest versions that support Ruby 3.0:

For example, in the API server, update Rails from ~> 7.1.3.4 to ~> 7.1.5. (Rails 7.2 requires Ruby 3.1.) Update the associated comments. Do not remove any pins. Even if the latest version supports Ruby 3.0, gems that dropped older Rubies before are likely to do so again. Just update the pin to the latest version.

Run bundle install in each directory to update the corresponding Gemfile.lock.

Bump at least the PATCH level in source:/sdk/ruby-google-api-client/lib/google/api_client/version.rb


Subtasks 1 (0 open1 closed)

Task #23135: Review 22920-update-gem-pinsResolvedBrett Smith09/08/2025Actions

Related issues 1 (0 open1 closed)

Blocked by Arvados - Support #22864: Drop support for Ubuntu 20.04 and Debian 11ResolvedBrett SmithActions
Actions #1

Updated by Brett Smith 10 months ago

  • Blocked by Support #22864: Drop support for Ubuntu 20.04 and Debian 11 added
Actions #2

Updated by Peter Amstutz 10 months ago

  • Target version set to Development 2025-07-09
Actions #3

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-07-09 to Development 2025-07-23
Actions #4

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-07-23 to Development 2025-07-09
Actions #5

Updated by Brett Smith 10 months ago

  • Release set to 79
  • Description updated (diff)
Actions #6

Updated by Brett Smith 9 months ago

  • Release deleted (79)
  • Target version deleted (Development 2025-07-09)
Actions #7

Updated by Brett Smith 9 months ago

  • Release set to 79
Actions #8

Updated by Brett Smith 7 months ago

  • Description updated (diff)
  • Subject changed from Upgrade to Rails 7.1.5.1 to Upgrade Gemfile pins for Ruby 2.7→3.0
Actions #9

Updated by Brett Smith 7 months ago

  • Tracker changed from Feature to Support
Actions #10

Updated by Tom Clegg 7 months ago

  • Target version set to Development 2025-09-03
  • Assigned To set to Tom Clegg
  • Status changed from New to In Progress
Actions #11

Updated by Tom Clegg 7 months ago

Update source:services/api Update source:sdk/ruby and source:sdk/cli
  • 22920-update-gem-pins @ 5c69a9b4a55d093fde167de7d5f83107b1044f31 -- developer-run-tests: #4867
  • Is it best for our gems to declare minimum Ruby 3.0.0 to avoid problems with transitive dependencies and express that we no longer test with 2.7.0? Or leave it at 2.7.0 so it's still possible to install on 2.7.0 if you manage any transitive dependency problems yourself?
  • There's an oj version pin caused by sso-provider being in arvbox, and that's not a thing any more, so I think it's quite safe to remove that version pin entirely.

(edit: nvm, see note below)

Actions #12

Updated by Tom Clegg 7 months ago

  • Subtask #23135 added
Actions #13

Updated by Tom Clegg 7 months ago

Rebased to main (#note-11 was accidentally based on an unmerged branch)

Plus a commit updating the minimum Ruby version to 2.7.3 in arvados.gemspec and arvados-cli.gemspec.
  • This makes our gems compatible with activesupport 7.1.5.2 (versions >=7.1.4 require 2.7.3, versions >=7.2 require Ruby 3.1)
  • We can't update source:services/api/Gemfile.lock to take advantage of that until we publish an arvados gem with an updated dependency (i.e., this commit), so arvados-api-server is still at Rails 7.1.3.4
  • Also unpin oj in arvados-cli -- it was pinned for compatibility with Ruby 2.4 and sso-provider, both of which are ancient history
  • 22920-update-gem-pins @ 12d7965049298185b04898dad98a1b418f9a1fdc
  • developer-run-tests: #4871
  • build-publish-packages-python-ruby: #99 (looks like this jenkins job is a little broken atm: cannot open /home/jenkins/tmp/VENV3DIR/bin/activate: No such file)
Actions #14

Updated by Brett Smith 7 months ago

Tom Clegg wrote in #note-11:

  • Is it best for our gems to declare minimum Ruby 3.0.0 to avoid problems with transitive dependencies and express that we no longer test with 2.7.0? Or leave it at 2.7.0 so it's still possible to install on 2.7.0 if you manage any transitive dependency problems yourself?

Open to discussing this but I vote the former. I think we should allow ourselves to use features in the oldest version of interpreted languages we support. Bumping the version dependency now declares our intent even before we actually do it and prevents problems of "we used a new feature but forgot to update the metadata."

This is basically how we're handling Python. See #23097. (Python is a little better because pip install has an --ignore-requires-python option if you want to be clever.)

  • There's an oj version pin caused by sso-provider being in arvbox, and that's not a thing any more, so I think it's quite safe to remove that version pin entirely.

Sounds good to me, thanks.

Actions #15

Updated by Brett Smith 7 months ago

Tom Clegg wrote in #note-13:

It was running on an unexpected node type. Updated the config, please try again.

Actions #16

Updated by Tom Clegg 7 months ago

22920-update-gem-pins @ 17afcb1565c828028af3969de0308b26c0cd68fd -- developer-run-tests: #4872 If these changes look good, next steps are
  1. Publish arvados-google-api-client 0.8.7.13 from this branch
  2. Publish arvados, arvados-cli, arvados-login-sync 3.2.0rc1 from this branch
  3. Run bundle update again so services/api/Gemfile.lock picks up the rc gems and the third party dependency updates unblocked by the rc gems
  4. Run tests and build-packages-multijob again to test against all the new dependencies
  5. Merge to main
Actions #17

Updated by Brett Smith 7 months ago

Tom Clegg wrote in #note-16:

22920-update-gem-pins @ 17afcb1565c828028af3969de0308b26c0cd68fd -- developer-run-tests: #4872

These test failures look relevant. I'll look at the branch in parallel but if you could please investigate, definitely I'd want to see these passing, or at least an explanation of how the proposed process will get us there.

Actions #18

Updated by Tom Clegg 7 months ago

Brett Smith wrote in #note-17:

These test failures look relevant. I'll look at the branch in parallel but if you could please investigate, definitely I'd want to see these passing, or at least an explanation of how the proposed process will get us there.

Yes, this is relevant. Tests passed for me locally because I didn't delete Gemfile.lock. (Is there any reason we shouldn't rm Gemfile.lock etc. before gem install in run-tests.sh?)

Actions #19

Updated by Tom Clegg 7 months ago

22920-update-gem-pins @ 6a0ad473aec997dac50f799001460a031f9ed144
Actions #20

Updated by Brett Smith 7 months ago

  • Target version changed from Development 2025-09-03 to Development 2025-09-17
Actions #21

Updated by Brett Smith 7 months ago

Tom Clegg wrote in #note-19:

22920-update-gem-pins @ 6a0ad473aec997dac50f799001460a031f9ed144

Functionally this looks pretty good. I appreciate you doing such a complete audit. I found it difficult to understand how some of the comments related to some of the pins, especially when they start talking about much older Rubies like 2.4.

What do you think about standardizing our comments on a template like:

[GEM] dropped Ruby [VERSION] in [major|minor|patch] release [VERSION].

The Ruby version mentioned should be no newer than the oldest Ruby we support. And then we have a shared understanding that the [major|minor|patch] part tells you how specific we want to make the pin to prevent future headaches. (We should document that shared understanding somewhere. I'm not sure where.)

e.g., "Rails 7.2.x releases require Ruby >= 3.1.0." becomes "Rails dropped Ruby 3.0 in minor release 7.2.0." And that explains why we pin the minor version ~> 7.1.3.

The comment can add more explanation after this if it's helpful but each one should start with this template, e.g.,

# launchy dropped Ruby 3.0 in minor release 3.1.0.
# They did not change metadata but stopped testing against it.

# securerandom dropped Ruby 3.0 in minor release 0.4.0.
# They did not announce this in the changelog or release notes.

Excepting the very weird cases like autoparse and extlib. I think we should understand that pins without comments exist because we directly depend on that API, as with retriable.

+  # public_suffix 6.0.0 dropped Ruby 2.7.
   s.add_runtime_dependency 'public_suffix', '~> 5.0'

Why aren't we updating this pin to allow at least some of the 6.x series then?

Thanks.

Actions #22

Updated by Tom Clegg 7 months ago

Brett Smith wrote in #note-21:

Functionally this looks pretty good. I appreciate you doing such a complete audit. I found it difficult to understand how some of the comments related to some of the pins, especially when they start talking about much older Rubies like 2.4.

I was trying to express the rationale for choosing a major/minor/patchlevel pin for the gems whose latest version still supports Ruby 3.0. If a gem has a history of dropping Rubies at a non-zero minor, but not at a non-zero patchlevel, then we should pin to the latest minor version.

What do you think about standardizing our comments on a template like:

[GEM] dropped Ruby [VERSION] in [major|minor|patch] release [VERSION].

That's what I was going for, except I thought "[gem] [gemversion] dropped Ruby [rubyversion]" was easier to read.

The Ruby version mentioned should be no newer than the oldest Ruby we support.

Yes, except where the gem currently supports 3.0, in which case (I think) it's still worth expressing why we chose major/minor/patchlevel, and the fact that Ruby version support is the reason for the pin.

And then we have a shared understanding that the [major|minor|patch] part tells you how specific we want to make the pin to prevent future headaches. (We should document that shared understanding somewhere. I'm not sure where.)

Same.

e.g., "Rails 7.2.x releases require Ruby >= 3.1.0." becomes "Rails dropped Ruby 3.0 in minor release 7.2.0." And that explains why we pin the minor version ~> 7.1.3.

I've fixed this one to use the same format as the others.

Excepting the very weird cases like autoparse and extlib. I think we should understand that pins without comments exist because we directly depend on that API, as with retriable.

I think it's worth noting known API incompatibilities, because it's quite common for major releases to remain API-compatible. Arguably, the ideal gem maintains API compatibility forever but increases the major version when dropping support for a Ruby version. If we note known API changes, we can skip re-learning that when looking for API-compatible updates, e.g., when we no longer support Ruby 3.0.

Why aren't we updating this pin to allow at least some of the 6.x series then?

Oops, fixed.

22920-update-gem-pins @ fbbc5228582a4aa1b1a37ad9baf42a5216d49d6b
Actions #23

Updated by Brett Smith 7 months ago

I get the sense that we're not 100% aligned on how to handle the specific case of "gem has dropped support for one of our Rubies in the past but currently supports all our current Rubies" and I can't tell if we're misaligned on how we should actually pin it or just how we should document it. Let me talk it through with the understanding that it could be either.

That's what I was going for, except I thought "[gem] [gemversion] dropped Ruby [rubyversion]" was easier to read.

I'm not too fussed about the word order, that's fine, but I do feel like the explicit [major|minor|patch] callout helps explain why the pin is written a certain way. In other words, it addresses this:

Yes, except where the gem currently supports 3.0, in which case (I think) it's still worth expressing why we chose major/minor/patchlevel, and the fact that Ruby version support is the reason for the pin.

You're basically already spelling it out any time it's necessary so it seems like it might as well become part of the template. At least for minor or patch releases. For example:

+  # faraday 2.13.4 supported Ruby 3.0. Support for Ruby 2.7 was
+  # dropped in a minor version (2.9.0).

Could just become "faraday minor version 2.9.0 dropped Ruby 2.7." And then we just have a shared understanding that we're pinning ~> 2.13.0 because at the time that was the latest version that supported all of our Rubies. Ditto for all the changed comments in services/api/Gemfile.

To get really concrete, with the lack of callout, there are some pins that, given the comment, I would expect a different pin. And so this is where I'm wondering about the misalignment.

+  # googleauth 1.14.0 dropped Ruby 2.
+  s.add_runtime_dependency 'googleauth', '~> 1.15'

Since apparently a minor version dropped a Ruby, I would expect to pin the minor version ~> 1.15.0. Analogously here:

+  # kramdown 2.5.0 dropped Ruby 2.4.
+  s.add_development_dependency 'kramdown', '>= 1.5', '< 3'

I've fixed this one to use the same format as the others.

I am not seeing this change in the branch as pushed.

Actions #24

Updated by Tom Clegg 7 months ago

Fixed a couple of pins:
  • kramdown < 2.6. I had < 3.0 before, because although it dropped 2.4 in a minor release, it still supports Rubies so old even we don't care about them, and I figured it will probably continue to do so. Also, it's only a development dependency. But yes, avoiding 2.6 is more cautious and consistent.
  • googleauth < 1.16.

Added a comment about pinning minor versions when previous minor versions have dropped support for a Ruby version.

Added "gem x.y is the highest minor version we've tested" comments in cases where the only reason for a minor version pin is that the gem has previously dropped a Ruby at a minor version.

I am not seeing this change in the branch as pushed.

Oops, actually pushed my latest commit this time.

One more commit with only comments changed in services/api/Gemfile.
Actions #25

Updated by Tom Clegg 7 months ago

build-publish-packages-python-ruby: #102 failed. The warning about stringio is probably not causing the failure. (The same warning appears when building the gems, which succeeds anyway.)

======= Start upload ruby gems
2025-09-03 16:58:33 arvados-dev.upload.gems[1497] INFO: Uploading /tmp/workspace/build-publish-packages-python-ruby/sdk/ruby/arvados-3.2.0rc1.gem
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
      stringio (>= 0)
      Available/installed versions of this gem:
      - 3.1.5
      - 3.0.1.2
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
Traceback (most recent call last):
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 356, in <module>
    main(sys.argv[1:])
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 352, in main
    build_suite_and_upload(target, last_upload_ts, args)
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 342, in build_suite_and_upload
    suite.update_packages(since_timestamp)
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 115, in update_packages
    self.upload_files(upload_paths)
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 107, in upload_files
    self.upload_file(path)
  File "/tmp/workspace/build-publish-packages-python-ruby@tmp/tmp.OdB0FASjmC/jenkins/run_upload_packages.py", line 160, in upload_file
    raise subprocess.CalledProcessError(push_returncode, cmd)
subprocess.CalledProcessError: Command '['gem', 'push', '/tmp/workspace/build-publish-packages-python-ruby/sdk/ruby/arvados-3.2.0rc1.gem']' returned non-zero exit status 1.
======= upload ruby gems -- FAILED
Actions #27

Updated by Brett Smith 7 months ago

Tom Clegg wrote in #note-16:

  1. Publish arvados, arvados-cli, arvados-login-sync 3.2.0rc1 from this branch
  2. Run bundle update again so services/api/Gemfile.lock picks up the rc gems and the third party dependency updates unblocked by the rc gems
  3. Run tests and build-packages-multijob again to test against all the new dependencies

22920-update-gem-pins @ 079990b7f0956ec52b8092537b55f9da0d13d1c9
developer-run-tests: #4876
build-packages-multijob: #4826

Actions #28

Updated by Brett Smith 7 months ago

  • Status changed from In Progress to Resolved
Actions

Also available in: Atom PDF