mirror of
https://github.com/ruby/setup-ruby.git
synced 2026-09-13 14:34:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
084885eaca | ||
|
|
efd6675fc9 | ||
|
|
e5a267414f | ||
|
|
cadade3366 | ||
|
|
d3562e70d9 | ||
|
|
23b2b5e5f1 | ||
|
|
42fc2d3bce | ||
|
|
30f5e2d4cd | ||
|
|
fd1d77b75c | ||
|
|
2a0be7a409 | ||
|
|
bacba738b2 | ||
|
|
21351ecc0a | ||
|
|
4d7e038419 | ||
|
|
e27aee156d | ||
|
|
43bb24d212 | ||
|
|
0c4183e8b8 | ||
|
|
50ae8432ea | ||
|
|
a699edbce6 | ||
|
|
e38f9abc9e |
@@ -17,20 +17,21 @@ jobs:
|
||||
matrix:
|
||||
os: [ ubuntu-16.04, ubuntu-18.04, ubuntu-20.04, macos-10.15, macos-11.0, windows-2016, windows-2019 ]
|
||||
# Use various version syntax here for testing
|
||||
ruby: [ 2.1, 2.2, 2.3, 2.4, 2.5, 2.6.6, 2.7, ruby-head, debug, jruby-9.1, jruby, jruby-head, truffleruby, truffleruby-head ]
|
||||
ruby: [ 2.1, 2.2, 2.3, 2.4, 2.5, 2.6.6, 2.7, '3.0', ruby-head, debug, jruby-9.1, jruby, jruby-head, truffleruby, truffleruby-head ]
|
||||
include:
|
||||
- { os: windows-2016, ruby: mingw }
|
||||
- { os: windows-2019, ruby: mingw }
|
||||
- { os: windows-2019, ruby: mswin }
|
||||
exclude:
|
||||
- { os: windows-2016, ruby: '3.0' }
|
||||
- { os: windows-2016, ruby: debug }
|
||||
- { os: windows-2016, ruby: truffleruby }
|
||||
- { os: windows-2016, ruby: truffleruby-head }
|
||||
- { os: windows-2019, ruby: '3.0' }
|
||||
- { os: windows-2019, ruby: debug }
|
||||
- { os: windows-2019, ruby: truffleruby }
|
||||
- { os: windows-2019, ruby: truffleruby-head }
|
||||
- { os: macos-11.0, ruby: truffleruby }
|
||||
- { os: macos-11.0, ruby: truffleruby-head }
|
||||
|
||||
name: ${{ matrix.os }} ${{ matrix.ruby }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -102,7 +103,7 @@ jobs:
|
||||
run: gem install sassc -N
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: yarn install
|
||||
|
||||
@@ -14,9 +14,9 @@ This action currently supports these versions of MRI, JRuby and TruffleRuby:
|
||||
|
||||
| Interpreter | Versions |
|
||||
| ----------- | -------- |
|
||||
| Ruby | 2.1.9, 2.2, 2.3.0 - 2.3.8, 2.4.0 - 2.4.10, 2.5.0 - 2.5.8, 2.6.0 - 2.6.6, 2.7.2, head, debug, mingw, mswin |
|
||||
| JRuby | 9.1.17.0, 9.2.9.0 - 9.2.13.0, head |
|
||||
| TruffleRuby | 19.3.0 - 20.2.0, head |
|
||||
| `ruby` | 2.1.9, 2.2, 2.3.0 - 2.3.8, 2.4.0 - 2.4.10, 2.5.0 - 2.5.8, 2.6.0 - 2.6.6, 2.7.2, head, debug, mingw, mswin |
|
||||
| `jruby` | 9.1.17.0, 9.2.9.0 - 9.2.13.0, head |
|
||||
| `truffleruby` | 19.3.0 - 20.3.0, head |
|
||||
|
||||
`ruby-debug` is the same as `ruby-head` but with assertions enabled (`-DRUBY_DEBUG=1`).
|
||||
On Windows, `mingw` and `mswin` are `ruby-head` builds using the MSYS2/MinGW and the MSVC toolchains respectively.
|
||||
@@ -85,7 +85,6 @@ jobs:
|
||||
os: [ubuntu, macos]
|
||||
ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ruby/setup-ruby@v1
|
||||
@@ -137,6 +136,23 @@ This caching speeds up installing gems significantly and avoids too many request
|
||||
It needs a `Gemfile` (or `$BUNDLE_GEMFILE` or `gems.rb`) under the [`working-directory`](#working-directory).
|
||||
If there is a `Gemfile.lock` (or `$BUNDLE_GEMFILE.lock` or `gems.locked`), `bundle config --local deployment true` is used.
|
||||
|
||||
To use a `Gemfile` which is not at the root or has a different name, set `BUNDLE_GEMFILE` in the `env` at the job level, so it is set for all steps:
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
BUNDLE_GEMFILE: subdir/mygemfile
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
bundler-cache: true
|
||||
- run: bundle exec rake
|
||||
```
|
||||
Of course you can also use a matrix of gemfiles if you need to test multiple gemfiles.
|
||||
|
||||
To perform caching, this action will use `bundle config --local path vendor/bundle`.
|
||||
Therefore, the Bundler `path` should not be changed in your workflow for the cache to work (no `bundle config path`).
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ export const windows = (os.platform() === 'win32')
|
||||
// Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14
|
||||
export const drive = (windows ? (process.env['GITHUB_WORKSPACE'] || 'C')[0] : undefined)
|
||||
|
||||
export function partition(string, separator) {
|
||||
const i = string.indexOf(separator)
|
||||
if (i === -1) {
|
||||
throw new Error(`No separator ${separator} in string ${string}`)
|
||||
}
|
||||
return [string.slice(0, i), string.slice(i + separator.length, string.length)]
|
||||
}
|
||||
|
||||
export async function measure(name, block) {
|
||||
return await core.group(name, async () => {
|
||||
const start = performance.now()
|
||||
@@ -32,6 +40,25 @@ export function isStableVersion(rubyVersion) {
|
||||
return /^\d+(\.\d+)*$/.test(rubyVersion)
|
||||
}
|
||||
|
||||
export function isBundler2Default(engine, rubyVersion) {
|
||||
if (engine === 'ruby') {
|
||||
return isHeadVersion(rubyVersion) || floatVersion(rubyVersion) >= 2.7
|
||||
} else if (engine === 'truffleruby') {
|
||||
return isHeadVersion(rubyVersion)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function floatVersion(rubyVersion) {
|
||||
const match = rubyVersion.match(/^\d+\.\d+/)
|
||||
if (match) {
|
||||
return parseFloat(match[0])
|
||||
} else {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
export async function hashFile(file) {
|
||||
// See https://github.com/actions/runner/blob/master/src/Misc/expressionFunc/hashFiles/src/hashFiles.ts
|
||||
const hash = crypto.createHash('sha256')
|
||||
@@ -69,7 +96,7 @@ export function getVirtualEnvironmentName() {
|
||||
throw new Error(`Unknown ImageOS ${imageOS}`)
|
||||
}
|
||||
|
||||
export function shouldExtractInToolCache(engine, version) {
|
||||
export function shouldUseToolCache(engine, version) {
|
||||
return engine === 'ruby' && !isHeadVersion(version)
|
||||
}
|
||||
|
||||
@@ -91,11 +118,16 @@ export function getToolCacheRubyPrefix(platform, version) {
|
||||
return path.join(toolCache, 'Ruby', version, 'x64')
|
||||
}
|
||||
|
||||
export function createToolCacheCompleteFile(toolCacheRubyPrefix) {
|
||||
const completeFile = `${toolCacheRubyPrefix}.complete`
|
||||
fs.writeFileSync(completeFile, '')
|
||||
}
|
||||
|
||||
// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin
|
||||
export function win2nix(path) {
|
||||
if (/^[A-Z]:/i.test(path)) {
|
||||
// path starts with drive
|
||||
path = `/${path[0].toLowerCase()}${path.split(':', 2)[1]}`
|
||||
path = `/${path[0].toLowerCase()}${partition(path, ':')[1]}`
|
||||
}
|
||||
return path.replace(/\\/g, '/').replace(/ /g, '\\ ')
|
||||
}
|
||||
|
||||
+118
-36
@@ -27712,18 +27712,32 @@ async function install(platform, engine, version) {
|
||||
}
|
||||
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
|
||||
|
||||
let rubyPrefix
|
||||
if (common.shouldExtractInToolCache(engine, version)) {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
let rubyPrefix, inToolCache
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
inToolCache = tc.find('Ruby', version)
|
||||
if (inToolCache) {
|
||||
rubyPrefix = inToolCache
|
||||
} else {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
}
|
||||
} else {
|
||||
rubyPrefix = `${drive}:\\${base}`
|
||||
}
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version)
|
||||
|
||||
common.setupPath([`${rubyPrefix}\\bin`, ...toolchainPaths])
|
||||
|
||||
if (!inToolCache) {
|
||||
await downloadAndExtract(engine, version, url, base, rubyPrefix);
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
}
|
||||
|
||||
async function downloadAndExtract(engine, version, url, base, rubyPrefix) {
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
const downloadPath = await common.measure('Downloading Ruby', async () => {
|
||||
console.log(url)
|
||||
return await tc.downloadTool(url)
|
||||
@@ -27736,7 +27750,9 @@ async function install(platform, engine, version) {
|
||||
await io.mv(path.join(parentDir, base), rubyPrefix)
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
common.createToolCacheCompleteFile(rubyPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
async function setupMingw(version) {
|
||||
@@ -27796,7 +27812,7 @@ function addVCVARSEnv() {
|
||||
let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/)
|
||||
newSet = newSet.filter(line => line.match(/\S=\S/))
|
||||
newSet.forEach(s => {
|
||||
let [k,v] = s.split('=', 2)
|
||||
let [k,v] = common.partition(s, '=')
|
||||
newEnv.set(k,v)
|
||||
})
|
||||
|
||||
@@ -32094,13 +32110,17 @@ exports.default = _default;
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windows", function() { return windows; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "drive", function() { return drive; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "measure", function() { return measure; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeadVersion", function() { return isHeadVersion; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isStableVersion", function() { return isStableVersion; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isBundler2Default", function() { return isBundler2Default; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "floatVersion", function() { return floatVersion; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hashFile", function() { return hashFile; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getVirtualEnvironmentName", function() { return getVirtualEnvironmentName; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shouldExtractInToolCache", function() { return shouldExtractInToolCache; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shouldUseToolCache", function() { return shouldUseToolCache; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getToolCacheRubyPrefix", function() { return getToolCacheRubyPrefix; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createToolCacheCompleteFile", function() { return createToolCacheCompleteFile; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "win2nix", function() { return win2nix; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setupPath", function() { return setupPath; });
|
||||
const os = __webpack_require__(87)
|
||||
@@ -32116,6 +32136,14 @@ const windows = (os.platform() === 'win32')
|
||||
// Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14
|
||||
const drive = (windows ? (process.env['GITHUB_WORKSPACE'] || 'C')[0] : undefined)
|
||||
|
||||
function partition(string, separator) {
|
||||
const i = string.indexOf(separator)
|
||||
if (i === -1) {
|
||||
throw new Error(`No separator ${separator} in string ${string}`)
|
||||
}
|
||||
return [string.slice(0, i), string.slice(i + separator.length, string.length)]
|
||||
}
|
||||
|
||||
async function measure(name, block) {
|
||||
return await core.group(name, async () => {
|
||||
const start = performance.now()
|
||||
@@ -32137,6 +32165,25 @@ function isStableVersion(rubyVersion) {
|
||||
return /^\d+(\.\d+)*$/.test(rubyVersion)
|
||||
}
|
||||
|
||||
function isBundler2Default(engine, rubyVersion) {
|
||||
if (engine === 'ruby') {
|
||||
return isHeadVersion(rubyVersion) || floatVersion(rubyVersion) >= 2.7
|
||||
} else if (engine === 'truffleruby') {
|
||||
return isHeadVersion(rubyVersion)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function floatVersion(rubyVersion) {
|
||||
const match = rubyVersion.match(/^\d+\.\d+/)
|
||||
if (match) {
|
||||
return parseFloat(match[0])
|
||||
} else {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
async function hashFile(file) {
|
||||
// See https://github.com/actions/runner/blob/master/src/Misc/expressionFunc/hashFiles/src/hashFiles.ts
|
||||
const hash = crypto.createHash('sha256')
|
||||
@@ -32174,7 +32221,7 @@ function getVirtualEnvironmentName() {
|
||||
throw new Error(`Unknown ImageOS ${imageOS}`)
|
||||
}
|
||||
|
||||
function shouldExtractInToolCache(engine, version) {
|
||||
function shouldUseToolCache(engine, version) {
|
||||
return engine === 'ruby' && !isHeadVersion(version)
|
||||
}
|
||||
|
||||
@@ -32196,11 +32243,16 @@ function getToolCacheRubyPrefix(platform, version) {
|
||||
return path.join(toolCache, 'Ruby', version, 'x64')
|
||||
}
|
||||
|
||||
function createToolCacheCompleteFile(toolCacheRubyPrefix) {
|
||||
const completeFile = `${toolCacheRubyPrefix}.complete`
|
||||
fs.writeFileSync(completeFile, '')
|
||||
}
|
||||
|
||||
// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin
|
||||
function win2nix(path) {
|
||||
if (/^[A-Z]:/i.test(path)) {
|
||||
// path starts with drive
|
||||
path = `/${path[0].toLowerCase()}${path.split(':', 2)[1]}`
|
||||
path = `/${path[0].toLowerCase()}${partition(path, ':')[1]}`
|
||||
}
|
||||
return path.replace(/\\/g, '/').replace(/ /g, '\\ ')
|
||||
}
|
||||
@@ -44531,7 +44583,7 @@ function getVersions(platform) {
|
||||
"2.5.0", "2.5.1", "2.5.2", "2.5.3", "2.5.4", "2.5.5", "2.5.6", "2.5.7", "2.5.8",
|
||||
"2.6.0", "2.6.1", "2.6.2", "2.6.3", "2.6.4", "2.6.5", "2.6.6",
|
||||
"2.7.0", "2.7.1", "2.7.2",
|
||||
"3.0.0-preview1",
|
||||
"3.0.0-preview1", "3.0.0-preview2",
|
||||
"head", "debug",
|
||||
],
|
||||
"jruby": [
|
||||
@@ -44541,7 +44593,7 @@ function getVersions(platform) {
|
||||
],
|
||||
"truffleruby": [
|
||||
"19.3.0", "19.3.1",
|
||||
"20.0.0", "20.1.0", "20.2.0",
|
||||
"20.0.0", "20.1.0", "20.2.0", "20.3.0",
|
||||
"head"
|
||||
]
|
||||
}
|
||||
@@ -51226,12 +51278,12 @@ async function setupRuby(options = {}) {
|
||||
if (inputs['bundler'] !== 'none') {
|
||||
const [gemfile, lockFile] = detectGemfiles()
|
||||
|
||||
await common.measure('Installing Bundler', async () =>
|
||||
const bundlerVersion = await common.measure('Installing Bundler', async () =>
|
||||
installBundler(inputs['bundler'], lockFile, platform, rubyPrefix, engine, version))
|
||||
|
||||
if (inputs['bundler-cache'] === 'true') {
|
||||
await common.measure('bundle install', async () =>
|
||||
bundleInstall(gemfile, lockFile, platform, engine, version))
|
||||
bundleInstall(gemfile, lockFile, platform, engine, version, bundlerVersion))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51269,7 +51321,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
|
||||
} else if (rubyVersion === '.tool-versions') { // Read from .tool-versions
|
||||
const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim()
|
||||
const rubyLine = toolVersions.split(/\r?\n/).filter(e => e.match(/^ruby\s/))[0]
|
||||
rubyVersion = rubyLine.split(/\s+/, 2)[1]
|
||||
rubyVersion = rubyLine.match(/^ruby\s+(.+)$/)[1]
|
||||
console.log(`Using ${rubyVersion} as input from file .tool-versions`)
|
||||
}
|
||||
|
||||
@@ -51281,7 +51333,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
|
||||
engine = rubyVersion
|
||||
version = '' // Let the logic in validateRubyEngineAndVersion() find the version
|
||||
} else { // engine-X.Y.Z
|
||||
[engine, version] = rubyVersion.split('-', 2)
|
||||
[engine, version] = common.partition(rubyVersion, '-')
|
||||
}
|
||||
|
||||
return [engine, version]
|
||||
@@ -51295,7 +51347,13 @@ function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVe
|
||||
let version = parsedVersion
|
||||
if (!engineVersions.includes(parsedVersion)) {
|
||||
const latestToFirstVersion = engineVersions.slice().reverse()
|
||||
const found = latestToFirstVersion.find(v => common.isStableVersion(v) && v.startsWith(parsedVersion))
|
||||
// Try to match stable versions first, so an empty version (engine-only) matches the latest stable version
|
||||
let found = latestToFirstVersion.find(v => common.isStableVersion(v) && v.startsWith(parsedVersion))
|
||||
if (!found) {
|
||||
// Exclude head versions, they must be exact matches
|
||||
found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
|
||||
}
|
||||
|
||||
if (found) {
|
||||
version = found
|
||||
} else {
|
||||
@@ -51379,7 +51437,7 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
|
||||
bundlerVersion = '1'
|
||||
}
|
||||
|
||||
if ((engine === 'ruby' || engine === 'truffleruby') && common.isHeadVersion(rubyVersion) && bundlerVersion === '2') {
|
||||
if (common.isHeadVersion(rubyVersion) && common.isBundler2Default(engine, rubyVersion) && bundlerVersion === '2') {
|
||||
console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
|
||||
} else if (engine === 'truffleruby' && !common.isHeadVersion(rubyVersion) && bundlerVersion === '1') {
|
||||
console.log(`Using Bundler 1 shipped with ${engine}`)
|
||||
@@ -51387,32 +51445,42 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
|
||||
const gem = path.join(rubyPrefix, 'bin', 'gem')
|
||||
await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
|
||||
}
|
||||
|
||||
return bundlerVersion
|
||||
}
|
||||
|
||||
async function bundleInstall(gemfile, lockFile, platform, engine, version) {
|
||||
async function bundleInstall(gemfile, lockFile, platform, engine, rubyVersion, bundlerVersion) {
|
||||
if (gemfile === null) {
|
||||
console.log('Could not determine gemfile path, skipping "bundle install" and caching')
|
||||
return false
|
||||
}
|
||||
|
||||
let envOptions = {}
|
||||
if (bundlerVersion.startsWith('1') && common.isBundler2Default(engine, rubyVersion)) {
|
||||
// If Bundler 1 is specified on Rubies which ship with Bundler 2,
|
||||
// we need to specify which Bundler version to use explicitly until the lockfile exists.
|
||||
console.log(`Setting BUNDLER_VERSION=${bundlerVersion} for "bundle config|lock" commands below to ensure Bundler 1 is used`)
|
||||
envOptions = { env: { ...process.env, BUNDLER_VERSION: bundlerVersion } }
|
||||
}
|
||||
|
||||
// config
|
||||
const path = 'vendor/bundle'
|
||||
|
||||
await exec.exec('bundle', ['config', '--local', 'path', path])
|
||||
await exec.exec('bundle', ['config', '--local', 'path', path], envOptions)
|
||||
|
||||
if (fs.existsSync(lockFile)) {
|
||||
await exec.exec('bundle', ['config', '--local', 'deployment', 'true'])
|
||||
await exec.exec('bundle', ['config', '--local', 'deployment', 'true'], envOptions)
|
||||
} else {
|
||||
// Generate the lockfile so we can use it to compute the cache key.
|
||||
// This will also automatically pick up the latest gem versions compatible with the Gemfile.
|
||||
await exec.exec('bundle', ['lock'])
|
||||
await exec.exec('bundle', ['lock'], envOptions)
|
||||
}
|
||||
|
||||
// cache key
|
||||
const paths = [path]
|
||||
const baseKey = await computeBaseKey(platform, engine, version, lockFile)
|
||||
const baseKey = await computeBaseKey(platform, engine, rubyVersion, lockFile)
|
||||
const key = `${baseKey}-${await common.hashFile(lockFile)}`
|
||||
// If only Gemfile.lock changes we can reuse part of the cache (but it will keep old gem versions in the cache)
|
||||
// If only Gemfile.lock changes we can reuse part of the cache, and clean old gem versions below
|
||||
const restoreKeys = [`${baseKey}-`]
|
||||
console.log(`Cache key: ${key}`)
|
||||
|
||||
@@ -51437,6 +51505,10 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
|
||||
|
||||
// @actions/cache only allows to save for non-existing keys
|
||||
if (cachedKey !== key) {
|
||||
if (cachedKey) { // existing cache but Gemfile.lock differs, clean old gems
|
||||
await exec.exec('bundle', ['clean'])
|
||||
}
|
||||
|
||||
// Error handling from https://github.com/actions/cache/blob/master/src/save.ts
|
||||
console.log('Saving cache')
|
||||
try {
|
||||
@@ -52889,7 +52961,6 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "install", function() { return install; });
|
||||
const os = __webpack_require__(87)
|
||||
const path = __webpack_require__(622)
|
||||
const core = __webpack_require__(186)
|
||||
const exec = __webpack_require__(514)
|
||||
const io = __webpack_require__(436)
|
||||
const tc = __webpack_require__(188)
|
||||
@@ -52906,24 +52977,33 @@ function getAvailableVersions(platform, engine) {
|
||||
}
|
||||
|
||||
async function install(platform, engine, version) {
|
||||
return await downloadAndExtract(platform, engine, version)
|
||||
}
|
||||
|
||||
async function downloadAndExtract(platform, engine, version) {
|
||||
let rubyPrefix
|
||||
if (common.shouldExtractInToolCache(engine, version)) {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
let rubyPrefix, inToolCache
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
inToolCache = tc.find('Ruby', version)
|
||||
if (inToolCache) {
|
||||
rubyPrefix = inToolCache
|
||||
} else {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
}
|
||||
} else if (windows) {
|
||||
rubyPrefix = path.join(`${common.drive}:`, `${engine}-${version}`)
|
||||
} else {
|
||||
rubyPrefix = path.join(os.homedir(), '.rubies', `${engine}-${version}`)
|
||||
}
|
||||
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
// Set the PATH now, so the MSYS2 'tar' is in Path on Windows
|
||||
common.setupPath([path.join(rubyPrefix, 'bin')])
|
||||
|
||||
if (!inToolCache) {
|
||||
await downloadAndExtract(platform, engine, version, rubyPrefix);
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
}
|
||||
|
||||
async function downloadAndExtract(platform, engine, version, rubyPrefix) {
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
await io.rmRF(rubyPrefix)
|
||||
await io.mkdirP(parentDir)
|
||||
|
||||
@@ -52936,13 +53016,15 @@ async function downloadAndExtract(platform, engine, version) {
|
||||
await common.measure('Extracting Ruby', async () => {
|
||||
if (windows) {
|
||||
// Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths
|
||||
await exec.exec('tar', [ '-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath) ])
|
||||
await exec.exec('tar', ['-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath)])
|
||||
} else {
|
||||
await exec.exec('tar', [ '-xz', '-C', parentDir, '-f', downloadPath ])
|
||||
await exec.exec('tar', ['-xz', '-C', parentDir, '-f', downloadPath])
|
||||
}
|
||||
})
|
||||
|
||||
return rubyPrefix
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
common.createToolCacheCompleteFile(rubyPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
function getDownloadURL(platform, engine, version) {
|
||||
|
||||
@@ -63,12 +63,12 @@ export async function setupRuby(options = {}) {
|
||||
if (inputs['bundler'] !== 'none') {
|
||||
const [gemfile, lockFile] = detectGemfiles()
|
||||
|
||||
await common.measure('Installing Bundler', async () =>
|
||||
const bundlerVersion = await common.measure('Installing Bundler', async () =>
|
||||
installBundler(inputs['bundler'], lockFile, platform, rubyPrefix, engine, version))
|
||||
|
||||
if (inputs['bundler-cache'] === 'true') {
|
||||
await common.measure('bundle install', async () =>
|
||||
bundleInstall(gemfile, lockFile, platform, engine, version))
|
||||
bundleInstall(gemfile, lockFile, platform, engine, version, bundlerVersion))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
|
||||
} else if (rubyVersion === '.tool-versions') { // Read from .tool-versions
|
||||
const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim()
|
||||
const rubyLine = toolVersions.split(/\r?\n/).filter(e => e.match(/^ruby\s/))[0]
|
||||
rubyVersion = rubyLine.split(/\s+/, 2)[1]
|
||||
rubyVersion = rubyLine.match(/^ruby\s+(.+)$/)[1]
|
||||
console.log(`Using ${rubyVersion} as input from file .tool-versions`)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
|
||||
engine = rubyVersion
|
||||
version = '' // Let the logic in validateRubyEngineAndVersion() find the version
|
||||
} else { // engine-X.Y.Z
|
||||
[engine, version] = rubyVersion.split('-', 2)
|
||||
[engine, version] = common.partition(rubyVersion, '-')
|
||||
}
|
||||
|
||||
return [engine, version]
|
||||
@@ -132,7 +132,13 @@ function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVe
|
||||
let version = parsedVersion
|
||||
if (!engineVersions.includes(parsedVersion)) {
|
||||
const latestToFirstVersion = engineVersions.slice().reverse()
|
||||
const found = latestToFirstVersion.find(v => common.isStableVersion(v) && v.startsWith(parsedVersion))
|
||||
// Try to match stable versions first, so an empty version (engine-only) matches the latest stable version
|
||||
let found = latestToFirstVersion.find(v => common.isStableVersion(v) && v.startsWith(parsedVersion))
|
||||
if (!found) {
|
||||
// Exclude head versions, they must be exact matches
|
||||
found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
|
||||
}
|
||||
|
||||
if (found) {
|
||||
version = found
|
||||
} else {
|
||||
@@ -216,7 +222,7 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
|
||||
bundlerVersion = '1'
|
||||
}
|
||||
|
||||
if ((engine === 'ruby' || engine === 'truffleruby') && common.isHeadVersion(rubyVersion) && bundlerVersion === '2') {
|
||||
if (common.isHeadVersion(rubyVersion) && common.isBundler2Default(engine, rubyVersion) && bundlerVersion === '2') {
|
||||
console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
|
||||
} else if (engine === 'truffleruby' && !common.isHeadVersion(rubyVersion) && bundlerVersion === '1') {
|
||||
console.log(`Using Bundler 1 shipped with ${engine}`)
|
||||
@@ -224,32 +230,42 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
|
||||
const gem = path.join(rubyPrefix, 'bin', 'gem')
|
||||
await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
|
||||
}
|
||||
|
||||
return bundlerVersion
|
||||
}
|
||||
|
||||
async function bundleInstall(gemfile, lockFile, platform, engine, version) {
|
||||
async function bundleInstall(gemfile, lockFile, platform, engine, rubyVersion, bundlerVersion) {
|
||||
if (gemfile === null) {
|
||||
console.log('Could not determine gemfile path, skipping "bundle install" and caching')
|
||||
return false
|
||||
}
|
||||
|
||||
let envOptions = {}
|
||||
if (bundlerVersion.startsWith('1') && common.isBundler2Default(engine, rubyVersion)) {
|
||||
// If Bundler 1 is specified on Rubies which ship with Bundler 2,
|
||||
// we need to specify which Bundler version to use explicitly until the lockfile exists.
|
||||
console.log(`Setting BUNDLER_VERSION=${bundlerVersion} for "bundle config|lock" commands below to ensure Bundler 1 is used`)
|
||||
envOptions = { env: { ...process.env, BUNDLER_VERSION: bundlerVersion } }
|
||||
}
|
||||
|
||||
// config
|
||||
const path = 'vendor/bundle'
|
||||
|
||||
await exec.exec('bundle', ['config', '--local', 'path', path])
|
||||
await exec.exec('bundle', ['config', '--local', 'path', path], envOptions)
|
||||
|
||||
if (fs.existsSync(lockFile)) {
|
||||
await exec.exec('bundle', ['config', '--local', 'deployment', 'true'])
|
||||
await exec.exec('bundle', ['config', '--local', 'deployment', 'true'], envOptions)
|
||||
} else {
|
||||
// Generate the lockfile so we can use it to compute the cache key.
|
||||
// This will also automatically pick up the latest gem versions compatible with the Gemfile.
|
||||
await exec.exec('bundle', ['lock'])
|
||||
await exec.exec('bundle', ['lock'], envOptions)
|
||||
}
|
||||
|
||||
// cache key
|
||||
const paths = [path]
|
||||
const baseKey = await computeBaseKey(platform, engine, version, lockFile)
|
||||
const baseKey = await computeBaseKey(platform, engine, rubyVersion, lockFile)
|
||||
const key = `${baseKey}-${await common.hashFile(lockFile)}`
|
||||
// If only Gemfile.lock changes we can reuse part of the cache (but it will keep old gem versions in the cache)
|
||||
// If only Gemfile.lock changes we can reuse part of the cache, and clean old gem versions below
|
||||
const restoreKeys = [`${baseKey}-`]
|
||||
console.log(`Cache key: ${key}`)
|
||||
|
||||
@@ -274,6 +290,10 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
|
||||
|
||||
// @actions/cache only allows to save for non-existing keys
|
||||
if (cachedKey !== key) {
|
||||
if (cachedKey) { // existing cache but Gemfile.lock differs, clean old gems
|
||||
await exec.exec('bundle', ['clean'])
|
||||
}
|
||||
|
||||
// Error handling from https://github.com/actions/cache/blob/master/src/save.ts
|
||||
console.log('Saving cache')
|
||||
try {
|
||||
|
||||
@@ -8,7 +8,7 @@ export function getVersions(platform) {
|
||||
"2.5.0", "2.5.1", "2.5.2", "2.5.3", "2.5.4", "2.5.5", "2.5.6", "2.5.7", "2.5.8",
|
||||
"2.6.0", "2.6.1", "2.6.2", "2.6.3", "2.6.4", "2.6.5", "2.6.6",
|
||||
"2.7.0", "2.7.1", "2.7.2",
|
||||
"3.0.0-preview1",
|
||||
"3.0.0-preview1", "3.0.0-preview2",
|
||||
"head", "debug",
|
||||
],
|
||||
"jruby": [
|
||||
@@ -18,7 +18,7 @@ export function getVersions(platform) {
|
||||
],
|
||||
"truffleruby": [
|
||||
"19.3.0", "19.3.1",
|
||||
"20.0.0", "20.1.0", "20.2.0",
|
||||
"20.0.0", "20.1.0", "20.2.0", "20.3.0",
|
||||
"head"
|
||||
]
|
||||
}
|
||||
|
||||
+23
-13
@@ -1,6 +1,5 @@
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const core = require('@actions/core')
|
||||
const exec = require('@actions/exec')
|
||||
const io = require('@actions/io')
|
||||
const tc = require('@actions/tool-cache')
|
||||
@@ -17,24 +16,33 @@ export function getAvailableVersions(platform, engine) {
|
||||
}
|
||||
|
||||
export async function install(platform, engine, version) {
|
||||
return await downloadAndExtract(platform, engine, version)
|
||||
}
|
||||
|
||||
async function downloadAndExtract(platform, engine, version) {
|
||||
let rubyPrefix
|
||||
if (common.shouldExtractInToolCache(engine, version)) {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
let rubyPrefix, inToolCache
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
inToolCache = tc.find('Ruby', version)
|
||||
if (inToolCache) {
|
||||
rubyPrefix = inToolCache
|
||||
} else {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
}
|
||||
} else if (windows) {
|
||||
rubyPrefix = path.join(`${common.drive}:`, `${engine}-${version}`)
|
||||
} else {
|
||||
rubyPrefix = path.join(os.homedir(), '.rubies', `${engine}-${version}`)
|
||||
}
|
||||
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
// Set the PATH now, so the MSYS2 'tar' is in Path on Windows
|
||||
common.setupPath([path.join(rubyPrefix, 'bin')])
|
||||
|
||||
if (!inToolCache) {
|
||||
await downloadAndExtract(platform, engine, version, rubyPrefix);
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
}
|
||||
|
||||
async function downloadAndExtract(platform, engine, version, rubyPrefix) {
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
await io.rmRF(rubyPrefix)
|
||||
await io.mkdirP(parentDir)
|
||||
|
||||
@@ -47,13 +55,15 @@ async function downloadAndExtract(platform, engine, version) {
|
||||
await common.measure('Extracting Ruby', async () => {
|
||||
if (windows) {
|
||||
// Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths
|
||||
await exec.exec('tar', [ '-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath) ])
|
||||
await exec.exec('tar', ['-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath)])
|
||||
} else {
|
||||
await exec.exec('tar', [ '-xz', '-C', parentDir, '-f', downloadPath ])
|
||||
await exec.exec('tar', ['-xz', '-C', parentDir, '-f', downloadPath])
|
||||
}
|
||||
})
|
||||
|
||||
return rubyPrefix
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
common.createToolCacheCompleteFile(rubyPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
function getDownloadURL(platform, engine, version) {
|
||||
|
||||
+22
-6
@@ -36,18 +36,32 @@ export async function install(platform, engine, version) {
|
||||
}
|
||||
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
|
||||
|
||||
let rubyPrefix
|
||||
if (common.shouldExtractInToolCache(engine, version)) {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
let rubyPrefix, inToolCache
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
inToolCache = tc.find('Ruby', version)
|
||||
if (inToolCache) {
|
||||
rubyPrefix = inToolCache
|
||||
} else {
|
||||
rubyPrefix = common.getToolCacheRubyPrefix(platform, version)
|
||||
}
|
||||
} else {
|
||||
rubyPrefix = `${drive}:\\${base}`
|
||||
}
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version)
|
||||
|
||||
common.setupPath([`${rubyPrefix}\\bin`, ...toolchainPaths])
|
||||
|
||||
if (!inToolCache) {
|
||||
await downloadAndExtract(engine, version, url, base, rubyPrefix);
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
}
|
||||
|
||||
async function downloadAndExtract(engine, version, url, base, rubyPrefix) {
|
||||
const parentDir = path.dirname(rubyPrefix)
|
||||
|
||||
const downloadPath = await common.measure('Downloading Ruby', async () => {
|
||||
console.log(url)
|
||||
return await tc.downloadTool(url)
|
||||
@@ -60,7 +74,9 @@ export async function install(platform, engine, version) {
|
||||
await io.mv(path.join(parentDir, base), rubyPrefix)
|
||||
}
|
||||
|
||||
return rubyPrefix
|
||||
if (common.shouldUseToolCache(engine, version)) {
|
||||
common.createToolCacheCompleteFile(rubyPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
async function setupMingw(version) {
|
||||
@@ -120,7 +136,7 @@ export function addVCVARSEnv() {
|
||||
let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/)
|
||||
newSet = newSet.filter(line => line.match(/\S=\S/))
|
||||
newSet.forEach(s => {
|
||||
let [k,v] = s.split('=', 2)
|
||||
let [k,v] = common.partition(s, '=')
|
||||
newEnv.set(k,v)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user