Compare commits

...
37 Commits
Author SHA1 Message Date
Benoit Daloze 6647273ce9 Add support for Ubuntu 20.04 2020-06-07 13:16:44 +02:00
Benoit Daloze 071acb9122 Add script to conveniently print versions for ruby-builder 2020-06-07 13:00:19 +02:00
Benoit Daloze ba5b846810 Add TruffleRuby 20.1.0 2020-06-06 17:04:00 +02:00
Benoit Daloze 81be0938f7 Add an exported setupRuby() function which can be called from other actions
* Inputs are passed as simple object properties.
* It is recommended to expose the same inputs for other actions.
* See #58 and #33.
2020-06-06 13:52:42 +02:00
Benoit Daloze b04e5b8846 Use Bundler 1 on Ruby 2.3
* At least until there is a new Bundler 2 release fixing this.
* Fixes https://github.com/ruby/setup-ruby/issues/51
2020-06-06 13:16:46 +02:00
Benoit Daloze a7df86edc6 A separate bundle config path vendor/bundle is needed for older Bundler
* See https://github.com/ruby/setup-ruby/pull/53#issuecomment-624827273
2020-05-16 18:55:34 +02:00
Scott Jacobsen 8137829321 Use the new deployment true config setting 2020-05-16 18:52:00 +02:00
Scott Jacobsen a1d280134e Use the --deployment flag for bundle install
`bundle install --deployment` should be used on CI environments - it sets additional options beyond the install path (ensures the Gemfile.lock is checked in, up to date, etc). https://bundler.io/v2.0/man/bundle-install.1.html#DEPLOYMENT-MODE
2020-05-16 18:52:00 +02:00
Benoit Daloze d01e942f09 Link to condition and expression syntax docs too 2020-05-15 13:48:07 +02:00
Benoit Daloze e74945bcae Update README example workflows
* Show how to continue-on-error for head builds.
* Use the typical `bundle install` + `bundle exec rake` commands.
2020-05-15 13:29:19 +02:00
Benoit Daloze 8bff4379b9 Ruby 2.4 is EOL 2020-05-15 13:22:42 +02:00
Benoit Daloze 23b9735206 Fix checks for head versions
* Always use common.isHeadVersion().
2020-05-15 13:01:01 +02:00
Benoit Daloze 002b15eeca Add support for ruby master debug builds 2020-05-13 23:48:52 +02:00
Benoit Daloze e5857dbffe Pass the validated engine and version to install() 2020-05-13 23:36:33 +02:00
Benoit Daloze 381e2639aa Update all dependencies 2020-04-29 20:36:28 +02:00
Benoit Daloze d4032b551d The release workflow needs a full checkout 2020-04-18 14:01:20 +02:00
Benoit Daloze da846ef6db Add a workflow to automatically bump the v1 branch when publishing a release 2020-04-18 13:51:50 +02:00
Benoit Daloze 1fe99df431 Rename CI job back to test 2020-04-18 13:36:48 +02:00
Benoit Daloze c28669c4da Mention the new working-directory input in the README 2020-04-18 13:34:32 +02:00
Benoit Daloze 9f60be7c73 Extract main logic in its own function
* So there isn't a giant try/catch around it.
2020-04-18 13:24:09 +02:00
Chris Bailey 29eefdda13 Add support for setting a working directory 2020-04-18 13:22:34 +02:00
Benoit Daloze ec106b438a Document the consequences of using a specific version or commit sha 2020-04-09 19:25:18 +02:00
Benoit Daloze d7f9647ad8 Move Versioning earlier in README 2020-04-09 19:09:20 +02:00
Benoit Daloze f25e77d702 Do not show a "Installing Bundler" group if bundler: none
* That was rather confusing.
2020-04-05 20:04:22 +02:00
Benoit Daloze 463c3a8161 Simplify conditions 2020-04-05 14:46:21 +02:00
Benoit Daloze 63190648f4 Add some spacing in workflow 2020-04-05 14:44:43 +02:00
Benoit Daloze aec70617e0 Let CI run on pushes to master 2020-04-05 14:43:13 +02:00
Benoit Daloze 759c98774b Merge CI in a single workflow with the new include syntax 2020-04-05 14:25:26 +02:00
Benoit Daloze 24d7979773 Simplify os syntax in CI to avoid so many '-latest' 2020-04-05 14:18:41 +02:00
Benoit Daloze 56996937ab Clarify messages about the shipped Bundler being reused 2020-04-05 14:16:21 +02:00
Benoit Daloze e9b0369f85 Add groups to clarify output and measure the time each group takes 2020-04-05 14:09:18 +02:00
Benoit Daloze 045dd42354 Fix indentation 2020-04-05 13:51:43 +02:00
Benoit Daloze 152ff008a3 Extract utility methods to common.js 2020-04-05 13:27:45 +02:00
Benoit Daloze d4f9058279 Reorder 2020-04-03 23:59:35 +02:00
Benoit Daloze c40ce85201 Do not install Bundler 2 for ruby-head since it already ships a version that might work better 2020-04-03 23:58:23 +02:00
Benoit Daloze c68e25cb8c Explicitly use Bundler 2 if there is no version specified
* Avoid issues when using --conservative as seen in
  https://github.com/ruby/setup-ruby/pull/48, clarifies what's getting
  installed and simplifies the following logic.
