Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Allow changing Rubygems version #228

Closed
ashmaroli opened this issue Nov 8, 2021 · 16 comments
Closed

[Feature Request] Allow changing Rubygems version #228

ashmaroli opened this issue Nov 8, 2021 · 16 comments

Comments

@ashmaroli
Copy link

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"
@dentarg
Copy link

dentarg commented Jan 9, 2022

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
Copy link
Member

eregon commented Jan 9, 2022

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
Copy link

Jack12816 commented Jan 10, 2022

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
Copy link
Member

eregon commented Jan 10, 2022

@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
Copy link

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
Copy link
Member

eregon commented Jan 10, 2022

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
Copy link
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
Copy link
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
Copy link
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
Copy link
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
Copy link
Member

eregon commented Jan 12, 2022

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
Copy link
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
Copy link
Member

eregon commented Jan 14, 2022

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
Copy link
Contributor

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

@eregon
Copy link
Member

eregon commented Jan 23, 2022

#271 merged and released as https://github.com/ruby/setup-ruby/releases/tag/v1.93.0

@eregon eregon closed this as completed Jan 23, 2022
@ashmaroli
Copy link
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
Labels
None yet
Development

No branches or pull requests

6 participants