Compare commits

...
9 Commits
Author SHA1 Message Date
Benoit Daloze 3c644cf2fc Better error if MSYS2 is missing 2020-01-05 19:47:18 +01:00
Benoit Daloze 101f62de1d Add support for Windows 2020-01-05 19:33:14 +01:00
Benoit Daloze 9432c89d1a Recommend the short version syntax
* It's safer long-term and ensures to use the latest release with the most bug fixes.
2020-01-05 13:11:27 +01:00
Benoit Daloze 4c00b61136 Simplify the README 2020-01-05 13:03:07 +01:00
Benoit Daloze d49a90aea9 tmp 2020-01-05 13:02:10 +01:00
Benoit Daloze 1d7622c155 Use a consistent ordering for JRuby and TruffleRuby 2020-01-05 13:00:17 +01:00
Benoit Daloze a90d45f642 Improve the README 2020-01-05 12:55:52 +01:00
Benoit Daloze d9cd49386b Add support for Ruby 2.3
* Fixes https://github.com/eregon/use-ruby-action/issues/3
2020-01-05 12:50:37 +01:00
Benoit Daloze 7d189e2075 Improve error message when a version is not available 2020-01-04 16:18:37 +01:00
8 changed files with 280 additions and 77 deletions
+2 -1
View File
@@ -10,7 +10,8 @@
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
}
+14 -3
View File
@@ -5,8 +5,16 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-16.04, ubuntu-18.04, macos-latest ]
ruby: [ ruby-2.4, 2.5, ruby-2.6.5, 2.7.0, truffleruby, jruby ]
os: [ ubuntu-16.04, ubuntu-18.04, macos-latest, windows-latest ]
# Use various version syntaxes here for testing
ruby: [ 2.3, ruby-2.4, 2.5, ruby-2.6.5, 2.7.0, jruby, truffleruby ]
exclude:
- os: windows-latest
ruby: 2.3
- os: windows-latest
ruby: jruby
- os: windows-latest
ruby: truffleruby
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -14,4 +22,7 @@ jobs:
with:
ruby-version: ${{ matrix.ruby }}
- run: ruby -v
- run: ruby -ropen-uri -e 'puts open("https://rubygems.org/") { |f| f.read(2014) }'
- run: ridk version
if: matrix.os == 'windows-latest'
- run: ruby -ropen-uri -e 'puts open(%{https://rubygems.org/}) { |f| f.read(2014) }'
- run: gem install json --no-document
+36 -36
View File
@@ -2,15 +2,38 @@
This action downloads a prebuilt ruby and adds it to `$PATH`.
It currently supports the latest stable versions of MRI, JRuby and TruffleRuby.
It is very efficient and takes about 5 seconds to download, extract and add the given Ruby to `$PATH`.
No extra packages need to be installed.
### Supported Versions
This action currently supports these versions of MRI, JRuby and TruffleRuby:
| Interpreter | Versions |
| ----------- | -------- |
| Ruby | 2.3.8, 2.4.9, 2.5.7, 2.6.5, 2.7.0 |
| JRuby | 9.2.9.0 |
| TruffleRuby | 19.3.0 |
The recommended way to refer to these versions is:
`2.3`, `2.4`, `2.5`, `2.6`, `2.7`, `jruby`, `truffleruby`.
That way, the latest compatible release is used, which contains the most bug fixes.
See https://github.com/eregon/ruby-install-builder/blob/metadata/versions.json
for the available Ruby versions.
for the always up-to-date list of available Ruby versions.
The action works for the `ubuntu-16.04`, `ubuntu-18.04` and `macos-latest` GitHub-hosted runners.
`windows-latest` is not yet supported.
Note that Ruby 2.3 and the OpenSSL version it needs (1.0.2) are both end-of-life,
which means Ruby 2.3 is unmaintained and considered insecure.
The prebuilt rubies are generated by https://github.com/eregon/ruby-install-builder.
### Supported Platforms
The action works for all GitHub-hosted runners:
`ubuntu-16.04`, `ubuntu-18.04`, `macos-latest` and `windows-latest`.
Ruby 2.3, JRuby and TruffleRuby are not yet supported on `windows-latest`.
The prebuilt rubies are generated by https://github.com/eregon/ruby-install-builder
and on Windows by https://github.com/oneclick/rubyinstaller2.
## Usage
@@ -26,12 +49,14 @@ jobs:
- uses: actions/checkout@v2
- uses: eregon/use-ruby-action@master
with:
ruby-version: ruby-2.6
ruby-version: 2.6
- run: ruby -v
```
### Matrix
This matrix tests all stable releases of MRI, JRuby and TruffleRuby on Ubuntu and macOS.
```yaml
name: My workflow
on: [push]
@@ -41,7 +66,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest ]
ruby: [ ruby-2.6, ruby-2.7, truffleruby-19.3.0, jruby-9.2.9.0 ]
ruby: [ 2.4, 2.5, 2.6, 2.7, jruby, truffleruby ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -58,35 +83,10 @@ jobs:
* version only like `2.6.5`, assumes MRI for the engine
* engine only like `truffleruby`, uses the latest stable release of that implementation
### All Stable Versions
With that, we can test on all stable releases of MRI, JRuby and TruffleRuby with:
```yaml
name: My workflow
on: [push]
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest ]
ruby: [ 2.4, 2.5, 2.6, 2.7, truffleruby, jruby ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: eregon/use-ruby-action@master
with:
ruby-version: ${{ matrix.ruby }}
- run: ruby -v
```
## Efficiency
It takes about 5 seconds to setup the given Ruby.
## Limitations
* Currently does not work on Windows since the builder doesn't build on Windows.
https://github.com/MSP-Greg/actions-ruby is an alternative on Windows.
* This action currently only works with GitHub-hosted runners, not private runners.
## Credits
Most of the Windows logic is from https://github.com/MSP-Greg/actions-ruby by MSP-Greg.
+1 -1
View File
@@ -6,7 +6,7 @@ branding:
icon: download
inputs:
ruby-version:
description: 'Engine and version to use in the format "myruby-X.Y.Z"'
description: 'Engine and version to use, see the syntax in the README'
required: true
outputs:
ruby-prefix:
Generated Vendored
+133 -18
View File
@@ -36,6 +36,8 @@ module.exports =
/******/ // Load entry module and return exports
/******/ return __webpack_require__(104);
/******/ };
/******/ // initialize runtime
/******/ runtime(__webpack_require__);
/******/
/******/ // run startup
/******/ return startup();
@@ -1383,33 +1385,43 @@ const core = __webpack_require__(470)
const io = __webpack_require__(1)
const tc = __webpack_require__(533)
const axios = __webpack_require__(53)
const windows = __webpack_require__(664)
const releasesURL = 'https://github.com/eregon/ruby-install-builder/releases'
const metadataURL = 'https://raw.githubusercontent.com/eregon/ruby-install-builder/metadata'
async function run() {
try {
const platform = getVirtualEnvironmentName()
const ruby = await getRubyEngineAndVersion(core.getInput('ruby-version'))
const rubiesDir = `${process.env.HOME}/.rubies`
await io.mkdirP(rubiesDir)
const platform = getVirtualEnvironmentName()
const tag = await getLatestReleaseTag()
const url = `${releasesURL}/download/${tag}/${ruby}-${platform}.tar.gz`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await tc.extractTar(downloadPath, rubiesDir)
const rubyPrefix = `${rubiesDir}/${ruby}`
core.addPath(`${rubyPrefix}/bin`)
let rubyPrefix
if (platform === 'windows-latest') {
rubyPrefix = await windows.downloadExtractAndSetPATH(ruby)
} else {
rubyPrefix = await downloadAndExtract(platform, ruby)
core.addPath(`${rubyPrefix}/bin`)
}
core.setOutput('ruby-prefix', rubyPrefix)
} catch (error) {
core.setFailed(error.message)
}
}
async function downloadAndExtract(platform, ruby) {
const rubiesDir = `${process.env.HOME}/.rubies`
await io.mkdirP(rubiesDir)
const tag = await getLatestReleaseTag()
const url = `${releasesURL}/download/${tag}/${ruby}-${platform}.tar.gz`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await tc.extractTar(downloadPath, rubiesDir)
return `${rubiesDir}/${ruby}`
}
async function getLatestReleaseTag() {
const response = await axios.get(`${metadataURL}/latest_release.tag`)
return response.data.trim()
@@ -1431,16 +1443,19 @@ async function getRubyEngineAndVersion(rubyVersion) {
const stableVersions = response.data
const engineVersions = stableVersions[engine]
if (!engineVersions) {
throw new Error(`Unknown engine ${engine} (${rubyVersion})`)
throw new Error(`Unknown engine ${engine} (input: ${rubyVersion})`)
}
if (!engineVersions.includes(version)) {
engineVersions.reverse() // inplace!
let found = engineVersions.find(v => v.startsWith(version))
const latestToFirstVersion = engineVersions.slice().reverse()
const found = latestToFirstVersion.find(v => v.startsWith(version))
if (found) {
version = found
} else {
throw new Error(`Unknown version ${version} (${rubyVersion})`)
throw new Error(`Unknown version ${version} for ${engine}
input: ${rubyVersion}
available versions for ${engine}: ${engineVersions.join(', ')}
File an issue at https://github.com/eregon/ruby-install-builder/issues if would like support for a new version`)
}
}
@@ -6437,6 +6452,79 @@ function plural(ms, n, name) {
}
/***/ }),
/***/ 664:
/***/ (function(__unusedmodule, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "downloadExtractAndSetPATH", function() { return downloadExtractAndSetPATH; });
// Most of this logic is from
// https://github.com/MSP-Greg/actions-ruby/blob/master/lib/main.js
const core = __webpack_require__(470)
const exec = __webpack_require__(986)
const tc = __webpack_require__(533)
const releasesURL = 'https://github.com/oneclick/rubyinstaller2/releases'
async function downloadExtractAndSetPATH(ruby) {
const version = ruby.split('-', 2)[1]
if (!ruby.startsWith('ruby-') || version.startsWith('2.3')) {
throw new Error(`Only ruby >= 2.4 is supported on Windows currently (input: ${ruby})`)
}
const tag = `RubyInstaller-${version}-1`
const base = `${tag.toLowerCase()}-x64`
const url = `${releasesURL}/download/${tag}/${base}.7z`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await exec.exec(`7z x ${downloadPath} -xr!${base}\\share\\doc -oC:\\`)
const rubyPrefix = `C:\\${base}`
const msys2 = await linkMSYS2()
const newPath = setupPath(msys2, rubyPrefix)
core.exportVariable('PATH', newPath)
return rubyPrefix
}
async function linkMSYS2() {
const toolCacheVersions = tc.findAllVersions('Ruby')
toolCacheVersions.sort()
if (toolCacheVersions.length == 0) {
throw new Error('Could not find MSYS2 in the toolcache')
}
const latestVersion = toolCacheVersions.slice(-1)[0]
const latestHostedRuby = tc.find('Ruby', latestVersion)
const hostedMSYS2 = `${latestHostedRuby}\\msys64`
const msys2 = 'C:\\msys64'
await exec.exec(`cmd /c mklink /D ${msys2} ${hostedMSYS2}`)
return msys2
}
function setupPath(msys2, rubyPrefix) {
let path = process.env['PATH'].split(';')
// Remove conflicting dev tools from PATH
path = path.filter(e => !e.match(/\b(Chocolatey|CMake|mingw64|OpenSSL|Strawberry)\b/))
// Remove default Ruby in PATH
path = path.filter(e => !e.match(/\bRuby\b/))
// Add MSYS2 in PATH
path.unshift(`${msys2}\\mingw64`, `${msys2}\\usr`)
// Add the downloaded Ruby in PATH
path.unshift(`${rubyPrefix}\\bin`)
return path.join(';')
}
/***/ }),
/***/ 669:
@@ -8759,4 +8847,31 @@ exports.exec = exec;
/***/ })
/******/ });
/******/ },
/******/ function(__webpack_require__) { // webpackRuntimeModules
/******/ "use strict";
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getter */
/******/ !function() {
/******/ // define getter function for harmony exports
/******/ var hasOwnProperty = Object.prototype.hasOwnProperty;
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!hasOwnProperty.call(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/ }();
/******/
/******/ }
);
+30 -17
View File
@@ -4,33 +4,43 @@ const core = require('@actions/core')
const io = require('@actions/io')
const tc = require('@actions/tool-cache')
const axios = require('axios')
const windows = require('./windows')
const releasesURL = 'https://github.com/eregon/ruby-install-builder/releases'
const metadataURL = 'https://raw.githubusercontent.com/eregon/ruby-install-builder/metadata'
async function run() {
try {
const platform = getVirtualEnvironmentName()
const ruby = await getRubyEngineAndVersion(core.getInput('ruby-version'))
const rubiesDir = `${process.env.HOME}/.rubies`
await io.mkdirP(rubiesDir)
const platform = getVirtualEnvironmentName()
const tag = await getLatestReleaseTag()
const url = `${releasesURL}/download/${tag}/${ruby}-${platform}.tar.gz`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await tc.extractTar(downloadPath, rubiesDir)
const rubyPrefix = `${rubiesDir}/${ruby}`
core.addPath(`${rubyPrefix}/bin`)
let rubyPrefix
if (platform === 'windows-latest') {
rubyPrefix = await windows.downloadExtractAndSetPATH(ruby)
} else {
rubyPrefix = await downloadAndExtract(platform, ruby)
core.addPath(`${rubyPrefix}/bin`)
}
core.setOutput('ruby-prefix', rubyPrefix)
} catch (error) {
core.setFailed(error.message)
}
}
async function downloadAndExtract(platform, ruby) {
const rubiesDir = `${process.env.HOME}/.rubies`
await io.mkdirP(rubiesDir)
const tag = await getLatestReleaseTag()
const url = `${releasesURL}/download/${tag}/${ruby}-${platform}.tar.gz`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await tc.extractTar(downloadPath, rubiesDir)
return `${rubiesDir}/${ruby}`
}
async function getLatestReleaseTag() {
const response = await axios.get(`${metadataURL}/latest_release.tag`)
return response.data.trim()
@@ -52,16 +62,19 @@ async function getRubyEngineAndVersion(rubyVersion) {
const stableVersions = response.data
const engineVersions = stableVersions[engine]
if (!engineVersions) {
throw new Error(`Unknown engine ${engine} (${rubyVersion})`)
throw new Error(`Unknown engine ${engine} (input: ${rubyVersion})`)
}
if (!engineVersions.includes(version)) {
engineVersions.reverse() // inplace!
let found = engineVersions.find(v => v.startsWith(version))
const latestToFirstVersion = engineVersions.slice().reverse()
const found = latestToFirstVersion.find(v => v.startsWith(version))
if (found) {
version = found
} else {
throw new Error(`Unknown version ${version} (${rubyVersion})`)
throw new Error(`Unknown version ${version} for ${engine}
input: ${rubyVersion}
available versions for ${engine}: ${engineVersions.join(', ')}
File an issue at https://github.com/eregon/ruby-install-builder/issues if would like support for a new version`)
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
"description": "Download a prebuilt ruby and add it to $PATH",
"main": "index.js",
"scripts": {
"lint": "eslint index.js",
"lint": "eslint *.js",
"package": "ncc build index.js -o dist"
},
"repository": {
+63
View File
@@ -0,0 +1,63 @@
// Most of this logic is from
// https://github.com/MSP-Greg/actions-ruby/blob/master/lib/main.js
const core = require('@actions/core')
const exec = require('@actions/exec')
const tc = require('@actions/tool-cache')
const releasesURL = 'https://github.com/oneclick/rubyinstaller2/releases'
export async function downloadExtractAndSetPATH(ruby) {
const version = ruby.split('-', 2)[1]
if (!ruby.startsWith('ruby-') || version.startsWith('2.3')) {
throw new Error(`Only ruby >= 2.4 is supported on Windows currently (input: ${ruby})`)
}
const tag = `RubyInstaller-${version}-1`
const base = `${tag.toLowerCase()}-x64`
const url = `${releasesURL}/download/${tag}/${base}.7z`
console.log(url)
const downloadPath = await tc.downloadTool(url)
await exec.exec(`7z x ${downloadPath} -xr!${base}\\share\\doc -oC:\\`)
const rubyPrefix = `C:\\${base}`
const msys2 = await linkMSYS2()
const newPath = setupPath(msys2, rubyPrefix)
core.exportVariable('PATH', newPath)
return rubyPrefix
}
async function linkMSYS2() {
const toolCacheVersions = tc.findAllVersions('Ruby')
toolCacheVersions.sort()
if (toolCacheVersions.length == 0) {
throw new Error('Could not find MSYS2 in the toolcache')
}
const latestVersion = toolCacheVersions.slice(-1)[0]
const latestHostedRuby = tc.find('Ruby', latestVersion)
const hostedMSYS2 = `${latestHostedRuby}\\msys64`
const msys2 = 'C:\\msys64'
await exec.exec(`cmd /c mklink /D ${msys2} ${hostedMSYS2}`)
return msys2
}
function setupPath(msys2, rubyPrefix) {
let path = process.env['PATH'].split(';')
// Remove conflicting dev tools from PATH
path = path.filter(e => !e.match(/\b(Chocolatey|CMake|mingw64|OpenSSL|Strawberry)\b/))
// Remove default Ruby in PATH
path = path.filter(e => !e.match(/\bRuby\b/))
// Add MSYS2 in PATH
path.unshift(`${msys2}\\mingw64`, `${msys2}\\usr`)
// Add the downloaded Ruby in PATH
path.unshift(`${rubyPrefix}\\bin`)
return path.join(';')
}