Skip to content

[Feature Request] Allow changing Rubygems version #228

Closed

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

  1. 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.

  2. 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.

  3. 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: ruby/rubygems#4976 / Solution: ruby/rubygems#4976 (comment)

  4. 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.

  5. 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.

  6. 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: ruby/rubygems#5177 (review)

  7. 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.

  8. 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.

  9. 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.

  10. 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...

  11. 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).

  12. 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.

  13. 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.

  14. deivid-rodriguez commented on Jan 21, 2022

    @deivid-rodriguez
    Contributor

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

  15. eregon commented on Jan 23, 2022

    @eregon
    Member
  16. 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

      Issue actions