Skip to content

[Feature Request] Allow changing Rubygems version #228

@ashmaroli

Description

@ashmaroli

Currently, if I were to run a job using Ruby 2.4 and Rubygems 2.x, I'm locked to rubygems-2.6.14.4.
If there's a gem that requires Rubygems 2.7 (for security reasons), bundle install fails, forcing me to abandon the bundle-cache provided by this action.

I would therefore like to have a way to update to rubygems-2.7.11. Under the hood, it would be a system call to

gem update --system --version="~> 2.7"

Activity

dentarg

dentarg commented on Jan 9, 2022

@dentarg

Maybe it makes sense to ensure at least RubyGems 2.7.11 in setup-ruby? RubyGems 2.7.11 seems to work all the way back to Ruby 1.9.

eregon

eregon commented on Jan 9, 2022

@eregon
Member

I dislike updating RubyGems, for many reasons, #224 (comment) and https://eregon.me/blog/2020/01/13/a-migration-path-to-bundler2.html#the-rubygems-requirement-of-bundler-2.
So I don't want to update RubyGems automatically in setup-ruby.

But of course if people want to update to a given RubyGems version, then that's fine as it's their explicit choice.
Will be solved when the caching is a separate action.

Jack12816

Jack12816 commented on Jan 10, 2022

@Jack12816

Maybe it could be turned on as a boolean input? The default could be off.

Currently, I'm getting this issue for a vanilla 2.5 build:

    steps:
      - uses: actions/checkout@v2

      - name: Install the correct Ruby version
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true      
Run ruby/setup-ruby@v1
  with:
    ruby-version: 2.5
    bundler-cache: true
    bundler: default
    working-directory: .
    cache-version: 0
  env:
    BUNDLE_GEMFILE: gemfiles/rails_5.2.gemfile
Modifying PATH
  Entries added to PATH to use selected Ruby:
    /opt/hostedtoolcache/Ruby/2.5.9/x64/bin
Installing Bundler
  /opt/hostedtoolcache/Ruby/2.5.9/x64/bin/gem install bundler -v ~> 2
  Successfully installed bundler-2.3.4
  1 gem installed
  Took   2.67 seconds
bundle install
  /opt/hostedtoolcache/Ruby/2.5.9/x64/bin/bundle config --local path /home/runner/work/speechless/speechless/vendor/bundle
  Your RubyGems version (2.7.6.3)) has a bug that prevents `required_ruby_version` from working for Bundler. Any scripts that use `gem install bundler` will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running `gem update --system 3.2.3`
  /opt/hostedtoolcache/Ruby/2.5.9/x64/bin/bundle lock
  Your RubyGems version (2.7.6.3)) has a bug that prevents `required_ruby_version` from working for Bundler. Any scripts that use `gem install bundler` will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running `gem update --system 3.2.3`
  Fetching gem metadata from https://rubygems.org/.........
  Resolving dependencies......
  Writing lockfile to /home/runner/work/speechless/speechless/gemfiles/rails_5.2.gemfile.lock
  Cache key: setup-ruby-bundler-cache-v3-ubuntu-20.04-ruby-2.5.9-gemfiles/rails_5.2.gemfile.lock-6640afda389003171b0173cb5664e2bb9fd70fe81ca38702c61167c3128943cc
  Received 36089678 of 36089678 (100.0%), 93.0 MBs/sec
  Cache Size: ~34 MB (36089678 B)
  /usr/bin/tar --use-compress-program zstd -d -xf /home/runner/work/_temp/c16c2cfd-0e68-41b6-88f9-d93913fe8778/cache.tzst -P -C /home/runner/work/speechless/speechless
  Cache restored successfully
  Found cache for key: setup-ruby-bundler-cache-v3-ubuntu-20.04-ruby-2.5.9-gemfiles/rails_5.2.gemfile.lock-2d7b0aacca9f2622e377c39ab25ab5bbb66d79b740c44ef1225fe9131cd1bd76
  /opt/hostedtoolcache/Ruby/2.5.9/x64/bin/bundle install --jobs 4
  Your RubyGems version (2.7.6.3)) has a bug that prevents `required_ruby_version` from working for Bundler. Any scripts that use `gem install bundler` will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running `gem update --system 3.2.3`
  Failed to load /home/runner/.gemrc, wrong number of arguments (given 2, expected 1)
  Fetching gem metadata from https://rubygems.org/........
  Using rake 10.5.0
  [..]

  --- ERROR REPORT TEMPLATE -------------------------------------------------------

  ArgumentError: wrong number of arguments (given 4, expected 1)
    /home/runner/work/speechless/speechless/vendor/bundle/ruby/2.5.0/gems/psych-4.0.3/lib/psych.rb:323:in `safe_load'
    /opt/hostedtoolcache/Ruby/2.5.9/x64/lib/ruby/2.5.0/rubygems/safe_yaml.rb:31:in `safe_load'
    /opt/hostedtoolcache/Ruby/2.5.9/x64/lib/ruby/2.5.0/rubygems/package.rb:496:in `block (2 levels) in read_checksums'
    /opt/hostedtoolcache/Ruby/2.5.9/x64/lib/ruby/2.5.0/rubygems/package.rb:495:in `wrap'
    [..]

  ## Environment

  Bundler       2.3.4
    Platforms   ruby, x86_64-linux
  Ruby          2.5.9p229 (2021-04-05 revision 67939) [x86_64-linux]
    Full Path   /opt/hostedtoolcache/Ruby/2.5.9/x64/bin/ruby
    Config Dir  /opt/hostedtoolcache/Ruby/2.5.9/x64/etc
  RubyGems      2.7.6.3
    Gem Home    /home/runner/work/speechless/speechless/vendor/bundle/ruby/2.5.0
    Gem Path    /home/runner/work/speechless/speechless/vendor/bundle/ruby/2.5.0
    User Home   /home/runner
    User Path   /home/runner/.gem/ruby/2.5.0
    Bin Dir     /home/runner/work/speechless/speechless/vendor/bundle/ruby/2.5.0/bin
  OpenSSL
    Compiled    OpenSSL 1.1.1f  31 Mar 2020
    Loaded      OpenSSL 1.1.1f  31 Mar 2020
    Cert File   /usr/lib/ssl/cert.pem
    Cert Dir    /usr/lib/ssl/certs
  Tools
    Git         2.34.1
    RVM         not installed
    rbenv       not installed
    chruby      not installed

