Compare commits

..
12 Commits
Author SHA1 Message Date
ojab 30f5e2d4cd Fixup bundler version for rubies with bundler as a default gem
Fixes #117
2020-12-05 15:40:47 +01:00
Benoit Daloze fd1d77b75c GitHub Actions parses 3.0 as '3', so use quotes
* And adapt excludes.
2020-12-05 13:14:51 +01:00
Benoit Daloze 2a0be7a409 Try stable versions first, and then try non-head versions
* Fixes https://github.com/ruby/setup-ruby/issues/115
2020-12-05 12:52:21 +01:00
Benoit Daloze bacba738b2 Run bundle clean when reusing a cache and the lockfile changed
* Fixes https://github.com/ruby/setup-ruby/issues/113
2020-12-02 17:36:27 +01:00
Benoit Daloze 21351ecc0a More details about BUNDLE_GEMFILE 2020-11-27 11:16:50 +01:00
Benoit Daloze 4d7e038419 Show how to set BUNDLE_GEMFILE in the README 2020-11-27 11:03:17 +01:00
Benoit Daloze e27aee156d Add TruffleRuby 20.3.0 2020-11-20 13:00:18 +01:00
Benoit Daloze 43bb24d212 Run lint explicitly on Ubuntu 20.04 to avoid warning 2020-11-20 13:00:18 +01:00
Benoit Daloze 0c4183e8b8 truffleruby-head works fine on macOS Big Sur now 2020-11-20 12:39:46 +01:00
Benoit Daloze 50ae8432ea Remove part about continue-on-error in example
* It does not seem to work well.
* See https://github.com/actions/toolkit/issues/399
2020-11-20 12:37:14 +01:00
Benoit Daloze a699edbce6 Add test for ruby-3.0.0-preview1 2020-11-19 00:33:41 +01:00
Benoit Daloze e38f9abc9e Fix usages of string.split(sep, limit)
* Since the limit just removes further matches in JavaScript.
2020-11-19 00:33:40 +01:00
7 changed files with 77 additions and 19 deletions
+4 -3
View File
@@ -17,20 +17,21 @@ jobs:
matrix: matrix:
os: [ ubuntu-16.04, ubuntu-18.04, ubuntu-20.04, macos-10.15, macos-11.0, windows-2016, windows-2019 ] 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 # 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: include:
- { os: windows-2016, ruby: mingw } - { os: windows-2016, ruby: mingw }
- { os: windows-2019, ruby: mingw } - { os: windows-2019, ruby: mingw }
- { os: windows-2019, ruby: mswin } - { os: windows-2019, ruby: mswin }
exclude: exclude:
- { os: windows-2016, ruby: '3.0' }
- { os: windows-2016, ruby: debug } - { os: windows-2016, ruby: debug }
- { os: windows-2016, ruby: truffleruby } - { os: windows-2016, ruby: truffleruby }
- { os: windows-2016, ruby: truffleruby-head } - { os: windows-2016, ruby: truffleruby-head }
- { os: windows-2019, ruby: '3.0' }
- { os: windows-2019, ruby: debug } - { os: windows-2019, ruby: debug }
- { os: windows-2019, ruby: truffleruby } - { os: windows-2019, ruby: truffleruby }
- { os: windows-2019, ruby: truffleruby-head } - { os: windows-2019, ruby: truffleruby-head }
- { os: macos-11.0, ruby: truffleruby } - { os: macos-11.0, ruby: truffleruby }
- { os: macos-11.0, ruby: truffleruby-head }
name: ${{ matrix.os }} ${{ matrix.ruby }} name: ${{ matrix.os }} ${{ matrix.ruby }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -102,7 +103,7 @@ jobs:
run: gem install sassc -N run: gem install sassc -N
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: yarn install - run: yarn install
+18 -2
View File
@@ -16,7 +16,7 @@ This action currently supports these versions of MRI, JRuby and TruffleRuby:
| ----------- | -------- | | ----------- | -------- |
| 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 | | 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 | | JRuby | 9.1.17.0, 9.2.9.0 - 9.2.13.0, head |
| TruffleRuby | 19.3.0 - 20.2.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`). `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.
@@ -85,7 +85,6 @@ jobs:
os: [ubuntu, macos] os: [ubuntu, macos]
ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head] ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]
runs-on: ${{ matrix.os }}-latest runs-on: ${{ matrix.os }}-latest
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1 - 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). 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. 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`. 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`). Therefore, the Bundler `path` should not be changed in your workflow for the cache to work (no `bundle config path`).
+9 -1
View File
@@ -11,6 +11,14 @@ export const windows = (os.platform() === 'win32')
// Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14 // 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 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) { export async function measure(name, block) {
return await core.group(name, async () => { return await core.group(name, async () => {
const start = performance.now() const start = performance.now()
@@ -95,7 +103,7 @@ export function getToolCacheRubyPrefix(platform, version) {
export function win2nix(path) { export function win2nix(path) {
if (/^[A-Z]:/i.test(path)) { if (/^[A-Z]:/i.test(path)) {
// path starts with drive // 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, '\\ ') return path.replace(/\\/g, '/').replace(/ /g, '\\ ')
} }
Generated Vendored
+28 -7
View File
@@ -27796,7 +27796,7 @@ function addVCVARSEnv() {
let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/) let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/)
newSet = newSet.filter(line => line.match(/\S=\S/)) newSet = newSet.filter(line => line.match(/\S=\S/))
newSet.forEach(s => { newSet.forEach(s => {
let [k,v] = s.split('=', 2) let [k,v] = common.partition(s, '=')
newEnv.set(k,v) newEnv.set(k,v)
}) })
@@ -32094,6 +32094,7 @@ exports.default = _default;
__webpack_require__.r(__webpack_exports__); __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__, "windows", function() { return windows; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "drive", function() { return drive; }); /* 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__, "measure", function() { return measure; });
/* 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__, "isStableVersion", function() { return isStableVersion; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isStableVersion", function() { return isStableVersion; });
@@ -32116,6 +32117,14 @@ const windows = (os.platform() === 'win32')
// Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14 // Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14
const drive = (windows ? (process.env['GITHUB_WORKSPACE'] || 'C')[0] : undefined) 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) { async function measure(name, block) {
return await core.group(name, async () => { return await core.group(name, async () => {
const start = performance.now() const start = performance.now()
@@ -32200,7 +32209,7 @@ function getToolCacheRubyPrefix(platform, version) {
function win2nix(path) { function win2nix(path) {
if (/^[A-Z]:/i.test(path)) { if (/^[A-Z]:/i.test(path)) {
// path starts with drive // 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, '\\ ') return path.replace(/\\/g, '/').replace(/ /g, '\\ ')
} }
@@ -44541,7 +44550,7 @@ function getVersions(platform) {
], ],
"truffleruby": [ "truffleruby": [
"19.3.0", "19.3.1", "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" "head"
] ]
} }
@@ -51269,7 +51278,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
} else if (rubyVersion === '.tool-versions') { // Read from .tool-versions } else if (rubyVersion === '.tool-versions') { // Read from .tool-versions
const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim() const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim()
const rubyLine = toolVersions.split(/\r?\n/).filter(e => e.match(/^ruby\s/))[0] 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`) console.log(`Using ${rubyVersion} as input from file .tool-versions`)
} }
@@ -51281,7 +51290,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
engine = rubyVersion engine = rubyVersion
version = '' // Let the logic in validateRubyEngineAndVersion() 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] = common.partition(rubyVersion, '-')
} }
return [engine, version] return [engine, version]
@@ -51295,7 +51304,13 @@ function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVe
let version = parsedVersion let version = parsedVersion
if (!engineVersions.includes(parsedVersion)) { if (!engineVersions.includes(parsedVersion)) {
const latestToFirstVersion = engineVersions.slice().reverse() 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) { if (found) {
version = found version = found
} else { } else {
@@ -51387,6 +51402,8 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
const gem = path.join(rubyPrefix, 'bin', 'gem') const gem = path.join(rubyPrefix, 'bin', 'gem')
await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document']) await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
} }
core.exportVariable('BUNDLER_VERSION', bundlerVersion)
} }
async function bundleInstall(gemfile, lockFile, platform, engine, version) { async function bundleInstall(gemfile, lockFile, platform, engine, version) {
@@ -51412,7 +51429,7 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
const paths = [path] const paths = [path]
const baseKey = await computeBaseKey(platform, engine, version, lockFile) const baseKey = await computeBaseKey(platform, engine, version, lockFile)
const key = `${baseKey}-${await common.hashFile(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}-`] const restoreKeys = [`${baseKey}-`]
console.log(`Cache key: ${key}`) console.log(`Cache key: ${key}`)
@@ -51437,6 +51454,10 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
// @actions/cache only allows to save for non-existing keys // @actions/cache only allows to save for non-existing keys
if (cachedKey !== key) { 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 // Error handling from https://github.com/actions/cache/blob/master/src/save.ts
console.log('Saving cache') console.log('Saving cache')
try { try {
+16 -4
View File
@@ -106,7 +106,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
} else if (rubyVersion === '.tool-versions') { // Read from .tool-versions } else if (rubyVersion === '.tool-versions') { // Read from .tool-versions
const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim() const toolVersions = fs.readFileSync('.tool-versions', 'utf8').trim()
const rubyLine = toolVersions.split(/\r?\n/).filter(e => e.match(/^ruby\s/))[0] 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`) console.log(`Using ${rubyVersion} as input from file .tool-versions`)
} }
@@ -118,7 +118,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
engine = rubyVersion engine = rubyVersion
version = '' // Let the logic in validateRubyEngineAndVersion() 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] = common.partition(rubyVersion, '-')
} }
return [engine, version] return [engine, version]
@@ -132,7 +132,13 @@ function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVe
let version = parsedVersion let version = parsedVersion
if (!engineVersions.includes(parsedVersion)) { if (!engineVersions.includes(parsedVersion)) {
const latestToFirstVersion = engineVersions.slice().reverse() 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) { if (found) {
version = found version = found
} else { } else {
@@ -224,6 +230,8 @@ async function installBundler(bundlerVersionInput, lockFile, platform, rubyPrefi
const gem = path.join(rubyPrefix, 'bin', 'gem') const gem = path.join(rubyPrefix, 'bin', 'gem')
await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document']) await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
} }
core.exportVariable('BUNDLER_VERSION', bundlerVersion)
} }
async function bundleInstall(gemfile, lockFile, platform, engine, version) { async function bundleInstall(gemfile, lockFile, platform, engine, version) {
@@ -249,7 +257,7 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
const paths = [path] const paths = [path]
const baseKey = await computeBaseKey(platform, engine, version, lockFile) const baseKey = await computeBaseKey(platform, engine, version, lockFile)
const key = `${baseKey}-${await common.hashFile(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}-`] const restoreKeys = [`${baseKey}-`]
console.log(`Cache key: ${key}`) console.log(`Cache key: ${key}`)
@@ -274,6 +282,10 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
// @actions/cache only allows to save for non-existing keys // @actions/cache only allows to save for non-existing keys
if (cachedKey !== key) { 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 // Error handling from https://github.com/actions/cache/blob/master/src/save.ts
console.log('Saving cache') console.log('Saving cache')
try { try {
+1 -1
View File
@@ -18,7 +18,7 @@ export function getVersions(platform) {
], ],
"truffleruby": [ "truffleruby": [
"19.3.0", "19.3.1", "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" "head"
] ]
} }
+1 -1
View File
@@ -120,7 +120,7 @@ export function addVCVARSEnv() {
let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/) let newSet = cp.execSync(cmd).toString().trim().split(/\r?\n/)
newSet = newSet.filter(line => line.match(/\S=\S/)) newSet = newSet.filter(line => line.match(/\S=\S/))
newSet.forEach(s => { newSet.forEach(s => {
let [k,v] = s.split('=', 2) let [k,v] = common.partition(s, '=')
newEnv.set(k,v) newEnv.set(k,v)
}) })