name: install-rubygems

on:
  pull_request:

  push:
    branches:
      - 3.5

concurrency:
  group: ci-${{ github.ref }}-${{ github.workflow }}
  cancel-in-progress: true

permissions:  # added using https://github.com/step-security/secure-workflows
  contents: read

jobs:
  install_rubygems_ubuntu:
    name: Install Rubygems on Ubuntu (${{ matrix.ruby.name }}, ${{ matrix.openssl.name }})
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        ruby:
          - { name: "3.0", value: 3.0.7 }
          - { name: "3.1", value: 3.1.6 }
          - { name: "3.2", value: 3.2.6 }
          - { name: "3.3", value: 3.3.5 }
          - { name: jruby, value: jruby-9.4.8.0 }
          - { name: truffleruby, value: truffleruby-24.0.1 }
        openssl:
          - { name: "openssl", value: true }
          - { name: "no-openssl", value: false }
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - name: Setup ruby
        uses: ruby/setup-ruby@7d3497fd78c07c0d84ebafa58d8dac60cd1f0763 # v1.199.0
        with:
          ruby-version: ${{ matrix.ruby.value }}
          bundler: none
      - name: Check successful install without warnings
        run: |
          ruby -Ilib -S rake install 2> errors.txt || (cat errors.txt && exit 1)
          test ! -s errors.txt || (cat errors.txt && exit 1)
      - name: Check downgrading
        run: gem update --system 3.3.3
      - name: Check installing fileutils
        run: gem install fileutils
      - name: Check installing with upgraded fileutils
        run: |
          ruby -Ilib -S rake install 2> errors.txt || (cat errors.txt && exit 1)
          test ! -s errors.txt || (cat errors.txt && exit 1)
      - name: Run a local rubygems command
        run: gem list bundler
        env:
          RUBYOPT: -Itest/rubygems/fake_certlib
        if: matrix.openssl.value == false
      - name: Run a local rubygems command
        run: gem list bundler
        if: matrix.openssl.value == true
      - name: Run a remote rubygems command
        run: gem outdated
        if: matrix.openssl.value == true
      - name: Check commands in presence of a plugin that leaves unresolved dependencies print no warnings
        run: |
          gem install attempt:0.6.2 rspec:3.10.0 rspec:3.11.0
          mkdir -p tmp/plugin-home
          echo "require 'attempt'" > tmp/plugin-home/rubygems_plugin.rb
          RUBYOPT=-Itmp/plugin-home gem env version 2> errors.txt || (cat errors.txt && exit 1)
          test ! -s errors.txt || (cat errors.txt && exit 1)
          RUBYOPT=-Itmp/plugin-home gem install sys-admin:1.8.1 2> errors.txt || (cat errors.txt && exit 1)
          test ! -s errors.txt || (cat errors.txt && exit 1)
      - name: Run bundler installed as a default gem
        run: bundle --version
      - name: Check bundler man pages were installed and are properly picked up
        run: bundle install --help | grep -q BUNDLE-INSTALL
      - name: Check bundler fallback man pages are properly picked up
        run: sudo rm $(which man) && bundle install --help
      - name: Build bundler
        run: gem build bundler.gemspec
        working-directory: ./bundler
      - name: Install built bundler
        run: gem install bundler-*.gem --verbose --backtrace > output.txt
        working-directory: ./bundler
      - name: Check bundler install didn't hit the network
        run: if grep -q 'GET http' output.txt; then false; else true; fi
        working-directory: ./bundler
      - name: Check gem exec can create a rails project
        run: gem exec rails new app --minimal
        if: matrix.ruby.name != 'truffleruby' && matrix.ruby.name != 'jruby'
      - name: Check rails can be installed
        run: gem install rails --verbose --backtrace
      - name: Install and load a gem that defines a command as a plugin
        run: |
          gem install nexus:1.5.2
          gem nexus --help
    timeout-minutes: 10

  install_rubygems_windows:
    name: Install Rubygems on Windows (${{ matrix.ruby.name }})
    runs-on: windows-2022
    strategy:
      fail-fast: false
      matrix:
        ruby:
          - { name: "3.1", value: 3.1.6 }
          - { name: "3.2", value: 3.2.6 }
          - { name: "3.3", value: 3.3.5 }
          - { name: jruby-9.4, value: jruby-9.4.8.0, rails-args: "--skip-webpack-install" }
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - name: Setup ruby
        uses: ruby/setup-ruby@7d3497fd78c07c0d84ebafa58d8dac60cd1f0763 # v1.199.0
        with:
          ruby-version: ${{ matrix.ruby.value }}
          bundler: none
      - name: Setup java
        uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
        with:
          distribution: temurin
          java-version: 19.0.2
        if: startsWith(matrix.ruby.name, 'jruby')
      - name: Install rubygems
        run: ruby setup.rb
        shell: bash
      - name: Check installation didn't modify any source controlled files
        run: git add . && git diff --cached --exit-code
        shell: bash
      - name: Check we can install a Gemfile with git sources
        run: bundle init && bundle add fileutils --git https://github.com/ruby/fileutils
        shell: bash
      - name: Generate a Rails application
        run: gem install rails --version 7.0.8 && rails new foo ${{ matrix.ruby.rails-args }}
        shell: bash
      - name: Use gem installed in a bin dir different from where Ruby itself is installed
        run: gem install rspec --version 3.13.0 --install-dir foo && GEM_HOME=foo foo/bin/rspec --version
        shell: bash

    timeout-minutes: 20

  shared_gem_home:
    name: Handling issues with a shared gem home
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        rubygems:
          - dev
          - system
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - name: Setup original ruby
        uses: ruby/setup-ruby@7d3497fd78c07c0d84ebafa58d8dac60cd1f0763 # v1.199.0
        with:
          ruby-version: 3.2
          bundler: none
      - name: Save system RubyGems version to ENV
        run: |
          RGV=$(ruby -e 'puts Gem::VERSION.split(".")[0..2].join(".")')
          echo "RGV=v$RGV" >> $GITHUB_ENV
        if: matrix.rubygems == 'system'
      - name: Set dev RubyGems version
        run: |
          RGV=..
          echo "RGV=v$RGV" >> $GITHUB_ENV
        if: matrix.rubygems == 'dev'
      - name: Setup app depending on psych with initial Ruby
        run: mkdir foo && cd foo && ruby ../bundler/spec/support/bundle.rb init && ruby ../bundler/spec/support/bundle.rb add psych -v 5.1.2
        shell: bash
        env:
          GEM_HOME: bar
          GEM_PATH: bar
      - name: Setup final ruby
        uses: ruby/setup-ruby@7d3497fd78c07c0d84ebafa58d8dac60cd1f0763 # v1.199.0
        with:
          ruby-version: 3.3
          bundler: none
      - name: Install gems with final ruby, using GEM_HOME created by the other Ruby
        run: ruby ../bundler/spec/support/bundle.rb install
        working-directory: foo
        env:
          GEM_HOME: bar
          GEM_PATH: bar

    timeout-minutes: 20