Seems to be related: rubygems/rubygems#4976 / Solution: rubygems/rubygems#4976 (comment)

eregon

eregon commented on Jan 10, 2022

@eregon
Member

@Jack12816 That sounds like your Gemfile includes Psych 4 somehow, and the default RubyGems doesn't support it. Probably going to run into more issues by trying to use recent gems + old Ruby.
For now the workaround is to not use bundler-cache: true if you need to update RubyGems.

Jack12816

Jack12816 commented on Jan 10, 2022

@Jack12816

Mhh, yeah looks like psych 4 is required by rdoc 6.4. This is then also related to not having a cached/in-repo-stored Gemfile.lock for our gem repo, which is fine from my point of view. The most convenient solution is then to drop support for ruby 2.5.

But this should be reflected by this gh action, too? Why should it allow to install ruby 2.5 (or earlier) when it is obviously broken by the bundled rubygems from back then when there is an official update available with support for the language version?

The latest RubyGems version 3.3.4 is compatible with Ruby >=2.3. So sounds safe to use it, because we could rely on this information also provided by other gems.

eregon

eregon commented on Jan 10, 2022

@eregon
Member

That RubyGems is in general not broken and works for plenty of CI workflows, and it is the RubyGems version you would get when you install Ruby 2.5, so IMHO the only sane default.

Regarding

Your RubyGems version (2.7.6.3)) has a bug that prevents required_ruby_version from working for Bundler. Any scripts that use gem install bundler will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running gem update --system 3.2.3

One way to silence this warning is to use Bundler < 2.3.0 on those older Rubies: rubygems/rubygems#5177 (review)

deivid-rodriguez

deivid-rodriguez commented on Jan 12, 2022

@deivid-rodriguez
Contributor

I think a rubygems: default, latest, <version> input would fit everyone's needs and opinions, and it seems reasonably simple to implement and maintain inside this action. The default can still be rubygems: default so that nothing needs to change by default and @eregon can keep his opinionated view as the maintainer of this action.

From the RubyGems and Bundler maintainers side, 100% of rubygems tests are run against all supported rubies, so the use case of updating rubygems on an old Ruby is a 100% supported scenario.

MSP-Greg

MSP-Greg commented on Jan 12, 2022

@MSP-Greg
Collaborator

@deivid-rodriguez

Thanks. I think many people would consider all of us to be opinionated. Somewhat related to age, along with terseness. JFYI, I'm old (60+, coded on teletypes, Apple II's, original IBM & Compaq PC's).

Anway, given the increasing integration between RubyGems & Bundler, I also think an option to update RG is needed. Issues like how it functions with Gemfile.lock need to be worked out.

Off-topic: Given that RubyGems & Bundler (and all of Ruby) are OSS, the idea that a full three dimensional matrix of Ruby/RubyGems/Bundler versions can be supported is somewhat nuts.

deivid-rodriguez

deivid-rodriguez commented on Jan 12, 2022

@deivid-rodriguez
Contributor

I looked for "opinionated" in the dictionary and I didn't use that word properly. Sincere apologies, I didn't mean it in an offensive way. I only wanted to state that this proposal would only be purely opt-in, and Eregon can still keep his opinion about not updating RubyGems being the best default.

MSP-Greg

MSP-Greg commented on Jan 12, 2022

@MSP-Greg
Collaborator

I looked for "opinionated" in the dictionary, Sincere apologies

