From 4e1189c53d558b920b51b4cdb7161205ddb7b274 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Tue, 26 Jul 2022 20:28:07 +0200 Subject: [PATCH] Use the Bundler shipped with that Ruby by default * Fixes https://github.com/ruby/setup-ruby/issues/358 --- README.md | 9 +++++--- action.yml | 8 ++++--- bundler.js | 50 ++++++++++++++++++++--------------------- common.js | 10 ++++++++- dist/index.js | 62 ++++++++++++++++++++++++++++----------------------- index.js | 2 +- 6 files changed, 79 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index a4bf0e4..3af7db3 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,12 @@ should be able to fix them by setting `rubygems: 3.0.0` or higher. ### Bundler -By default, if there is a `Gemfile.lock` file (or `$BUNDLE_GEMFILE.lock` or `gems.locked`) with a `BUNDLED WITH` section, -that version of Bundler will be installed and used. -Otherwise, the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.4, Bundler 1 on Ruby < 2.4). +By default, Bundler is installed as follows: + +* If there is a `Gemfile.lock` file (or `$BUNDLE_GEMFILE.lock` or `gems.locked`) with a `BUNDLED WITH` section, + that version of Bundler will be installed and used. +* If the Ruby ships with Bundler (as a default gem), that version is used. +* Otherwise, the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.4, Bundler 1 on Ruby < 2.4). This behavior can be customized, see [action.yml](action.yml) for more details about the `bundler` input. diff --git a/action.yml b/action.yml index f64a994..c5ade60 100644 --- a/action.yml +++ b/action.yml @@ -16,9 +16,11 @@ inputs: Similarly, if a version number is given, `gem update --system ` is run to update to that version of RubyGems, as long as that version is newer than the one provided by default. bundler: description: | - The version of Bundler to install. Either 'none', 'latest', 'Gemfile.lock', or a version number (e.g., 1, 2, 2.1, 2.1.4). - For 'Gemfile.lock', the version is determined based on the BUNDLED WITH section from the file Gemfile.lock, $BUNDLE_GEMFILE.lock or gems.locked. - Defaults to 'default', which means 'Gemfile.lock' if the file exists and 'latest' otherwise. + The version of Bundler to install. Either 'Gemfile.lock' (the default), 'default', 'latest', 'none', or a version number (e.g., 1, 2, 2.1, 2.1.4). + For 'Gemfile.lock', the version of the BUNDLED WITH section from the Gemfile.lock if it exists. If the file or section does not exist then the same as 'default'. + For 'default', the version of Bundler that comes with that Ruby by default is used, or if that Ruby comes without Bundler then the same as 'latest'. + For 'latest', the latest compatible Bundler version is installed (Bundler 2 on Ruby >= 2.4, Bundler 1 on Ruby < 2.4). + For 'none', nothing is done. bundler-cache: description: 'Run "bundle install", and cache the result automatically. Either true or false.' default: 'false' diff --git a/bundler.js b/bundler.js index d28e114..adc9673 100644 --- a/bundler.js +++ b/bundler.js @@ -53,15 +53,29 @@ async function afterLockFile(lockFile, platform, engine, rubyVersion) { export async function installBundler(bundlerVersionInput, rubygemsInputSet, lockFile, platform, rubyPrefix, engine, rubyVersion) { let bundlerVersion = bundlerVersionInput - if (rubygemsInputSet && bundlerVersion === 'default') { + if (rubygemsInputSet && (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock')) { console.log('Using the Bundler installed by updating RubyGems') return 'unknown' } - if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { - bundlerVersion = readBundledWithFromGemfileLock(lockFile) + if (bundlerVersion === 'Gemfile.lock') { + let bundlerVersionFromGemfileLock = readBundledWithFromGemfileLock(lockFile) - if (!bundlerVersion) { + if (bundlerVersionFromGemfileLock) { + bundlerVersion = bundlerVersionFromGemfileLock + } else { + bundlerVersion = 'default' + } + } + + if (bundlerVersion === 'default') { + if (common.isBundler2Default(engine, rubyVersion)) { + console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`) + return '2' + } else if (common.isBundler1Default(engine, rubyVersion)) { + console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion}`) + return '1' + } else { bundlerVersion = 'latest' } } @@ -92,30 +106,14 @@ export async function installBundler(bundlerVersionInput, rubygemsInputSet, lock } } - // Workaround for truffleruby 22.0 + latest Bundler, use shipped Bundler instead: https://github.com/oracle/truffleruby/issues/2586 - const truffleruby22workaround = engine.startsWith('truffleruby') && rubyVersion.startsWith('22.0') - const useShippedBundler2 = common.isHeadVersion(rubyVersion) || truffleruby22workaround + const gem = path.join(rubyPrefix, 'bin', 'gem') + // Workaround for https://github.com/rubygems/rubygems/issues/5245 + const force = (platform.startsWith('windows-') && engine === 'ruby' && floatVersion >= 3.1) ? ['--force'] : [] - if (useShippedBundler2 && common.isBundler2Default(engine, rubyVersion) && bundlerVersion.startsWith('2')) { - // Avoid installing a newer Bundler version for head versions as it might not work. - // For releases, even if they ship with Bundler 2 we install the latest Bundler. - if (truffleruby22workaround) { - console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion} (workaround for https://github.com/oracle/truffleruby/issues/2586 on truffleruby 22.0)`) - } else { - console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion} (head versions do not always support the latest Bundler release)`) - } - } else if (engine.startsWith('truffleruby') && common.isBundler1Default(engine, rubyVersion) && bundlerVersion.startsWith('1')) { - console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion} (required for truffleruby < 21.0)`) - } else { - const gem = path.join(rubyPrefix, 'bin', 'gem') - // Workaround for https://github.com/rubygems/rubygems/issues/5245 - const force = (platform.startsWith('windows-') && engine === 'ruby' && floatVersion >= 3.1) ? ['--force'] : [] + const versionParts = [...bundlerVersion.matchAll(/\d+/g)].length + const bundlerVersionConstraint = versionParts === 3 ? bundlerVersion : `~> ${bundlerVersion}.0` - const versionParts = [...bundlerVersion.matchAll(/\d+/g)].length - const bundlerVersionConstraint = versionParts === 3 ? bundlerVersion : `~> ${bundlerVersion}.0` - - await exec.exec(gem, ['install', 'bundler', ...force, '-v', bundlerVersionConstraint]) - } + await exec.exec(gem, ['install', 'bundler', ...force, '-v', bundlerVersionConstraint]) return bundlerVersion } diff --git a/common.js b/common.js index 0c87a76..aa24aee 100644 --- a/common.js +++ b/common.js @@ -56,7 +56,15 @@ export function isStableVersion(rubyVersion) { } export function isBundler1Default(engine, rubyVersion) { - return !isBundler2Default(engine, rubyVersion) + if (engine === 'ruby') { + return floatVersion(rubyVersion) >= 2.6 && floatVersion(rubyVersion) < 2.7 + } else if (engine.startsWith('truffleruby')) { + return floatVersion(rubyVersion) < 21.0 + } else if (engine === 'jruby') { + return false + } else { + return false + } } export function isBundler2Default(engine, rubyVersion) { diff --git a/dist/index.js b/dist/index.js index 9a16fef..a2b9860 100644 --- a/dist/index.js +++ b/dist/index.js @@ -67,15 +67,29 @@ async function afterLockFile(lockFile, platform, engine, rubyVersion) { async function installBundler(bundlerVersionInput, rubygemsInputSet, lockFile, platform, rubyPrefix, engine, rubyVersion) { let bundlerVersion = bundlerVersionInput - if (rubygemsInputSet && bundlerVersion === 'default') { + if (rubygemsInputSet && (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock')) { console.log('Using the Bundler installed by updating RubyGems') return 'unknown' } - if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { - bundlerVersion = readBundledWithFromGemfileLock(lockFile) + if (bundlerVersion === 'Gemfile.lock') { + let bundlerVersionFromGemfileLock = readBundledWithFromGemfileLock(lockFile) - if (!bundlerVersion) { + if (bundlerVersionFromGemfileLock) { + bundlerVersion = bundlerVersionFromGemfileLock + } else { + bundlerVersion = 'default' + } + } + + if (bundlerVersion === 'default') { + if (common.isBundler2Default(engine, rubyVersion)) { + console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`) + return '2' + } else if (common.isBundler1Default(engine, rubyVersion)) { + console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion}`) + return '1' + } else { bundlerVersion = 'latest' } } @@ -106,30 +120,14 @@ async function installBundler(bundlerVersionInput, rubygemsInputSet, lockFile, p } } - // Workaround for truffleruby 22.0 + latest Bundler, use shipped Bundler instead: https://github.com/oracle/truffleruby/issues/2586 - const truffleruby22workaround = engine.startsWith('truffleruby') && rubyVersion.startsWith('22.0') - const useShippedBundler2 = common.isHeadVersion(rubyVersion) || truffleruby22workaround + const gem = path.join(rubyPrefix, 'bin', 'gem') + // Workaround for https://github.com/rubygems/rubygems/issues/5245 + const force = (platform.startsWith('windows-') && engine === 'ruby' && floatVersion >= 3.1) ? ['--force'] : [] - if (useShippedBundler2 && common.isBundler2Default(engine, rubyVersion) && bundlerVersion.startsWith('2')) { - // Avoid installing a newer Bundler version for head versions as it might not work. - // For releases, even if they ship with Bundler 2 we install the latest Bundler. - if (truffleruby22workaround) { - console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion} (workaround for https://github.com/oracle/truffleruby/issues/2586 on truffleruby 22.0)`) - } else { - console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion} (head versions do not always support the latest Bundler release)`) - } - } else if (engine.startsWith('truffleruby') && common.isBundler1Default(engine, rubyVersion) && bundlerVersion.startsWith('1')) { - console.log(`Using Bundler 1 shipped with ${engine}-${rubyVersion} (required for truffleruby < 21.0)`) - } else { - const gem = path.join(rubyPrefix, 'bin', 'gem') - // Workaround for https://github.com/rubygems/rubygems/issues/5245 - const force = (platform.startsWith('windows-') && engine === 'ruby' && floatVersion >= 3.1) ? ['--force'] : [] + const versionParts = [...bundlerVersion.matchAll(/\d+/g)].length + const bundlerVersionConstraint = versionParts === 3 ? bundlerVersion : `~> ${bundlerVersion}.0` - const versionParts = [...bundlerVersion.matchAll(/\d+/g)].length - const bundlerVersionConstraint = versionParts === 3 ? bundlerVersion : `~> ${bundlerVersion}.0` - - await exec.exec(gem, ['install', 'bundler', ...force, '-v', bundlerVersionConstraint]) - } + await exec.exec(gem, ['install', 'bundler', ...force, '-v', bundlerVersionConstraint]) return bundlerVersion } @@ -325,7 +323,15 @@ function isStableVersion(rubyVersion) { } function isBundler1Default(engine, rubyVersion) { - return !isBundler2Default(engine, rubyVersion) + if (engine === 'ruby') { + return floatVersion(rubyVersion) >= 2.6 && floatVersion(rubyVersion) < 2.7 + } else if (engine.startsWith('truffleruby')) { + return floatVersion(rubyVersion) < 21.0 + } else if (engine === 'jruby') { + return false + } else { + return false + } } function isBundler2Default(engine, rubyVersion) { @@ -65624,7 +65630,7 @@ const windows = common.windows const inputDefaults = { 'ruby-version': 'default', 'rubygems': 'default', - 'bundler': 'default', + 'bundler': 'Gemfile.lock', 'bundler-cache': 'false', 'working-directory': '.', 'cache-version': bundler.DEFAULT_CACHE_VERSION, diff --git a/index.js b/index.js index 3644c56..12a5289 100644 --- a/index.js +++ b/index.js @@ -12,7 +12,7 @@ const windows = common.windows const inputDefaults = { 'ruby-version': 'default', 'rubygems': 'default', - 'bundler': 'default', + 'bundler': 'Gemfile.lock', 'bundler-cache': 'false', 'working-directory': '.', 'cache-version': bundler.DEFAULT_CACHE_VERSION,