Compare commits

...
4 Commits
7 changed files with 100 additions and 30 deletions
+4
View File
@@ -21,6 +21,10 @@ This action currently supports these versions of MRI, JRuby and TruffleRuby:
`ruby-debug` is the same as `ruby-head` but with assertions enabled (`-DRUBY_DEBUG=1`). `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. On Windows, `mingw` and `mswin` are `ruby-head` builds using the MSYS2/MinGW and the MSVC toolchains respectively.
Preview and RC versions of Ruby might be available too on Ubuntu and macOS (not on Windows).
However, it is recommended to test against `ruby-head` rather than previews,
as it provides more useful feedback for the Ruby core team and for upcoming changes.
Only versions published by [RubyInstaller](https://rubyinstaller.org/downloads/archives/) are available on Windows. Only versions published by [RubyInstaller](https://rubyinstaller.org/downloads/archives/) are available on Windows.
Due to that, Ruby 2.2 resolves to 2.2.6 on Windows and 2.2.10 on other platforms. Due to that, Ruby 2.2 resolves to 2.2.6 on Windows and 2.2.10 on other platforms.
And Ruby 2.3 on Windows only has builds for 2.3.0, 2.3.1 and 2.3.3. And Ruby 2.3 on Windows only has builds for 2.3.0, 2.3.1 and 2.3.3.
+12
View File
@@ -59,6 +59,18 @@ function findUbuntuVersion() {
} }
} }
export function shouldExtractInToolCache(engine, version) {
return engine === 'ruby' && !isHeadVersion(version)
}
export function getToolCacheRubyPrefix(version) {
const toolCache = process.env['RUNNER_TOOL_CACHE']
if (!toolCache) {
throw new Error('$RUNNER_TOOL_CACHE must be set')
}
return path.join(toolCache, 'Ruby', version, 'x64')
}
// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin // convert windows path like C:\Users\runneradmin to /c/Users/runneradmin
export function win2nix(path) { export function win2nix(path) {
if (/^[A-Z]:/i.test(path)) { if (/^[A-Z]:/i.test(path)) {
Generated Vendored
+49 -15
View File
@@ -27682,6 +27682,7 @@ const path = __webpack_require__(622)
const cp = __webpack_require__(129) const cp = __webpack_require__(129)
const core = __webpack_require__(186) const core = __webpack_require__(186)
const exec = __webpack_require__(514) const exec = __webpack_require__(514)
const io = __webpack_require__(436)
const tc = __webpack_require__(188) const tc = __webpack_require__(188)
const common = __webpack_require__(390) const common = __webpack_require__(390)
const rubyInstallerVersions = __webpack_require__(223).versions const rubyInstallerVersions = __webpack_require__(223).versions
@@ -27711,7 +27712,13 @@ async function install(platform, engine, version) {
} }
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length) const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
const rubyPrefix = `${drive}:\\${base}` let rubyPrefix
if (common.shouldExtractInToolCache(engine, version)) {
rubyPrefix = common.getToolCacheRubyPrefix(version)
} else {
rubyPrefix = `${drive}:\\${base}`
}
const parentDir = path.dirname(rubyPrefix)
let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version) let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version)
@@ -27723,7 +27730,11 @@ async function install(platform, engine, version) {
}) })
await common.measure('Extracting Ruby', async () => await common.measure('Extracting Ruby', async () =>
exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true })) exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${parentDir}`], { silent: true }))
if (base !== path.basename(rubyPrefix)) {
await io.mv(path.join(parentDir, base), rubyPrefix)
}
return rubyPrefix return rubyPrefix
} }
@@ -32087,6 +32098,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeadVersion", function() { return isHeadVersion; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isHeadVersion", function() { return isHeadVersion; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hashFile", function() { return hashFile; }); /* 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__, "getVirtualEnvironmentName", function() { return getVirtualEnvironmentName; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shouldExtractInToolCache", function() { return shouldExtractInToolCache; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getToolCacheRubyPrefix", function() { return getToolCacheRubyPrefix; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "win2nix", function() { return win2nix; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "win2nix", function() { return win2nix; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setupPath", function() { return setupPath; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setupPath", function() { return setupPath; });
const os = __webpack_require__(87) const os = __webpack_require__(87)
@@ -32150,6 +32163,18 @@ function findUbuntuVersion() {
} }
} }
function shouldExtractInToolCache(engine, version) {
return engine === 'ruby' && !isHeadVersion(version)
}
function getToolCacheRubyPrefix(version) {
const toolCache = process.env['RUNNER_TOOL_CACHE']
if (!toolCache) {
throw new Error('$RUNNER_TOOL_CACHE must be set')
}
return path.join(toolCache, 'Ruby', version, 'x64')
}
// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin // convert windows path like C:\Users\runneradmin to /c/Users/runneradmin
function win2nix(path) { function win2nix(path) {
if (/^[A-Z]:/i.test(path)) { if (/^[A-Z]:/i.test(path)) {
@@ -44485,6 +44510,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.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.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", "2.7.0", "2.7.1", "2.7.2",
"3.0.0-preview1",
"head", "debug", "head", "debug",
], ],
"jruby": [ "jruby": [
@@ -51155,7 +51181,7 @@ async function setupRuby(options = {}) {
const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version']) const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version'])
let installer let installer
if (platform === 'windows-latest' && engine !== 'jruby') { if (platform === 'windows-latest' && engine === 'ruby') {
installer = __webpack_require__(216) installer = __webpack_require__(216)
} else { } else {
installer = __webpack_require__(974) installer = __webpack_require__(974)
@@ -51242,7 +51268,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
version = rubyVersion version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion } else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
engine = rubyVersion engine = rubyVersion
version = '' // Let the logic below find the version version = '' // Let the logic in validateRubyEngineAndVersion() find the version
} else { // engine-X.Y.Z } else { // engine-X.Y.Z
[engine, version] = rubyVersion.split('-', 2) [engine, version] = rubyVersion.split('-', 2)
} }
@@ -51311,7 +51337,7 @@ function readBundledWithFromGemfileLock(lockFile) {
} }
async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefix, engine, rubyVersion) { async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = bundlerVersionInput let bundlerVersion = bundlerVersionInput
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock(lockFile) bundlerVersion = readBundledWithFromGemfileLock(lockFile)
@@ -51365,12 +51391,12 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
// cache key // cache key
const paths = [path] const paths = [path]
const baseKey = await computeBaseKey(platform, engine, version) const baseKey = await computeBaseKey(platform, engine, version, gemfile)
let key = baseKey let key = baseKey
let restoreKeys let restoreKeys
if (lockFile !== null) { if (lockFile !== null) {
key += `-${lockFile}-${await common.hashFile(lockFile)}` key += `-${lockFile}-${await common.hashFile(lockFile)}`
// If only Gemfile.lock we can reuse some 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 (but it will keep old gem versions in the cache)
restoreKeys = [`${baseKey}-${lockFile}-`] restoreKeys = [`${baseKey}-${lockFile}-`]
} else { } else {
// Only exact key, to never mix native gems of different platforms or Ruby versions // Only exact key, to never mix native gems of different platforms or Ruby versions
@@ -51421,8 +51447,8 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
return true return true
} }
async function computeBaseKey(platform, engine, version) { async function computeBaseKey(platform, engine, version, gemfile) {
let baseKey = `setup-ruby-bundle-install-${platform}-${engine}-${version}` let baseKey = `setup-ruby-toolcache-bundle-install-${platform}-${engine}-${version}-${gemfile}`
if (engine !== 'jruby' && common.isHeadVersion(version)) { if (engine !== 'jruby' && common.isHeadVersion(version)) {
let revision = ''; let revision = '';
await exec.exec('ruby', ['-e', 'print RUBY_REVISION'], { await exec.exec('ruby', ['-e', 'print RUBY_REVISION'], {
@@ -52859,7 +52885,7 @@ const tc = __webpack_require__(188)
const common = __webpack_require__(390) const common = __webpack_require__(390)
const rubyBuilderVersions = __webpack_require__(694) const rubyBuilderVersions = __webpack_require__(694)
const builderReleaseTag = 'enable-shared' const builderReleaseTag = 'toolcache'
const releasesURL = 'https://github.com/ruby/ruby-builder/releases' const releasesURL = 'https://github.com/ruby/ruby-builder/releases'
const windows = common.windows const windows = common.windows
@@ -52873,14 +52899,22 @@ async function install(platform, engine, version) {
} }
async function downloadAndExtract(platform, engine, version) { async function downloadAndExtract(platform, engine, version) {
const rubiesDir = windows ? `${common.drive}:` : path.join(os.homedir(), '.rubies') let rubyPrefix
if (common.shouldExtractInToolCache(engine, version)) {
rubyPrefix = common.getToolCacheRubyPrefix(version)
} else if (windows) {
rubyPrefix = path.join(`${common.drive}:`, `${engine}-${version}`)
} else {
rubyPrefix = path.join(os.homedir(), '.rubies', `${engine}-${version}`)
}
const rubyPrefix = path.join(rubiesDir, `${engine}-${version}`) const parentDir = path.dirname(rubyPrefix)
// Set the PATH now, so the MSYS2 'tar' is in Path on Windows // Set the PATH now, so the MSYS2 'tar' is in Path on Windows
common.setupPath([path.join(rubyPrefix, 'bin')]) common.setupPath([path.join(rubyPrefix, 'bin')])
await io.mkdirP(rubiesDir) await io.rmRF(rubyPrefix)
await io.mkdirP(parentDir)
const downloadPath = await common.measure('Downloading Ruby', async () => { const downloadPath = await common.measure('Downloading Ruby', async () => {
const url = getDownloadURL(platform, engine, version) const url = getDownloadURL(platform, engine, version)
@@ -52891,9 +52925,9 @@ async function downloadAndExtract(platform, engine, version) {
await common.measure('Extracting Ruby', async () => { await common.measure('Extracting Ruby', async () => {
if (windows) { if (windows) {
// Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths // Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths
await exec.exec('tar', [ '-xz', '-C', common.win2nix(rubiesDir), '-f', common.win2nix(downloadPath) ]) await exec.exec('tar', [ '-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath) ])
} else { } else {
await exec.exec('tar', [ '-xz', '-C', rubiesDir, '-f', downloadPath ]) await exec.exec('tar', [ '-xz', '-C', parentDir, '-f', downloadPath ])
} }
}) })
+7 -7
View File
@@ -39,7 +39,7 @@ export async function setupRuby(options = {}) {
const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version']) const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version'])
let installer let installer
if (platform === 'windows-latest' && engine !== 'jruby') { if (platform === 'windows-latest' && engine === 'ruby') {
installer = require('./windows') installer = require('./windows')
} else { } else {
installer = require('./ruby-builder') installer = require('./ruby-builder')
@@ -126,7 +126,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
version = rubyVersion version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion } else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
engine = rubyVersion engine = rubyVersion
version = '' // Let the logic below find the version version = '' // Let the logic in validateRubyEngineAndVersion() find the version
} else { // engine-X.Y.Z } else { // engine-X.Y.Z
[engine, version] = rubyVersion.split('-', 2) [engine, version] = rubyVersion.split('-', 2)
} }
@@ -195,7 +195,7 @@ function readBundledWithFromGemfileLock(lockFile) {
} }
async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefix, engine, rubyVersion) { async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = bundlerVersionInput let bundlerVersion = bundlerVersionInput
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock(lockFile) bundlerVersion = readBundledWithFromGemfileLock(lockFile)
@@ -249,12 +249,12 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
// cache key // cache key
const paths = [path] const paths = [path]
const baseKey = await computeBaseKey(platform, engine, version) const baseKey = await computeBaseKey(platform, engine, version, gemfile)
let key = baseKey let key = baseKey
let restoreKeys let restoreKeys
if (lockFile !== null) { if (lockFile !== null) {
key += `-${lockFile}-${await common.hashFile(lockFile)}` key += `-${lockFile}-${await common.hashFile(lockFile)}`
// If only Gemfile.lock we can reuse some 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 (but it will keep old gem versions in the cache)
restoreKeys = [`${baseKey}-${lockFile}-`] restoreKeys = [`${baseKey}-${lockFile}-`]
} else { } else {
// Only exact key, to never mix native gems of different platforms or Ruby versions // Only exact key, to never mix native gems of different platforms or Ruby versions
@@ -305,8 +305,8 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
return true return true
} }
async function computeBaseKey(platform, engine, version) { async function computeBaseKey(platform, engine, version, gemfile) {
let baseKey = `setup-ruby-bundle-install-${platform}-${engine}-${version}` let baseKey = `setup-ruby-toolcache-bundle-install-${platform}-${engine}-${version}-${gemfile}`
if (engine !== 'jruby' && common.isHeadVersion(version)) { if (engine !== 'jruby' && common.isHeadVersion(version)) {
let revision = ''; let revision = '';
await exec.exec('ruby', ['-e', 'print RUBY_REVISION'], { await exec.exec('ruby', ['-e', 'print RUBY_REVISION'], {
+1
View File
@@ -8,6 +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.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.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", "2.7.0", "2.7.1", "2.7.2",
"3.0.0-preview1",
"head", "debug", "head", "debug",
], ],
"jruby": [ "jruby": [
+14 -6
View File
@@ -7,7 +7,7 @@ const tc = require('@actions/tool-cache')
const common = require('./common') const common = require('./common')
const rubyBuilderVersions = require('./ruby-builder-versions') const rubyBuilderVersions = require('./ruby-builder-versions')
const builderReleaseTag = 'enable-shared' const builderReleaseTag = 'toolcache'
const releasesURL = 'https://github.com/ruby/ruby-builder/releases' const releasesURL = 'https://github.com/ruby/ruby-builder/releases'
const windows = common.windows const windows = common.windows
@@ -21,14 +21,22 @@ export async function install(platform, engine, version) {
} }
async function downloadAndExtract(platform, engine, version) { async function downloadAndExtract(platform, engine, version) {
const rubiesDir = windows ? `${common.drive}:` : path.join(os.homedir(), '.rubies') let rubyPrefix
if (common.shouldExtractInToolCache(engine, version)) {
rubyPrefix = common.getToolCacheRubyPrefix(version)
} else if (windows) {
rubyPrefix = path.join(`${common.drive}:`, `${engine}-${version}`)
} else {
rubyPrefix = path.join(os.homedir(), '.rubies', `${engine}-${version}`)
}
const rubyPrefix = path.join(rubiesDir, `${engine}-${version}`) const parentDir = path.dirname(rubyPrefix)
// Set the PATH now, so the MSYS2 'tar' is in Path on Windows // Set the PATH now, so the MSYS2 'tar' is in Path on Windows
common.setupPath([path.join(rubyPrefix, 'bin')]) common.setupPath([path.join(rubyPrefix, 'bin')])
await io.mkdirP(rubiesDir) await io.rmRF(rubyPrefix)
await io.mkdirP(parentDir)
const downloadPath = await common.measure('Downloading Ruby', async () => { const downloadPath = await common.measure('Downloading Ruby', async () => {
const url = getDownloadURL(platform, engine, version) const url = getDownloadURL(platform, engine, version)
@@ -39,9 +47,9 @@ async function downloadAndExtract(platform, engine, version) {
await common.measure('Extracting Ruby', async () => { await common.measure('Extracting Ruby', async () => {
if (windows) { if (windows) {
// Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths // Windows 2016 doesn't have system tar, use MSYS2's, it needs unix style paths
await exec.exec('tar', [ '-xz', '-C', common.win2nix(rubiesDir), '-f', common.win2nix(downloadPath) ]) await exec.exec('tar', [ '-xz', '-C', common.win2nix(parentDir), '-f', common.win2nix(downloadPath) ])
} else { } else {
await exec.exec('tar', [ '-xz', '-C', rubiesDir, '-f', downloadPath ]) await exec.exec('tar', [ '-xz', '-C', parentDir, '-f', downloadPath ])
} }
}) })
+13 -2
View File
@@ -6,6 +6,7 @@ const path = require('path')
const cp = require('child_process') const cp = require('child_process')
const core = require('@actions/core') const core = require('@actions/core')
const exec = require('@actions/exec') const exec = require('@actions/exec')
const io = require('@actions/io')
const tc = require('@actions/tool-cache') const tc = require('@actions/tool-cache')
const common = require('./common') const common = require('./common')
const rubyInstallerVersions = require('./windows-versions').versions const rubyInstallerVersions = require('./windows-versions').versions
@@ -35,7 +36,13 @@ export async function install(platform, engine, version) {
} }
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length) const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
const rubyPrefix = `${drive}:\\${base}` let rubyPrefix
if (common.shouldExtractInToolCache(engine, version)) {
rubyPrefix = common.getToolCacheRubyPrefix(version)
} else {
rubyPrefix = `${drive}:\\${base}`
}
const parentDir = path.dirname(rubyPrefix)
let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version) let toolchainPaths = (version === 'mswin') ? await setupMSWin() : await setupMingw(version)
@@ -47,7 +54,11 @@ export async function install(platform, engine, version) {
}) })
await common.measure('Extracting Ruby', async () => await common.measure('Extracting Ruby', async () =>
exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true })) exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${parentDir}`], { silent: true }))
if (base !== path.basename(rubyPrefix)) {
await io.mv(path.join(parentDir, base), rubyPrefix)
}
return rubyPrefix return rubyPrefix
} }