None needed by me. I'm American, and what is considered 'harse' is messy with 'international' conversations.

not updating RubyGems being the best default.

What's your opinion? I consider yours to be one of the best (if not the best) informed...

eregon

eregon commented on Jan 12, 2022

@eregon
Member

No worries, I read it as "opiniated" and thought that just means based on some opinions but apparently that's not a word.
Anyway, I agree we need a way to let people update RubyGems + use the bundler cache.

The reason to not just add that option now is this bigger design, which I think is much more flexible:
Create a new action like ruby/cache-gems or ruby/setup-bundle or ruby/bundle-install or so, and then one can run arbitrary commands/things in between:

    - uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.0
    - run: gem update --system
    - run: bundle config ...
    - ...
    - uses: ruby/bundle-install@v1
      with:
        bundler: version (optional)

This gives the full flexibility in between, including the full shell support from GitHub Actions, and it clearly separates the concerns. It also supports multiple gemfiles, multiple caches in a single job, etc.
The only disadvantage I see it that it's a bit more verbose, but we'd keep bundler-cache: true in setup-ruby for compatibility (at least for a while).
I'd like to avoid having more rubygems/bundler specifics in this github action (IMHO it's already too much, notably all the logic to find a good Bundler version based on various criteria).

deivid-rodriguez

deivid-rodriguez commented on Jan 12, 2022

@deivid-rodriguez
Contributor

What's your opinion? I consider yours to be one of the best (if not the best) informed...

Well, as a RubyGems maintainer I obviously prefer if people use the latest version and benefit from my work. But I think a "rolling version" is not a good default, because CI environments should be as frozen as possible. So I would either use the default version that comes with each Ruby (like done now), or an upgraded but fixed version as a default.

To be honest, what I like the most about this action is how it satisfies almost all use cases of setting up Ruby in a CI environment, with little to no configuration. I have migrated dozens of repositories from TravisCI and other systems to GitHub Actions, and I hardly ever encounter issues except for hitting RubyGems bugs on old rubies. That's why I believe a configuration to select the desired RubyGems version is the missing piece in this action, and there's no need to split it into different actions. I don't think the bundle config commands are needed in most cases, because Bundler supports configuration through ENV and GitHub Actions is very flexible regarding setting ENV.

Recent RubyGems and Bundler versions are able to automatically install the proper version of Bundler itself, so if this action shipped with a recent enough RubyGems version, all the logic to find a good Bundler version could just go.

All that said, I just realized that since TruffleRuby does not support upgrading RubyGems, it might get confusing if this gets added because people will expect it to work for their whole matrix, including TruffleRuby.

eregon

eregon commented on Jan 14, 2022

@eregon
Member

So I would either use the default version that comes with each Ruby (like done now), or an upgraded but fixed version as a default.

I'm happy we agree on "always latest RubyGems" is not ideal for a CI default :)

All that said, I just realized that since TruffleRuby does not support upgrading RubyGems, it might get confusing if this gets added because people will expect it to work for their whole matrix, including TruffleRuby.

It's possible to upgrade RubyGems in TruffleRuby with an extra flag to force it, but it takes quite some time (I'd need to check again), which I think most people would want to avoid in CI, and there is a potential risk the newer RubyGems doesn't work. OTOH the RubyGems in TruffleRuby is typically already fairly recent.
I remember TravisCI updating RubyGems when not asked to and that breaking both some CRuby versions and TruffleRuby, in addition to slowing things down, but that was a long time ago.


Right, it seems kind of nice to be able to use a single action if the only extra thing is updating RubyGems.
And to be fair updating RubyGems is not hard to implement (much simpler than handling the Bundler version), since it's just one command with an optional version argument.

I don't think the bundle config commands are needed in most cases, because Bundler supports configuration through ENV and GitHub Actions is very flexible regarding setting ENV.

There are two sides to this:

  • Setting through ENV is more efficient (a lot more on JRuby/TruffleRuby, starting a bundler process just to set that is significant overhead), and since the env is/should be on the job level it's also clear it applies to the whole job which is good. It's also clearly shown on each step by the UI. (bundle config key value is still global IIRC which is probably not what people intend in most cases).
  • OTOH setting it via bundle config is what people are used to and they can just copy/paste commands they do locally.

Related: #239

So let's go with #228 (comment).
PR welcome if anyone wants to contribute, otherwise it'll be when I have time.

deivid-rodriguez

deivid-rodriguez commented on Jan 21, 2022

@deivid-rodriguez
Contributor

I went ahead and gave this a try at #271!

eregon

eregon commented on Jan 23, 2022

@eregon
Member
ashmaroli

ashmaroli commented on Jan 23, 2022

@ashmaroli
Author

Thank you very much @deivid-rodriguez and @eregon :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @dentarg@eregon@Jack12816@deivid-rodriguez@ashmaroli

        Issue actions

          [Feature Request] Allow changing Rubygems version · Issue #228 · ruby/setup-ruby