* We'll probably need changes when Bundler 3 comes out anyway.
2020-04-03 23:57:16 +02:00
MSP-Greg 95135e9903 README.md - remove reference to MSP-Greg/actions-ruby
Preferred repo is now MSP-Greg/setup-ruby-pkgs
2020-04-03 23:42:22 +02:00
12 changed files with 551 additions and 345 deletions
+12
View File
@@ -0,0 +1,12 @@
name: Update the v1 branch when a release is published
on:
release:
types: [published]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- run: git push origin HEAD:v1
+22 -68
View File
@@ -3,38 +3,43 @@ on:
pull_request: pull_request:
push: push:
branches-ignore: branches-ignore:
- master
- v1 - v1
tags-ignore: tags-ignore:
- '*' - '*'
paths-ignore: paths-ignore:
- README.md - README.md
jobs: jobs:
common: test:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ] os: [ ubuntu, macos, windows ]
# Use various version syntaxes here for testing # Use various version syntax here for testing
ruby: [ 2.2, 2.3, 2.4, 2.5, 2.6.6, 2.7, ruby-head, jruby-9.1, jruby, jruby-head, truffleruby, truffleruby-head ] ruby: [ 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 ]
include:
- { os: ubuntu, ruby: rubinius }
- { os: windows, ruby: mingw }
- { os: windows, ruby: mswin }
exclude: exclude:
- os: windows-latest - { os: windows, ruby: debug }
ruby: truffleruby - { os: windows, ruby: truffleruby }
- os: windows-latest - { os: windows, ruby: truffleruby-head }
ruby: truffleruby-head
name: ${{ matrix.os }} ${{ matrix.ruby }} name: ${{ matrix.os }} ${{ matrix.ruby }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: ./ - uses: ./
with: with:
ruby-version: ${{ matrix.ruby }} ruby-version: ${{ matrix.ruby }}
- run: ruby -v - run: ruby -v
- name: build compiler - name: build compiler
run: | run: |
ruby -e "puts 'build compiler: ' + RbConfig::CONFIG.fetch('CC_VERSION_MESSAGE', 'unknown').lines.first" ruby -e "puts 'build compiler: ' + RbConfig::CONFIG.fetch('CC_VERSION_MESSAGE', 'unknown').lines.first"
- name: gcc and ridk version (mingw) - name: gcc and ridk version (mingw)
if: startsWith(matrix.os, 'windows') if: matrix.os == 'windows'
run: | run: |
$abi, $plat = $(ruby -e "STDOUT.write RbConfig::CONFIG['ruby_version'] + ' ' + RUBY_PLATFORM").split(' ') $abi, $plat = $(ruby -e "STDOUT.write RbConfig::CONFIG['ruby_version'] + ' ' + RUBY_PLATFORM").split(' ')
if ($plat.Contains('mingw')) { if ($plat.Contains('mingw')) {
@@ -45,76 +50,25 @@ jobs:
echo 'ridk is unavailable' echo 'ridk is unavailable'
} }
} }
- name: Subprocess test
run: ruby test_subprocess.rb
- name: OpenSSL version
run: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
- name: OpenSSL test
run: ruby -ropen-uri -e 'puts open(%{https://rubygems.org/}) { |f| f.read(1024) }'
- name: C extension test
run: gem install json:2.2.0 --no-document
- run: bundle --version
- run: bundle install
- run: bundle exec rake --version
- name: which ruby, rake
if: startsWith(matrix.os, 'windows') == false
run: which -a ruby rake
- name: where ruby, rake
if: startsWith(matrix.os, 'windows')
run: |
$ErrorActionPreference = 'Continue'
$where = 'ruby', 'rake'
foreach ($e in $where) {
$rslt = where.exe $e 2>&1 | Out-String
if ($rslt.contains($e)) { echo $rslt.Trim() }
else { echo "Can't find $e" }
echo ''
}
specials:
strategy:
fail-fast: false
matrix:
cfg:
- { ruby: rubinius, os: ubuntu-18.04 }
- { ruby: mingw , os: windows-latest }
- { ruby: mswin , os: windows-latest }
name: ${{ matrix.cfg.os }} ${{ matrix.cfg.ruby }}
runs-on: ${{ matrix.cfg.os }}
steps:
- uses: actions/checkout@v2
- uses: ./
with:
ruby-version: ${{ matrix.cfg.ruby }}
- run: ruby -v
- name: build compiler
run: |
ruby -e "puts 'build compiler: ' + RbConfig::CONFIG.fetch('CC_VERSION_MESSAGE', 'unknown').lines.first"
- name: gcc and ridk version (mingw)
if: startsWith(matrix.os, 'windows')
run: |
$abi, $plat = $(ruby -e "STDOUT.write RbConfig::CONFIG['ruby_version'] + ' ' + RUBY_PLATFORM").split(' ')
if ($plat.Contains('mingw')) {
gcc --version
if ($abi -ge '2.4') {
ridk version
} else {
echo 'ridk is unavailable'
}
}
- name: Subprocess test - name: Subprocess test
run: ruby test_subprocess.rb run: ruby test_subprocess.rb
- name: OpenSSL version - name: OpenSSL version
run: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION' run: ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
- name: OpenSSL test - name: OpenSSL test
run: ruby -ropen-uri -e 'puts open(%{https://rubygems.org/}) { |f| f.read(1024) }' run: ruby -ropen-uri -e 'puts open(%{https://rubygems.org/}) { |f| f.read(1024) }'
- name: C extension test - name: C extension test
run: gem install json:2.2.0 --no-document run: gem install json:2.2.0 --no-document
- run: bundle --version - run: bundle --version
- run: bundle install - run: bundle install
- run: bundle exec rake --version - run: bundle exec rake --version
- name: which ruby, rake
if: matrix.os != 'windows'
run: which -a ruby rake
- name: where ruby, rake - name: where ruby, rake
if: startsWith(matrix.cfg.os, 'windows') if: matrix.os == 'windows'
run: | run: |
$ErrorActionPreference = 'Continue' $ErrorActionPreference = 'Continue'
$where = 'ruby', 'rake' $where = 'ruby', 'rake'
+38 -17
View File
@@ -14,11 +14,12 @@ This action currently supports these versions of MRI, JRuby and TruffleRuby:
| Interpreter | Versions | | Interpreter | Versions |
| ----------- | -------- | | ----------- | -------- |
| Ruby | 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.1, head, mingw, mswin | | Ruby | 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.1, head, debug, mingw, mswin |
| JRuby | 9.1.17.0, 9.2.9.0 - 9.2.11.1, head | | JRuby | 9.1.17.0, 9.2.9.0 - 9.2.11.1, head |
| TruffleRuby | 19.3.0 - 20.0.0, head | | TruffleRuby | 19.3.0 - 20.1.0, head |
| Rubinius | 4.14 | | Rubinius | 4.14 |
`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.
Ruby 2.2 resolves to 2.2.6 on Windows (last build from RubyInstaller) and 2.2.10 otherwise. Ruby 2.2 resolves to 2.2.6 on Windows (last build from RubyInstaller) and 2.2.10 otherwise.
@@ -34,7 +35,7 @@ The action works for all [GitHub-hosted runners](https://help.github.com/en/acti
| Operating System | Versions | | Operating System | Versions |
| ----------- | -------- | | ----------- | -------- |
| Ubuntu | `ubuntu-latest` (= `ubuntu-18.04`), `ubuntu-16.04` | | Ubuntu | `ubuntu-20.04`, `ubuntu-latest` (= `ubuntu-18.04`), `ubuntu-16.04` |
| macOS | `macos-latest` | | macOS | `macos-latest` |
| Windows | `windows-latest` | | Windows | `windows-latest` |
@@ -63,13 +64,14 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1 - uses: ruby/setup-ruby@v1
with: with:
ruby-version: 2.6 ruby-version: 2.6 # Not needed with a .ruby-version file
- run: ruby -v - run: bundle install
- run: bundle exec rake
``` ```
### Matrix ### Matrix
This matrix tests all stable releases of MRI, JRuby and TruffleRuby on Ubuntu and macOS. This matrix tests all stable releases and `head` versions of MRI, JRuby and TruffleRuby on Ubuntu and macOS.
```yaml ```yaml
name: My workflow name: My workflow
@@ -79,17 +81,23 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ ubuntu-latest, macos-latest ] os: [ubuntu, macos]
ruby: [ 2.4, 2.5, 2.6, 2.7, jruby, truffleruby ] ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]
runs-on: ${{ matrix.os }} 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
with: with:
ruby-version: ${{ matrix.ruby }} ruby-version: ${{ matrix.ruby }}
- run: ruby -v - run: bundle install
- run: bundle exec rake
``` ```
See the GitHub Actions documentation for more details about the
[workflow syntax](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions)
and the [condition and expression syntax](https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions).
### Supported Version Syntax ### Supported Version Syntax
* engine-version like `ruby-2.6.5` and `truffleruby-19.3.0` * engine-version like `ruby-2.6.5` and `truffleruby-19.3.0`
@@ -104,7 +112,7 @@ jobs:
By default, if there is a `Gemfile.lock` file with a `BUNDLED WITH` section, By default, if there is a `Gemfile.lock` file with a `BUNDLED WITH` section,
the latest version of Bundler with the same major version will be installed. the latest version of Bundler with the same major version will be installed.
Otherwise, the latest Bundler version is installed (except for Ruby 2.2 where only Bundler 1 is supported). Otherwise, the latest Bundler version is installed (except for Ruby 2.2 and 2.3 where only Bundler 1 is supported).
This behavior can be customized, see [action.yml](action.yml) for details about the `bundler` input. This behavior can be customized, see [action.yml](action.yml) for details about the `bundler` input.
@@ -121,8 +129,9 @@ You can cache the installed gems with these two steps:
bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby }}- bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby }}-
- name: bundle install - name: bundle install
run: | run: |
bundle config deployment true
bundle config path vendor/bundle bundle config path vendor/bundle
bundle install --jobs 4 --retry 3 bundle install --jobs 4
``` ```
When using a single OS, replace `${{ matrix.os }}` with the OS. When using a single OS, replace `${{ matrix.os }}` with the OS.
@@ -134,6 +143,11 @@ This uses the [cache action](https://github.com/actions/cache).
The code above is a more complete version of the [Ruby - Bundler example](https://github.com/actions/cache/blob/master/examples.md#ruby---bundler). The code above is a more complete version of the [Ruby - Bundler example](https://github.com/actions/cache/blob/master/examples.md#ruby---bundler).
Make sure to include `use-ruby` in the `key` to avoid conflicting with previous caches. Make sure to include `use-ruby` in the `key` to avoid conflicting with previous caches.
### Working Directory
The `working-directory` input can be set to resolve `.ruby-version`, `.tool-versions` and `Gemfile.lock`
if they are not at the root of the repository, see [action.yml](action.yml) for details.
## Windows ## Windows
Note that running CI on Windows can be quite challenging if you are not very familiar with Windows. Note that running CI on Windows can be quite challenging if you are not very familiar with Windows.
@@ -146,15 +160,22 @@ It is recommended to first get your build working on Ubuntu and macOS before try
* For Ruby < 2.4, the DevKit MSYS tools are installed and prepended to the `Path`. * For Ruby < 2.4, the DevKit MSYS tools are installed and prepended to the `Path`.
* JRuby on Windows has a known bug that `bundle exec rake` [fails](https://github.com/ruby/setup-ruby/issues/18). * JRuby on Windows has a known bug that `bundle exec rake` [fails](https://github.com/ruby/setup-ruby/issues/18).
## Limitations
* This action currently only works with GitHub-hosted runners, not private runners.
## Versioning ## Versioning
It is highly recommended to use `ruby/setup-ruby@v1` for the version of this action.
This will provide the best experience by automatically getting bug fixes, new Ruby versions and new features.
If you instead choose a specific version (v1.2.3) or a commit sha, there will be no automatic bug fixes and
it will be your responsibility to update every time the action no longer works.
Make sure to always use the latest release before reporting an issue on GitHub.
This action follows semantic versioning with a moving `v1` branch. This action follows semantic versioning with a moving `v1` branch.
This follows the [recommendations](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md) of GitHub Actions. This follows the [recommendations](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md) of GitHub Actions.
## Limitations
* This action currently only works with GitHub-hosted runners, not private runners.
## History ## History
This action used to be at `eregon/use-ruby-action` and was moved to the `ruby` organization. This action used to be at `eregon/use-ruby-action` and was moved to the `ruby` organization.
@@ -163,5 +184,5 @@ Please [update](https://github.com/ruby/setup-ruby/releases/tag/v1.13.0) if you
## Credits ## Credits
The current maintainer of this action is @eregon. The current maintainer of this action is @eregon.
Most of the Windows logic is from https://github.com/MSP-Greg/actions-ruby by MSP-Greg. Most of the Windows logic is based on work by MSP-Greg.
Many thanks to MSP-Greg and Lars Kanis for the help with Ruby Installer. Many thanks to MSP-Greg and Lars Kanis for the help with Ruby Installer.
+5 -1
View File
@@ -6,13 +6,17 @@ branding:
icon: download icon: download
inputs: inputs:
ruby-version: ruby-version:
description: 'Engine and version to use, see the syntax in the README. Reads from .ruby-version if unset.' description: 'Engine and version to use, see the syntax in the README. Reads from .ruby-version or .tool-versions if unset.'
required: false required: false
default: 'default' default: 'default'
bundler: bundler:
description: 'The version of Bundler to install. Either none, 1, 2, latest or Gemfile.lock. The default tries Gemfile.lock and otherwise uses latest.' description: 'The version of Bundler to install. Either none, 1, 2, latest or Gemfile.lock. The default tries Gemfile.lock and otherwise uses latest.'
required: false required: false
default: 'default' default: 'default'
working-directory:
description: 'The working directory to use for resolving paths for .ruby-version, .tool-versions and Gemfile.lock.'
required: false
default: '.'
outputs: outputs:
ruby-prefix: ruby-prefix:
description: 'The prefix of the installed ruby' description: 'The prefix of the installed ruby'
+44
View File
@@ -0,0 +1,44 @@
const os = require('os')
const fs = require('fs')
const core = require('@actions/core')
const { performance } = require('perf_hooks')
export async function measure(name, block) {
return await core.group(name, async () => {
const start = performance.now()
try {
return await block()
} finally {
const end = performance.now()
const duration = (end - start) / 1000.0
console.log(`Took ${duration.toFixed(2).padStart(6)} seconds`)
}
})
}
export function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'debug' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
export function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
return `ubuntu-${findUbuntuVersion()}`
} else if (platform === 'darwin') {
return 'macos-latest'
} else if (platform === 'win32') {
return 'windows-latest'
} else {
throw new Error(`Unknown platform ${platform}`)
}
}
function findUbuntuVersion() {
const lsb_release = fs.readFileSync('/etc/lsb-release', 'utf8')
const match = lsb_release.match(/^DISTRIB_RELEASE=(\d+\.\d+)$/m)
if (match) {
return match[1]
} else {
throw new Error('Could not find Ubuntu version')
}
}
Generated Vendored
+279 -143
View File
@@ -356,13 +356,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const os = __webpack_require__(87); const os = __importStar(__webpack_require__(87));
const events = __webpack_require__(614); const events = __importStar(__webpack_require__(614));
const child = __webpack_require__(129); const child = __importStar(__webpack_require__(129));
const path = __webpack_require__(622); const path = __importStar(__webpack_require__(622));
const io = __webpack_require__(1); const io = __importStar(__webpack_require__(1));
const ioUtil = __webpack_require__(672); const ioUtil = __importStar(__webpack_require__(672));
/* eslint-disable @typescript-eslint/unbound-method */ /* eslint-disable @typescript-eslint/unbound-method */
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
/* /*
@@ -806,6 +813,12 @@ class ToolRunner extends events.EventEmitter {
resolve(exitCode); resolve(exitCode);
} }
}); });
if (this.options.input) {
if (!cp.stdin) {
throw new Error('child process missing stdin');
}
cp.stdin.end(this.options.input);
}
}); });
}); });
} }
@@ -956,41 +969,64 @@ module.exports = require("os");
"use strict"; "use strict";
__webpack_require__.r(__webpack_exports__); __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "run", function() { return run; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "run", function() { return run; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setupRuby", function() { return setupRuby; });
const os = __webpack_require__(87) const os = __webpack_require__(87)
const fs = __webpack_require__(747) const fs = __webpack_require__(747)
const path = __webpack_require__(622) const path = __webpack_require__(622)
const core = __webpack_require__(470) const core = __webpack_require__(470)
const exec = __webpack_require__(986) const exec = __webpack_require__(986)
const common = __webpack_require__(239)
const inputDefaults = {
'ruby-version': 'default',
'bundler': 'default',
'working-directory': '.',
}
async function run() { async function run() {
try { try {
const platform = getVirtualEnvironmentName() const options = {}
const [engine, version] = parseRubyEngineAndVersion(core.getInput('ruby-version')) for (const key in inputDefaults) {
options[key] = core.getInput(key)
let installer
if (platform === 'windows-latest' && engine !== 'jruby') {
installer = __webpack_require__(826)
} else {
installer = __webpack_require__(489)
} }
await setupRuby(options)
const engineVersions = installer.getAvailableVersions(platform, engine)
const ruby = validateRubyEngineAndVersion(platform, engineVersions, engine, version)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, ruby)
setupPath(ruby, newPathEntries)
await installBundler(platform, rubyPrefix, engine, version)
core.setOutput('ruby-prefix', rubyPrefix)
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error.message)
} }
} }
async function setupRuby(options) {
const inputs = { ...inputDefaults, ...options }
process.chdir(inputs['working-directory'])
const platform = common.getVirtualEnvironmentName()
const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version'])
let installer
if (platform === 'windows-latest' && engine !== 'jruby') {
installer = __webpack_require__(826)
} else {
installer = __webpack_require__(489)
}
const engineVersions = installer.getAvailableVersions(platform, engine)
const version = validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, engine, version)
setupPath(newPathEntries)
if (inputs['bundler'] !== 'none') {
await common.measure('Installing Bundler', async () =>
installBundler(inputs['bundler'], platform, rubyPrefix, engine, version))
}
core.setOutput('ruby-prefix', rubyPrefix)
}
function parseRubyEngineAndVersion(rubyVersion) { function parseRubyEngineAndVersion(rubyVersion) {
if (rubyVersion === 'default') { if (rubyVersion === 'default') {
if (fs.existsSync('.ruby-version')) { if (fs.existsSync('.ruby-version')) {
@@ -1013,7 +1049,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
} }
let engine, version let engine, version
if (rubyVersion.match(/^(\d+|head|mingw|mswin)/)) { // X.Y.Z => ruby-X.Y.Z if (rubyVersion.match(/^(\d+)/) || common.isHeadVersion(rubyVersion)) { // X.Y.Z => ruby-X.Y.Z
engine = 'ruby' engine = 'ruby'
version = rubyVersion version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion } else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
@@ -1026,24 +1062,25 @@ function parseRubyEngineAndVersion(rubyVersion) {
return [engine, version] return [engine, version]
} }
function validateRubyEngineAndVersion(platform, engineVersions, engine, version) { function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion) {
if (!engineVersions) { if (!engineVersions) {
throw new Error(`Unknown engine ${engine} on ${platform}`) throw new Error(`Unknown engine ${engine} on ${platform}`)
} }
if (!engineVersions.includes(version)) { let version = parsedVersion
if (!engineVersions.includes(parsedVersion)) {
const latestToFirstVersion = engineVersions.slice().reverse() const latestToFirstVersion = engineVersions.slice().reverse()
const found = latestToFirstVersion.find(v => v !== 'head' && v.startsWith(version)) const found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
if (found) { if (found) {
version = found version = found
} else { } else {
throw new Error(`Unknown version ${version} for ${engine} on ${platform} throw new Error(`Unknown version ${parsedVersion} for ${engine} on ${platform}
available versions for ${engine} on ${platform}: ${engineVersions.join(', ')} available versions for ${engine} on ${platform}: ${engineVersions.join(', ')}
File an issue at https://github.com/ruby/setup-ruby/issues if would like support for a new version`) File an issue at https://github.com/ruby/setup-ruby/issues if would like support for a new version`)
} }
} }
return engine + '-' + version return version
} }
function createGemRC() { function createGemRC() {
@@ -1053,20 +1090,22 @@ function createGemRC() {
} }
} }
function setupPath(ruby, newPathEntries) { function setupPath(newPathEntries) {
const originalPath = process.env['PATH'].split(path.delimiter) const originalPath = process.env['PATH'].split(path.delimiter)
let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry)) let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry))
if (cleanPath.length !== originalPath.length) { if (cleanPath.length !== originalPath.length) {
console.log("Entries removed from PATH to avoid conflicts with Ruby:") core.startGroup('Cleaning PATH')
for (const entry of originalPath) { console.log('Entries removed from PATH to avoid conflicts with Ruby:')
if (!cleanPath.includes(entry)) { for (const entry of originalPath) {
console.log(` ${entry}`) if (!cleanPath.includes(entry)) {
} console.log(` ${entry}`)
} }
} }
core.endGroup()
}
core.exportVariable('PATH', [...newPathEntries, ...cleanPath].join(path.delimiter)) core.exportVariable('PATH', [...newPathEntries, ...cleanPath].join(path.delimiter))
} }
function readBundledWithFromGemfileLock() { function readBundledWithFromGemfileLock() {
@@ -1087,11 +1126,8 @@ function readBundledWithFromGemfileLock() {
return null return null
} }
async function installBundler(platform, rubyPrefix, engine, rubyVersion) { async function installBundler(bundlerVersionInput, platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = core.getInput('bundler') var bundlerVersion = bundlerVersionInput
if (bundlerVersion === 'none') {
return
}
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock() bundlerVersion = readBundledWithFromGemfileLock()
@@ -1100,47 +1136,33 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
} }
} }
let versionArray if (bundlerVersion === 'latest') {
if (rubyVersion.startsWith('2.2')) { bundlerVersion = '2'
console.log('Bundler 2 requires Ruby 2.3+, using Bundler 1 on Ruby 2.2') }
versionArray = ['-v', '~> 1']
} else if (/^\d+/.test(bundlerVersion)) { if (/^\d+/.test(bundlerVersion)) {
versionArray = ['-v', `~> ${bundlerVersion}`] // OK
} else if (bundlerVersion === 'latest') {
versionArray = []
} else { } else {
throw new Error(`Cannot parse bundler input: ${bundlerVersion}`) throw new Error(`Cannot parse bundler input: ${bundlerVersion}`)
} }
if (engine === 'rubinius') { if (rubyVersion.startsWith('2.2')) {
console.log('Bundler 2 requires Ruby 2.3+, using Bundler 1 on Ruby 2.2')
bundlerVersion = '1'
} else if (rubyVersion.startsWith('2.3')) {
console.log('Ruby 2.3 has a bug with Bundler 2 (https://github.com/rubygems/rubygems/issues/3570), using Bundler 1 instead on Ruby 2.3')
bundlerVersion = '1'
}
if (engine === 'ruby' && common.isHeadVersion(rubyVersion) && bundlerVersion === '2') {
console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
} else if (engine === 'truffleruby' && bundlerVersion === '1') {
console.log(`Using Bundler 1 shipped with ${engine}`)
} else if (engine === 'rubinius') {
console.log(`Rubinius only supports the version of Bundler shipped with it`) console.log(`Rubinius only supports the version of Bundler shipped with it`)
} else if (bundlerVersion === '1' && engine === 'truffleruby') {
console.log(`Using the Bundler version shipped with ${engine}`)
} else { } else {
await exec.exec(path.join(rubyPrefix, 'bin', 'gem'), ['install', 'bundler', ...versionArray, '--no-document']) const gem = path.join(rubyPrefix, 'bin', 'gem')
} await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
}
function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
return `ubuntu-${findUbuntuVersion()}`
} else if (platform === 'darwin') {
return 'macos-latest'
} else if (platform === 'win32') {
return 'windows-latest'
} else {
throw new Error(`Unknown platform ${platform}`)
}
}
function findUbuntuVersion() {
const lsb_release = fs.readFileSync('/etc/lsb-release', 'utf8')
const match = lsb_release.match(/^DISTRIB_RELEASE=(\d+\.\d+)$/m)
if (match) {
return match[1]
} else {
throw new Error('Could not find Ubuntu version')
} }
} }
@@ -1458,7 +1480,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.0", "2.7.1",
"head" "head", "debug",
], ],
"jruby": [ "jruby": [
"9.1.17.0", "9.1.17.0",
@@ -1467,7 +1489,7 @@ function getVersions(platform) {
], ],
"truffleruby": [ "truffleruby": [
"19.3.0", "19.3.1", "19.3.0", "19.3.1",
"20.0.0", "20.0.0", "20.1.0",
"head" "head"
] ]
} }
@@ -1489,6 +1511,62 @@ function getVersions(platform) {
module.exports = require("https"); module.exports = require("https");
/***/ }),
/***/ 239:
/***/ (function(__unusedmodule, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* 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__, "getVirtualEnvironmentName", function() { return getVirtualEnvironmentName; });
const os = __webpack_require__(87)
const fs = __webpack_require__(747)
const core = __webpack_require__(470)
const { performance } = __webpack_require__(630)
async function measure(name, block) {
return await core.group(name, async () => {
const start = performance.now()
try {
return await block()
} finally {
const end = performance.now()
const duration = (end - start) / 1000.0
console.log(`Took ${duration.toFixed(2).padStart(6)} seconds`)
}
})
}
function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'debug' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
return `ubuntu-${findUbuntuVersion()}`
} else if (platform === 'darwin') {
return 'macos-latest'
} else if (platform === 'win32') {
return 'windows-latest'
} else {
throw new Error(`Unknown platform ${platform}`)
}
}
function findUbuntuVersion() {
const lsb_release = fs.readFileSync('/etc/lsb-release', 'utf8')
const match = lsb_release.match(/^DISTRIB_RELEASE=(\d+\.\d+)$/m)
if (match) {
return match[1]
} else {
throw new Error('Could not find Ubuntu version')
}
}
/***/ }), /***/ }),
/***/ 280: /***/ 280:
@@ -3473,6 +3551,7 @@ const path = __webpack_require__(622)
const exec = __webpack_require__(986) const exec = __webpack_require__(986)
const io = __webpack_require__(1) const io = __webpack_require__(1)
const tc = __webpack_require__(533) const tc = __webpack_require__(533)
const common = __webpack_require__(239)
const rubyBuilderVersions = __webpack_require__(156) const rubyBuilderVersions = __webpack_require__(156)
const builderReleaseTag = 'enable-shared' const builderReleaseTag = 'enable-shared'
@@ -3482,10 +3561,10 @@ function getAvailableVersions(platform, engine) {
return rubyBuilderVersions.getVersions(platform)[engine] return rubyBuilderVersions.getVersions(platform)[engine]
} }
async function install(platform, ruby) { async function install(platform, engine, version) {
const rubyPrefix = await downloadAndExtract(platform, ruby) const rubyPrefix = await downloadAndExtract(platform, engine, version)
let newPathEntries let newPathEntries
if (ruby.startsWith('rubinius')) { if (engine === 'rubinius') {
newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')] newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')]
} else { } else {
newPathEntries = [path.join(rubyPrefix, 'bin')] newPathEntries = [path.join(rubyPrefix, 'bin')]
@@ -3493,31 +3572,33 @@ async function install(platform, ruby) {
return [rubyPrefix, newPathEntries] return [rubyPrefix, newPathEntries]
} }
async function downloadAndExtract(platform, ruby) { async function downloadAndExtract(platform, engine, version) {
const rubiesDir = path.join(os.homedir(), '.rubies') const rubiesDir = path.join(os.homedir(), '.rubies')
await io.mkdirP(rubiesDir) await io.mkdirP(rubiesDir)
const url = await getDownloadURL(platform, ruby) const downloadPath = await common.measure('Downloading Ruby', async () => {
console.log(url) const url = getDownloadURL(platform, engine, version)
console.log(url)
return await tc.downloadTool(url)
})
const downloadPath = await tc.downloadTool(url)
const tar = platform.startsWith('windows') ? 'C:\\Windows\\system32\\tar.exe' : 'tar' const tar = platform.startsWith('windows') ? 'C:\\Windows\\system32\\tar.exe' : 'tar'
await exec.exec(tar, [ '-xz', '-C', rubiesDir, '-f', downloadPath ]) await common.measure('Extracting Ruby', async () =>
exec.exec(tar, [ '-xz', '-C', rubiesDir, '-f', downloadPath ]))
return path.join(rubiesDir, ruby) return path.join(rubiesDir, `${engine}-${version}`)
} }
function getDownloadURL(platform, ruby) { function getDownloadURL(platform, engine, version) {
if (ruby.endsWith('-head')) { if (common.isHeadVersion(version)) {
return getLatestHeadBuildURL(platform, ruby) return getLatestHeadBuildURL(platform, engine, version)
} else { } else {
return `${releasesURL}/download/${builderReleaseTag}/${ruby}-${platform}.tar.gz` return `${releasesURL}/download/${builderReleaseTag}/${engine}-${version}-${platform}.tar.gz`
} }
} }
function getLatestHeadBuildURL(platform, ruby) { function getLatestHeadBuildURL(platform, engine, version) {
const engine = ruby.split('-')[0] return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-${version}-${platform}.tar.gz`
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-head-${platform}.tar.gz`
} }
@@ -4100,6 +4181,7 @@ var HttpCodes;
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
@@ -4124,8 +4206,18 @@ function getProxyUrl(serverUrl) {
return proxyUrl ? proxyUrl.href : ''; return proxyUrl ? proxyUrl.href : '';
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect]; const HttpRedirectCodes = [
const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout]; HttpCodes.MovedPermanently,
HttpCodes.ResourceMoved,
HttpCodes.SeeOther,
HttpCodes.TemporaryRedirect,
HttpCodes.PermanentRedirect
];
const HttpResponseRetryCodes = [
HttpCodes.BadGateway,
HttpCodes.ServiceUnavailable,
HttpCodes.GatewayTimeout
];
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
const ExponentialBackoffCeiling = 10; const ExponentialBackoffCeiling = 10;
const ExponentialBackoffTimeSlice = 5; const ExponentialBackoffTimeSlice = 5;
@@ -4250,18 +4342,22 @@ class HttpClient {
*/ */
async request(verb, requestUrl, data, headers) { async request(verb, requestUrl, data, headers) {
if (this._disposed) { if (this._disposed) {
throw new Error("Client has already been disposed."); throw new Error('Client has already been disposed.');
} }
let parsedUrl = url.parse(requestUrl); let parsedUrl = url.parse(requestUrl);
let info = this._prepareRequest(verb, parsedUrl, headers); let info = this._prepareRequest(verb, parsedUrl, headers);
// Only perform retries on reads since writes may not be idempotent. // Only perform retries on reads since writes may not be idempotent.
let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1; let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
? this._maxRetries + 1
: 1;
let numTries = 0; let numTries = 0;
let response; let response;
while (numTries < maxTries) { while (numTries < maxTries) {
response = await this.requestRaw(info, data); response = await this.requestRaw(info, data);
// Check if it's an authentication challenge // Check if it's an authentication challenge
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) { if (response &&
response.message &&
response.message.statusCode === HttpCodes.Unauthorized) {
let authenticationHandler; let authenticationHandler;
for (let i = 0; i < this.handlers.length; i++) { for (let i = 0; i < this.handlers.length; i++) {
if (this.handlers[i].canHandleAuthentication(response)) { if (this.handlers[i].canHandleAuthentication(response)) {
@@ -4279,21 +4375,32 @@ class HttpClient {
} }
} }
let redirectsRemaining = this._maxRedirects; let redirectsRemaining = this._maxRedirects;
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&
&& this._allowRedirects this._allowRedirects &&
&& redirectsRemaining > 0) { redirectsRemaining > 0) {
const redirectUrl = response.message.headers["location"]; const redirectUrl = response.message.headers['location'];
if (!redirectUrl) { if (!redirectUrl) {
// if there's no location to redirect to, we won't // if there's no location to redirect to, we won't
break; break;
} }
let parsedRedirectUrl = url.parse(redirectUrl); let parsedRedirectUrl = url.parse(redirectUrl);
if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) { if (parsedUrl.protocol == 'https:' &&
throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true."); parsedUrl.protocol != parsedRedirectUrl.protocol &&
!this._allowRedirectDowngrade) {
throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
} }
// we need to finish reading the response before reassigning response // we need to finish reading the response before reassigning response
// which will leak the open socket. // which will leak the open socket.
await response.readBody(); await response.readBody();
// strip authorization header if redirected to a different hostname
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (let header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
}
}
}
// let's make the request with the new redirectUrl // let's make the request with the new redirectUrl
info = this._prepareRequest(verb, parsedRedirectUrl, headers); info = this._prepareRequest(verb, parsedRedirectUrl, headers);
response = await this.requestRaw(info, data); response = await this.requestRaw(info, data);
@@ -4344,8 +4451,8 @@ class HttpClient {
*/ */
requestRawWithCallback(info, data, onResult) { requestRawWithCallback(info, data, onResult) {
let socket; let socket;
if (typeof (data) === 'string') { if (typeof data === 'string') {
info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8'); info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
} }
let callbackCalled = false; let callbackCalled = false;
let handleResult = (err, res) => { let handleResult = (err, res) => {
@@ -4358,7 +4465,7 @@ class HttpClient {
let res = new HttpClientResponse(msg); let res = new HttpClientResponse(msg);
handleResult(null, res); handleResult(null, res);
}); });
req.on('socket', (sock) => { req.on('socket', sock => {
socket = sock; socket = sock;
}); });
// If we ever get disconnected, we want the socket to timeout eventually // If we ever get disconnected, we want the socket to timeout eventually
@@ -4373,10 +4480,10 @@ class HttpClient {
// res should have headers // res should have headers
handleResult(err, null); handleResult(err, null);
}); });
if (data && typeof (data) === 'string') { if (data && typeof data === 'string') {
req.write(data, 'utf8'); req.write(data, 'utf8');
} }
if (data && typeof (data) !== 'string') { if (data && typeof data !== 'string') {
data.on('close', function () { data.on('close', function () {
req.end(); req.end();
}); });
@@ -4403,31 +4510,34 @@ class HttpClient {
const defaultPort = usingSsl ? 443 : 80; const defaultPort = usingSsl ? 443 : 80;
info.options = {}; info.options = {};
info.options.host = info.parsedUrl.hostname; info.options.host = info.parsedUrl.hostname;
info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort; info.options.port = info.parsedUrl.port
info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); ? parseInt(info.parsedUrl.port)
: defaultPort;
info.options.path =
(info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
info.options.method = method; info.options.method = method;
info.options.headers = this._mergeHeaders(headers); info.options.headers = this._mergeHeaders(headers);
if (this.userAgent != null) { if (this.userAgent != null) {
info.options.headers["user-agent"] = this.userAgent; info.options.headers['user-agent'] = this.userAgent;
} }
info.options.agent = this._getAgent(info.parsedUrl); info.options.agent = this._getAgent(info.parsedUrl);
// gives handlers an opportunity to participate // gives handlers an opportunity to participate
if (this.handlers) { if (this.handlers) {
this.handlers.forEach((handler) => { this.handlers.forEach(handler => {
handler.prepareRequest(info.options); handler.prepareRequest(info.options);
}); });
} }
return info; return info;
} }
_mergeHeaders(headers) { _mergeHeaders(headers) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
} }
return lowercaseKeys(headers || {}); return lowercaseKeys(headers || {});
} }
_getExistingOrDefaultHeader(additionalHeaders, header, _default) { _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {}); const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
let clientHeader; let clientHeader;
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
@@ -4465,7 +4575,7 @@ class HttpClient {
proxyAuth: proxyUrl.auth, proxyAuth: proxyUrl.auth,
host: proxyUrl.hostname, host: proxyUrl.hostname,
port: proxyUrl.port port: proxyUrl.port
}, }
}; };
let tunnelAgent; let tunnelAgent;
const overHttps = proxyUrl.protocol === 'https:'; const overHttps = proxyUrl.protocol === 'https:';
@@ -4492,7 +4602,9 @@ class HttpClient {
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
// we have to cast it to any and change it directly // we have to cast it to any and change it directly
agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false }); agent.options = Object.assign(agent.options || {}, {
rejectUnauthorized: false
});
} }
return agent; return agent;
} }
@@ -4553,7 +4665,7 @@ class HttpClient {
msg = contents; msg = contents;
} }
else { else {
msg = "Failed request: (" + statusCode + ")"; msg = 'Failed request: (' + statusCode + ')';
} }
let err = new Error(msg); let err = new Error(msg);
// attach statusCode and body obj (if available) to the error object // attach statusCode and body obj (if available) to the error object
@@ -4595,6 +4707,13 @@ module.exports = require("path");
/***/ }), /***/ }),
/***/ 630:
/***/ (function(module) {
module.exports = require("perf_hooks");
/***/ }),
/***/ 631: /***/ 631:
/***/ (function(module) { /***/ (function(module) {
@@ -4875,6 +4994,7 @@ const cp = __webpack_require__(129)
const core = __webpack_require__(470) const core = __webpack_require__(470)
const exec = __webpack_require__(986) const exec = __webpack_require__(986)
const tc = __webpack_require__(533) const tc = __webpack_require__(533)
const common = __webpack_require__(239)
const rubyInstallerVersions = __webpack_require__(471).versions const rubyInstallerVersions = __webpack_require__(471).versions
// Extract to SSD, see https://github.com/ruby/setup-ruby/pull/14 // Extract to SSD, see https://github.com/ruby/setup-ruby/pull/14
@@ -4900,18 +5020,21 @@ function getAvailableVersions(platform, engine) {
} }
} }
async function install(platform, ruby) { async function install(platform, engine, version) {
const version = ruby.split('-', 2)[1]
const url = rubyInstallerVersions[version] const url = rubyInstallerVersions[version]
console.log(url)
if (!url.endsWith('.7z')) { if (!url.endsWith('.7z')) {
throw new Error('URL should end in .7z') throw new Error(`URL should end in .7z: ${url}`)
} }
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length) const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
const downloadPath = await tc.downloadTool(url) const downloadPath = await common.measure('Downloading Ruby', async () => {
await exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true }) console.log(url)
return await tc.downloadTool(url)
})
await common.measure('Extracting Ruby', async () =>
exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true }))
const rubyPrefix = `${drive}:\\${base}` const rubyPrefix = `${drive}:\\${base}`
let toolchainPaths = (version === 'mswin') ? let toolchainPaths = (version === 'mswin') ?
@@ -4930,7 +5053,8 @@ async function symLinkToEmbeddedMSYS2() {
} }
const latestVersion = toolCacheVersions.slice(-1)[0] const latestVersion = toolCacheVersions.slice(-1)[0]
const hostedRuby = tc.find('Ruby', latestVersion) const hostedRuby = tc.find('Ruby', latestVersion)
await exec.exec(`cmd /c mklink /D ${msys2} ${hostedRuby}\\msys64`) await common.measure('Linking MSYS2', async () =>
exec.exec(`cmd /c mklink /D ${msys2} ${hostedRuby}\\msys64`))
} }
async function setupMingw(version) { async function setupMingw(version) {
@@ -4938,7 +5062,8 @@ async function setupMingw(version) {
if (version.startsWith('2.2') || version.startsWith('2.3')) { if (version.startsWith('2.2') || version.startsWith('2.3')) {
core.exportVariable('SSL_CERT_FILE', certFile) core.exportVariable('SSL_CERT_FILE', certFile)
await installMSYS(version) await common.measure('Installing MSYS1', async () =>
installMSYS(version))
return msysPathEntries return msysPathEntries
} else { } else {
@@ -4985,7 +5110,10 @@ async function setupMSWin() {
await symLinkToEmbeddedMSYS2() await symLinkToEmbeddedMSYS2()
} }
return [...addVCVARSEnv(), ...msys2PathEntries] const VCPathEntries = await common.measure('Setting up MSVC environment', async () =>
addVCVARSEnv())
return [...VCPathEntries, ...msys2PathEntries]
} }
/* Sets MSVC environment for use in Actions /* Sets MSVC environment for use in Actions
@@ -5043,12 +5171,10 @@ function getProxyUrl(reqUrl) {
} }
let proxyVar; let proxyVar;
if (usingSsl) { if (usingSsl) {
proxyVar = process.env["https_proxy"] || proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
process.env["HTTPS_PROXY"];
} }
else { else {
proxyVar = process.env["http_proxy"] || proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];
process.env["HTTP_PROXY"];
} }
if (proxyVar) { if (proxyVar) {
proxyUrl = url.parse(proxyVar); proxyUrl = url.parse(proxyVar);
@@ -5060,7 +5186,7 @@ function checkBypass(reqUrl) {
if (!reqUrl.hostname) { if (!reqUrl.hostname) {
return false; return false;
} }
let noProxy = process.env["no_proxy"] || process.env["NO_PROXY"] || ''; let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) { if (!noProxy) {
return false; return false;
} }
@@ -5081,7 +5207,10 @@ function checkBypass(reqUrl) {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
} }
// Compare request host against noproxy // Compare request host against noproxy
for (let upperNoProxyItem of noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)) { for (let upperNoProxyItem of noProxy
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) { if (upperReqHosts.some(x => x === upperNoProxyItem)) {
return true; return true;
} }
@@ -5184,8 +5313,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const tr = __webpack_require__(9); const tr = __importStar(__webpack_require__(9));
/** /**
* Exec a command. * Exec a command.
* Output will be streamed to the live console. * Output will be streamed to the live console.
+86 -78
View File
@@ -3,36 +3,58 @@ const fs = require('fs')
const path = require('path') const path = require('path')
const core = require('@actions/core') const core = require('@actions/core')
const exec = require('@actions/exec') const exec = require('@actions/exec')
const common = require('./common')
const inputDefaults = {
'ruby-version': 'default',
'bundler': 'default',
'working-directory': '.',
}
export async function run() { export async function run() {
try { try {
const platform = getVirtualEnvironmentName() const options = {}
const [engine, version] = parseRubyEngineAndVersion(core.getInput('ruby-version')) for (const key in inputDefaults) {
options[key] = core.getInput(key)
let installer
if (platform === 'windows-latest' && engine !== 'jruby') {
installer = require('./windows')
} else {
installer = require('./ruby-builder')
} }
await setupRuby(options)
const engineVersions = installer.getAvailableVersions(platform, engine)
const ruby = validateRubyEngineAndVersion(platform, engineVersions, engine, version)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, ruby)
setupPath(ruby, newPathEntries)
await installBundler(platform, rubyPrefix, engine, version)
core.setOutput('ruby-prefix', rubyPrefix)
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error.message)
} }
} }
export async function setupRuby(options) {
const inputs = { ...inputDefaults, ...options }
process.chdir(inputs['working-directory'])
const platform = common.getVirtualEnvironmentName()
const [engine, parsedVersion] = parseRubyEngineAndVersion(inputs['ruby-version'])
let installer
if (platform === 'windows-latest' && engine !== 'jruby') {
installer = require('./windows')
} else {
installer = require('./ruby-builder')
}
const engineVersions = installer.getAvailableVersions(platform, engine)
const version = validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, engine, version)
setupPath(newPathEntries)
if (inputs['bundler'] !== 'none') {
await common.measure('Installing Bundler', async () =>
installBundler(inputs['bundler'], platform, rubyPrefix, engine, version))
}
core.setOutput('ruby-prefix', rubyPrefix)
}
function parseRubyEngineAndVersion(rubyVersion) { function parseRubyEngineAndVersion(rubyVersion) {
if (rubyVersion === 'default') { if (rubyVersion === 'default') {
if (fs.existsSync('.ruby-version')) { if (fs.existsSync('.ruby-version')) {
@@ -55,7 +77,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
} }
let engine, version let engine, version
if (rubyVersion.match(/^(\d+|head|mingw|mswin)/)) { // X.Y.Z => ruby-X.Y.Z if (rubyVersion.match(/^(\d+)/) || common.isHeadVersion(rubyVersion)) { // X.Y.Z => ruby-X.Y.Z
engine = 'ruby' engine = 'ruby'
version = rubyVersion version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion } else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
@@ -68,24 +90,25 @@ function parseRubyEngineAndVersion(rubyVersion) {
return [engine, version] return [engine, version]
} }
function validateRubyEngineAndVersion(platform, engineVersions, engine, version) { function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion) {
if (!engineVersions) { if (!engineVersions) {
throw new Error(`Unknown engine ${engine} on ${platform}`) throw new Error(`Unknown engine ${engine} on ${platform}`)
} }
if (!engineVersions.includes(version)) { let version = parsedVersion
if (!engineVersions.includes(parsedVersion)) {
const latestToFirstVersion = engineVersions.slice().reverse() const latestToFirstVersion = engineVersions.slice().reverse()
const found = latestToFirstVersion.find(v => v !== 'head' && v.startsWith(version)) const found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
if (found) { if (found) {
version = found version = found
} else { } else {
throw new Error(`Unknown version ${version} for ${engine} on ${platform} throw new Error(`Unknown version ${parsedVersion} for ${engine} on ${platform}
available versions for ${engine} on ${platform}: ${engineVersions.join(', ')} available versions for ${engine} on ${platform}: ${engineVersions.join(', ')}
File an issue at https://github.com/ruby/setup-ruby/issues if would like support for a new version`) File an issue at https://github.com/ruby/setup-ruby/issues if would like support for a new version`)
} }
} }
return engine + '-' + version return version
} }
function createGemRC() { function createGemRC() {
@@ -95,20 +118,22 @@ function createGemRC() {
} }
} }
function setupPath(ruby, newPathEntries) { function setupPath(newPathEntries) {
const originalPath = process.env['PATH'].split(path.delimiter) const originalPath = process.env['PATH'].split(path.delimiter)
let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry)) let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry))
if (cleanPath.length !== originalPath.length) { if (cleanPath.length !== originalPath.length) {
console.log("Entries removed from PATH to avoid conflicts with Ruby:") core.startGroup('Cleaning PATH')
for (const entry of originalPath) { console.log('Entries removed from PATH to avoid conflicts with Ruby:')
if (!cleanPath.includes(entry)) { for (const entry of originalPath) {
console.log(` ${entry}`) if (!cleanPath.includes(entry)) {
} console.log(` ${entry}`)
} }
} }
core.endGroup()
}
core.exportVariable('PATH', [...newPathEntries, ...cleanPath].join(path.delimiter)) core.exportVariable('PATH', [...newPathEntries, ...cleanPath].join(path.delimiter))
} }
function readBundledWithFromGemfileLock() { function readBundledWithFromGemfileLock() {
@@ -129,11 +154,8 @@ function readBundledWithFromGemfileLock() {
return null return null
} }
async function installBundler(platform, rubyPrefix, engine, rubyVersion) { async function installBundler(bundlerVersionInput, platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = core.getInput('bundler') var bundlerVersion = bundlerVersionInput
if (bundlerVersion === 'none') {
return
}
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') { if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock() bundlerVersion = readBundledWithFromGemfileLock()
@@ -142,47 +164,33 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
} }
} }
let versionArray if (bundlerVersion === 'latest') {
if (rubyVersion.startsWith('2.2')) { bundlerVersion = '2'
console.log('Bundler 2 requires Ruby 2.3+, using Bundler 1 on Ruby 2.2') }
versionArray = ['-v', '~> 1']
} else if (/^\d+/.test(bundlerVersion)) { if (/^\d+/.test(bundlerVersion)) {
versionArray = ['-v', `~> ${bundlerVersion}`] // OK
} else if (bundlerVersion === 'latest') {
versionArray = []
} else { } else {
throw new Error(`Cannot parse bundler input: ${bundlerVersion}`) throw new Error(`Cannot parse bundler input: ${bundlerVersion}`)
} }
if (engine === 'rubinius') { if (rubyVersion.startsWith('2.2')) {
console.log('Bundler 2 requires Ruby 2.3+, using Bundler 1 on Ruby 2.2')
bundlerVersion = '1'
} else if (rubyVersion.startsWith('2.3')) {
console.log('Ruby 2.3 has a bug with Bundler 2 (https://github.com/rubygems/rubygems/issues/3570), using Bundler 1 instead on Ruby 2.3')
bundlerVersion = '1'
}
if (engine === 'ruby' && common.isHeadVersion(rubyVersion) && bundlerVersion === '2') {
console.log(`Using Bundler 2 shipped with ${engine}-${rubyVersion}`)
} else if (engine === 'truffleruby' && bundlerVersion === '1') {
console.log(`Using Bundler 1 shipped with ${engine}`)
} else if (engine === 'rubinius') {
console.log(`Rubinius only supports the version of Bundler shipped with it`) console.log(`Rubinius only supports the version of Bundler shipped with it`)
} else if (bundlerVersion === '1' && engine === 'truffleruby') {
console.log(`Using the Bundler version shipped with ${engine}`)
} else { } else {
await exec.exec(path.join(rubyPrefix, 'bin', 'gem'), ['install', 'bundler', ...versionArray, '--no-document']) const gem = path.join(rubyPrefix, 'bin', 'gem')
} await exec.exec(gem, ['install', 'bundler', '-v', `~> ${bundlerVersion}`, '--no-document'])
}
function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
return `ubuntu-${findUbuntuVersion()}`
} else if (platform === 'darwin') {
return 'macos-latest'
} else if (platform === 'win32') {
return 'windows-latest'
} else {
throw new Error(`Unknown platform ${platform}`)
}
}
function findUbuntuVersion() {
const lsb_release = fs.readFileSync('/etc/lsb-release', 'utf8')
const match = lsb_release.match(/^DISTRIB_RELEASE=(\d+\.\d+)$/m)
if (match) {
return match[1]
} else {
throw new Error('Could not find Ubuntu version')
} }
} }
+2 -2
View File
@@ -7,7 +7,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.0", "2.7.1",
"head" "head", "debug",
], ],
"jruby": [ "jruby": [
"9.1.17.0", "9.1.17.0",
@@ -16,7 +16,7 @@ export function getVersions(platform) {
], ],
"truffleruby": [ "truffleruby": [
"19.3.0", "19.3.1", "19.3.0", "19.3.1",
"20.0.0", "20.0.0", "20.1.0",
"head" "head"
] ]
} }
+19 -16
View File
@@ -3,6 +3,7 @@ const path = require('path')
const exec = require('@actions/exec') const exec = require('@actions/exec')
const io = require('@actions/io') const io = require('@actions/io')
const tc = require('@actions/tool-cache') const tc = require('@actions/tool-cache')
const common = require('./common')
const rubyBuilderVersions = require('./ruby-builder-versions') const rubyBuilderVersions = require('./ruby-builder-versions')
const builderReleaseTag = 'enable-shared' const builderReleaseTag = 'enable-shared'
@@ -12,10 +13,10 @@ export function getAvailableVersions(platform, engine) {
return rubyBuilderVersions.getVersions(platform)[engine] return rubyBuilderVersions.getVersions(platform)[engine]
} }
export async function install(platform, ruby) { export async function install(platform, engine, version) {
const rubyPrefix = await downloadAndExtract(platform, ruby) const rubyPrefix = await downloadAndExtract(platform, engine, version)
let newPathEntries let newPathEntries
if (ruby.startsWith('rubinius')) { if (engine === 'rubinius') {
newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')] newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')]
} else { } else {
newPathEntries = [path.join(rubyPrefix, 'bin')] newPathEntries = [path.join(rubyPrefix, 'bin')]
@@ -23,29 +24,31 @@ export async function install(platform, ruby) {
return [rubyPrefix, newPathEntries] return [rubyPrefix, newPathEntries]
} }
async function downloadAndExtract(platform, ruby) { async function downloadAndExtract(platform, engine, version) {
const rubiesDir = path.join(os.homedir(), '.rubies') const rubiesDir = path.join(os.homedir(), '.rubies')
await io.mkdirP(rubiesDir) await io.mkdirP(rubiesDir)
const url = await getDownloadURL(platform, ruby) const downloadPath = await common.measure('Downloading Ruby', async () => {
console.log(url) const url = getDownloadURL(platform, engine, version)
console.log(url)
return await tc.downloadTool(url)
})
const downloadPath = await tc.downloadTool(url)
const tar = platform.startsWith('windows') ? 'C:\\Windows\\system32\\tar.exe' : 'tar' const tar = platform.startsWith('windows') ? 'C:\\Windows\\system32\\tar.exe' : 'tar'
await exec.exec(tar, [ '-xz', '-C', rubiesDir, '-f', downloadPath ]) await common.measure('Extracting Ruby', async () =>
exec.exec(tar, [ '-xz', '-C', rubiesDir, '-f', downloadPath ]))
return path.join(rubiesDir, ruby) return path.join(rubiesDir, `${engine}-${version}`)
} }
function getDownloadURL(platform, ruby) { function getDownloadURL(platform, engine, version) {
if (ruby.endsWith('-head')) { if (common.isHeadVersion(version)) {
return getLatestHeadBuildURL(platform, ruby) return getLatestHeadBuildURL(platform, engine, version)
} else { } else {
return `${releasesURL}/download/${builderReleaseTag}/${ruby}-${platform}.tar.gz` return `${releasesURL}/download/${builderReleaseTag}/${engine}-${version}-${platform}.tar.gz`
} }
} }
function getLatestHeadBuildURL(platform, ruby) { function getLatestHeadBuildURL(platform, engine, version) {
const engine = ruby.split('-')[0] return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-${version}-${platform}.tar.gz`
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-head-${platform}.tar.gz`
} }
+15
View File
@@ -0,0 +1,15 @@
hash = File.read('ruby-builder-versions.js')[/\bversions = {[^}]+}/]
versions = eval hash
by_minor = versions[:ruby].group_by { |v| v[/^\d\.\d/] }
p by_minor['2.2']
p by_minor['2.3']
(4..7).each do |minor|
p by_minor["2.#{minor}"].map { |v| "ruby-#{v}" }
end
p (versions[:jruby] - %w[head]).map { |v| "jruby-#{v}" }
p (versions[:truffleruby] - %w[head]).map { |v| "truffleruby-#{v}" }
+18 -9
View File
@@ -7,6 +7,7 @@ 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 tc = require('@actions/tool-cache') const tc = require('@actions/tool-cache')
const common = require('./common')
const rubyInstallerVersions = require('./windows-versions').versions const rubyInstallerVersions = require('./windows-versions').versions
// Extract to SSD, see https://github.com/ruby/setup-ruby/pull/14 // Extract to SSD, see https://github.com/ruby/setup-ruby/pull/14
@@ -32,18 +33,21 @@ export function getAvailableVersions(platform, engine) {
} }
} }
export async function install(platform, ruby) { export async function install(platform, engine, version) {
const version = ruby.split('-', 2)[1]
const url = rubyInstallerVersions[version] const url = rubyInstallerVersions[version]
console.log(url)
if (!url.endsWith('.7z')) { if (!url.endsWith('.7z')) {
throw new Error('URL should end in .7z') throw new Error(`URL should end in .7z: ${url}`)
} }
const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length) const base = url.slice(url.lastIndexOf('/') + 1, url.length - '.7z'.length)
const downloadPath = await tc.downloadTool(url) const downloadPath = await common.measure('Downloading Ruby', async () => {
await exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true }) console.log(url)
return await tc.downloadTool(url)
})
await common.measure('Extracting Ruby', async () =>
exec.exec('7z', ['x', downloadPath, `-xr!${base}\\share\\doc`, `-o${drive}:\\`], { silent: true }))
const rubyPrefix = `${drive}:\\${base}` const rubyPrefix = `${drive}:\\${base}`
let toolchainPaths = (version === 'mswin') ? let toolchainPaths = (version === 'mswin') ?
@@ -62,7 +66,8 @@ async function symLinkToEmbeddedMSYS2() {
} }
const latestVersion = toolCacheVersions.slice(-1)[0] const latestVersion = toolCacheVersions.slice(-1)[0]
const hostedRuby = tc.find('Ruby', latestVersion) const hostedRuby = tc.find('Ruby', latestVersion)
await exec.exec(`cmd /c mklink /D ${msys2} ${hostedRuby}\\msys64`) await common.measure('Linking MSYS2', async () =>
exec.exec(`cmd /c mklink /D ${msys2} ${hostedRuby}\\msys64`))
} }
async function setupMingw(version) { async function setupMingw(version) {
@@ -70,7 +75,8 @@ async function setupMingw(version) {
if (version.startsWith('2.2') || version.startsWith('2.3')) { if (version.startsWith('2.2') || version.startsWith('2.3')) {
core.exportVariable('SSL_CERT_FILE', certFile) core.exportVariable('SSL_CERT_FILE', certFile)
await installMSYS(version) await common.measure('Installing MSYS1', async () =>
installMSYS(version))
return msysPathEntries return msysPathEntries
} else { } else {
@@ -117,7 +123,10 @@ async function setupMSWin() {
await symLinkToEmbeddedMSYS2() await symLinkToEmbeddedMSYS2()
} }
return [...addVCVARSEnv(), ...msys2PathEntries] const VCPathEntries = await common.measure('Setting up MSVC environment', async () =>
addVCVARSEnv())
return [...VCPathEntries, ...msys2PathEntries]
} }
/* Sets MSVC environment for use in Actions /* Sets MSVC environment for use in Actions
Generated
+11 -11
View File
@@ -8,16 +8,16 @@
integrity sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w== integrity sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w==
"@actions/exec@^1.0.0", "@actions/exec@^1.0.3": "@actions/exec@^1.0.0", "@actions/exec@^1.0.3":
version "1.0.3" version "1.0.4"
resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.0.3.tgz#b967f8700d6ff011dcc91243b58bafc1bb9ab95f" resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.0.4.tgz#99d75310e62e59fc37d2ee6dcff6d4bffadd3a5d"
integrity sha512-TogJGnueOmM7ntCi0ASTUj4LapRRtDfj57Ja4IhPmg2fls28uVOPbAn8N+JifaOumN2UG3oEO/Ixek2A4NcYSA== integrity sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==
dependencies: dependencies:
"@actions/io" "^1.0.1" "@actions/io" "^1.0.1"
"@actions/http-client@^1.0.3": "@actions/http-client@^1.0.8":
version "1.0.6" version "1.0.8"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.6.tgz#6f9267ca50e1d74d8581f4a894a943cd4c97b49a" resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.8.tgz#8bd76e8eca89dc8bcf619aa128eba85f7a39af45"
integrity sha512-LGmio4w98UyGX33b/W6V6Nx/sQHRXZ859YlMkn36wPsXPB82u8xTVlA/Dq2DXrm6lEq9RVmisRJa1c+HETAIJA== integrity sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==
dependencies: dependencies:
tunnel "0.0.6" tunnel "0.0.6"
@@ -27,13 +27,13 @@
integrity sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg== integrity sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==
"@actions/tool-cache@^1.3.1": "@actions/tool-cache@^1.3.1":
version "1.3.3" version "1.3.4"
resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.3.3.tgz#34cf87a0436a2178207a644932114a236194b0fd" resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.3.4.tgz#2d2e3d109696edc7c12b0bd47ab6f66446428246"
integrity sha512-AFVyTLcIxusDVI1gMhbZW8m/On7YNJG+xYaxorV+qic+f7lO7h37aT2mfzxqAq7mwHxtP1YlVFNrXe9QDf/bPg== integrity sha512-1Pfz4vDbKzqsWOi5CdNl377cwBNfsNrV3Wy8i94mw+49T+6JVqAH3gtFj/Woe93zyvlvzqM0rmQlPh5+jvKLag==
dependencies: dependencies:
"@actions/core" "^1.2.0" "@actions/core" "^1.2.0"
"@actions/exec" "^1.0.0" "@actions/exec" "^1.0.0"
"@actions/http-client" "^1.0.3" "@actions/http-client" "^1.0.8"
"@actions/io" "^1.0.1" "@actions/io" "^1.0.1"
semver "^6.1.0" semver "^6.1.0"
uuid "^3.3.2" uuid "^3.3.2"