Compare commits

...
16 Commits
Author SHA1 Message Date
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
11 changed files with 265 additions and 170 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
+12 -7
View File
@@ -3,25 +3,25 @@ on:
pull_request:
push:
branches-ignore:
- master
- v1
tags-ignore:
- '*'
paths-ignore:
- README.md
jobs:
common:
test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu, macos, windows ]
# Use various version syntaxes 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 ]
# Use various version syntax here for testing
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:
- { os: windows, ruby: debug }
- { os: windows, ruby: truffleruby }
- { os: windows, ruby: truffleruby-head }
@@ -29,15 +29,17 @@ jobs:
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
- uses: ./
with:
ruby-version: ${{ matrix.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')
if: matrix.os == 'windows'
run: |
$abi, $plat = $(ruby -e "STDOUT.write RbConfig::CONFIG['ruby_version'] + ' ' + RUBY_PLATFORM").split(' ')
if ($plat.Contains('mingw')) {
@@ -48,22 +50,25 @@ jobs:
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
if: matrix.os != 'windows'
run: which -a ruby rake
- name: where ruby, rake
if: startsWith(matrix.os, 'windows')
if: matrix.os == 'windows'
run: |
$ErrorActionPreference = 'Continue'
$where = 'ruby', 'rake'
+18 -5
View File
@@ -14,11 +14,12 @@ This action currently supports these versions of MRI, JRuby and TruffleRuby:
| 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 |
| TruffleRuby | 19.3.0 - 20.0.0, head |
| 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.
Ruby 2.2 resolves to 2.2.6 on Windows (last build from RubyInstaller) and 2.2.10 otherwise.
@@ -134,6 +135,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).
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
Note that running CI on Windows can be quite challenging if you are not very familiar with Windows.
@@ -146,15 +152,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`.
* 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
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 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
This action used to be at `eregon/use-ruby-action` and was moved to the `ruby` organization.
+5 -1
View File
@@ -6,13 +6,17 @@ branding:
icon: download
inputs:
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
default: 'default'
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.'
required: false
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:
ruby-prefix:
description: 'The prefix of the installed ruby'
+4
View File
@@ -16,6 +16,10 @@ export async function measure(name, block) {
})
}
export function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'debug' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
export function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
Generated Vendored
+149 -92
View File
@@ -356,13 +356,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
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 });
const os = __webpack_require__(87);
const events = __webpack_require__(614);
const child = __webpack_require__(129);
const path = __webpack_require__(622);
const io = __webpack_require__(1);
const ioUtil = __webpack_require__(672);
const os = __importStar(__webpack_require__(87));
const events = __importStar(__webpack_require__(614));
const child = __importStar(__webpack_require__(129));
const path = __importStar(__webpack_require__(622));
const io = __importStar(__webpack_require__(1));
const ioUtil = __importStar(__webpack_require__(672));
/* eslint-disable @typescript-eslint/unbound-method */
const IS_WINDOWS = process.platform === 'win32';
/*
@@ -806,6 +813,12 @@ class ToolRunner extends events.EventEmitter {
resolve(exitCode);
}
});
if (this.options.input) {
if (!cp.stdin) {
throw new Error('child process missing stdin');
}
cp.stdin.end(this.options.input);
}
});
});
}
@@ -965,34 +978,42 @@ const common = __webpack_require__(239)
async function run() {
try {
const platform = common.getVirtualEnvironmentName()
const [engine, version] = parseRubyEngineAndVersion(core.getInput('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 ruby = validateRubyEngineAndVersion(platform, engineVersions, engine, version)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, ruby)
setupPath(ruby, newPathEntries)
await common.measure('Installing Bundler', async () =>
installBundler(platform, rubyPrefix, engine, version))
core.setOutput('ruby-prefix', rubyPrefix)
await main()
} catch (error) {
core.setFailed(error.message)
}
}
async function main() {
process.chdir(core.getInput('working-directory'))
const platform = common.getVirtualEnvironmentName()
const [engine, parsedVersion] = parseRubyEngineAndVersion(core.getInput('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 (core.getInput('bundler') !== 'none') {
await common.measure('Installing Bundler', async () =>
installBundler(platform, rubyPrefix, engine, version))
}
core.setOutput('ruby-prefix', rubyPrefix)
}
function parseRubyEngineAndVersion(rubyVersion) {
if (rubyVersion === 'default') {
if (fs.existsSync('.ruby-version')) {
@@ -1015,7 +1036,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
}
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'
version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
@@ -1028,24 +1049,25 @@ function parseRubyEngineAndVersion(rubyVersion) {
return [engine, version]
}
function validateRubyEngineAndVersion(platform, engineVersions, engine, version) {
function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion) {
if (!engineVersions) {
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 found = latestToFirstVersion.find(v => v !== 'head' && v.startsWith(version))
const found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
if (found) {
version = found
} 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(', ')}
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() {
@@ -1055,7 +1077,7 @@ function createGemRC() {
}
}
function setupPath(ruby, newPathEntries) {
function setupPath(newPathEntries) {
const originalPath = process.env['PATH'].split(path.delimiter)
let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry))
@@ -1093,9 +1115,6 @@ function readBundledWithFromGemfileLock() {
async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = core.getInput('bundler')
if (bundlerVersion === 'none') {
return
}
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock()
@@ -1117,7 +1136,7 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
throw new Error(`Cannot parse bundler input: ${bundlerVersion}`)
}
if (engine === 'ruby' && isHeadVersion(rubyVersion) && bundlerVersion === '2') {
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}`)
@@ -1129,10 +1148,6 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
}
}
function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
if (__filename.endsWith('index.js')) { run() }
@@ -1447,7 +1462,7 @@ function getVersions(platform) {
"2.5.0", "2.5.1", "2.5.2", "2.5.3", "2.5.4", "2.5.5", "2.5.6", "2.5.7", "2.5.8",
"2.6.0", "2.6.1", "2.6.2", "2.6.3", "2.6.4", "2.6.5", "2.6.6",
"2.7.0", "2.7.1",
"head"
"head", "debug",
],
"jruby": [
"9.1.17.0",
@@ -1486,6 +1501,7 @@ module.exports = require("https");
"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)
@@ -1505,6 +1521,10 @@ async function measure(name, block) {
})
}
function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'debug' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
function getVirtualEnvironmentName() {
const platform = os.platform()
if (platform === 'linux') {
@@ -3523,10 +3543,10 @@ function getAvailableVersions(platform, engine) {
return rubyBuilderVersions.getVersions(platform)[engine]
}
async function install(platform, ruby) {
const rubyPrefix = await downloadAndExtract(platform, ruby)
async function install(platform, engine, version) {
const rubyPrefix = await downloadAndExtract(platform, engine, version)
let newPathEntries
if (ruby.startsWith('rubinius')) {
if (engine === 'rubinius') {
newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')]
} else {
newPathEntries = [path.join(rubyPrefix, 'bin')]
@@ -3534,12 +3554,12 @@ async function install(platform, ruby) {
return [rubyPrefix, newPathEntries]
}
async function downloadAndExtract(platform, ruby) {
async function downloadAndExtract(platform, engine, version) {
const rubiesDir = path.join(os.homedir(), '.rubies')
await io.mkdirP(rubiesDir)
const downloadPath = await common.measure('Downloading Ruby', async () => {
const url = getDownloadURL(platform, ruby)
const url = getDownloadURL(platform, engine, version)
console.log(url)
return await tc.downloadTool(url)
})
@@ -3548,20 +3568,19 @@ async function downloadAndExtract(platform, ruby) {
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) {
if (ruby.endsWith('-head')) {
return getLatestHeadBuildURL(platform, ruby)
function getDownloadURL(platform, engine, version) {
if (common.isHeadVersion(version)) {
return getLatestHeadBuildURL(platform, engine, version)
} else {
return `${releasesURL}/download/${builderReleaseTag}/${ruby}-${platform}.tar.gz`
return `${releasesURL}/download/${builderReleaseTag}/${engine}-${version}-${platform}.tar.gz`
}
}
function getLatestHeadBuildURL(platform, ruby) {
const engine = ruby.split('-')[0]
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-head-${platform}.tar.gz`
function getLatestHeadBuildURL(platform, engine, version) {
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-${version}-${platform}.tar.gz`
}
@@ -4144,6 +4163,7 @@ var HttpCodes;
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
@@ -4168,8 +4188,18 @@ function getProxyUrl(serverUrl) {
return proxyUrl ? proxyUrl.href : '';
}
exports.getProxyUrl = getProxyUrl;
const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
const HttpRedirectCodes = [
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 ExponentialBackoffCeiling = 10;
const ExponentialBackoffTimeSlice = 5;
@@ -4294,18 +4324,22 @@ class HttpClient {
*/
async request(verb, requestUrl, data, headers) {
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 info = this._prepareRequest(verb, parsedUrl, headers);
// 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 response;
while (numTries < maxTries) {
response = await this.requestRaw(info, data);
// 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;
for (let i = 0; i < this.handlers.length; i++) {
if (this.handlers[i].canHandleAuthentication(response)) {
@@ -4323,21 +4357,32 @@ class HttpClient {
}
}
let redirectsRemaining = this._maxRedirects;
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
&& this._allowRedirects
&& redirectsRemaining > 0) {
const redirectUrl = response.message.headers["location"];
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&
this._allowRedirects &&
redirectsRemaining > 0) {
const redirectUrl = response.message.headers['location'];
if (!redirectUrl) {
// if there's no location to redirect to, we won't
break;
}
let parsedRedirectUrl = url.parse(redirectUrl);
if (parsedUrl.protocol == 'https:' && 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.");
if (parsedUrl.protocol == 'https:' &&
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
// which will leak the open socket.
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
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
response = await this.requestRaw(info, data);
@@ -4388,8 +4433,8 @@ class HttpClient {
*/
requestRawWithCallback(info, data, onResult) {
let socket;
if (typeof (data) === 'string') {
info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8');
if (typeof data === 'string') {
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
}
let callbackCalled = false;
let handleResult = (err, res) => {
@@ -4402,7 +4447,7 @@ class HttpClient {
let res = new HttpClientResponse(msg);
handleResult(null, res);
});
req.on('socket', (sock) => {
req.on('socket', sock => {
socket = sock;
});
// If we ever get disconnected, we want the socket to timeout eventually
@@ -4417,10 +4462,10 @@ class HttpClient {
// res should have headers
handleResult(err, null);
});
if (data && typeof (data) === 'string') {
if (data && typeof data === 'string') {
req.write(data, 'utf8');
}
if (data && typeof (data) !== 'string') {
if (data && typeof data !== 'string') {
data.on('close', function () {
req.end();
});
@@ -4447,31 +4492,34 @@ class HttpClient {
const defaultPort = usingSsl ? 443 : 80;
info.options = {};
info.options.host = info.parsedUrl.hostname;
info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
info.options.port = info.parsedUrl.port
? parseInt(info.parsedUrl.port)
: defaultPort;
info.options.path =
(info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
info.options.method = method;
info.options.headers = this._mergeHeaders(headers);
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);
// gives handlers an opportunity to participate
if (this.handlers) {
this.handlers.forEach((handler) => {
this.handlers.forEach(handler => {
handler.prepareRequest(info.options);
});
}
return info;
}
_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) {
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
}
return lowercaseKeys(headers || {});
}
_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;
if (this.requestOptions && this.requestOptions.headers) {
clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
@@ -4509,7 +4557,7 @@ class HttpClient {
proxyAuth: proxyUrl.auth,
host: proxyUrl.hostname,
port: proxyUrl.port
},
}
};
let tunnelAgent;
const overHttps = proxyUrl.protocol === 'https:';
@@ -4536,7 +4584,9 @@ class HttpClient {
// 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
// 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;
}
@@ -4597,7 +4647,7 @@ class HttpClient {
msg = contents;
}
else {
msg = "Failed request: (" + statusCode + ")";
msg = 'Failed request: (' + statusCode + ')';
}
let err = new Error(msg);
// attach statusCode and body obj (if available) to the error object
@@ -4952,8 +5002,7 @@ function getAvailableVersions(platform, engine) {
}
}
async function install(platform, ruby) {
const version = ruby.split('-', 2)[1]
async function install(platform, engine, version) {
const url = rubyInstallerVersions[version]
if (!url.endsWith('.7z')) {
@@ -5104,12 +5153,10 @@ function getProxyUrl(reqUrl) {
}
let proxyVar;
if (usingSsl) {
proxyVar = process.env["https_proxy"] ||
process.env["HTTPS_PROXY"];
proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
}
else {
proxyVar = process.env["http_proxy"] ||
process.env["HTTP_PROXY"];
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];
}
if (proxyVar) {
proxyUrl = url.parse(proxyVar);
@@ -5121,7 +5168,7 @@ function checkBypass(reqUrl) {
if (!reqUrl.hostname) {
return false;
}
let noProxy = process.env["no_proxy"] || process.env["NO_PROXY"] || '';
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) {
return false;
}
@@ -5142,7 +5189,10 @@ function checkBypass(reqUrl) {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
}
// 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)) {
return true;
}
@@ -5245,8 +5295,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
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 });
const tr = __webpack_require__(9);
const tr = __importStar(__webpack_require__(9));
/**
* Exec a command.
* Output will be streamed to the live console.
+40 -38
View File
@@ -7,34 +7,42 @@ const common = require('./common')
export async function run() {
try {
const platform = common.getVirtualEnvironmentName()
const [engine, version] = parseRubyEngineAndVersion(core.getInput('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 ruby = validateRubyEngineAndVersion(platform, engineVersions, engine, version)
createGemRC()
const [rubyPrefix, newPathEntries] = await installer.install(platform, ruby)
setupPath(ruby, newPathEntries)
await common.measure('Installing Bundler', async () =>
installBundler(platform, rubyPrefix, engine, version))
core.setOutput('ruby-prefix', rubyPrefix)
await main()
} catch (error) {
core.setFailed(error.message)
}
}
async function main() {
process.chdir(core.getInput('working-directory'))
const platform = common.getVirtualEnvironmentName()
const [engine, parsedVersion] = parseRubyEngineAndVersion(core.getInput('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 (core.getInput('bundler') !== 'none') {
await common.measure('Installing Bundler', async () =>
installBundler(platform, rubyPrefix, engine, version))
}
core.setOutput('ruby-prefix', rubyPrefix)
}
function parseRubyEngineAndVersion(rubyVersion) {
if (rubyVersion === 'default') {
if (fs.existsSync('.ruby-version')) {
@@ -57,7 +65,7 @@ function parseRubyEngineAndVersion(rubyVersion) {
}
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'
version = rubyVersion
} else if (!rubyVersion.includes('-')) { // myruby -> myruby-stableVersion
@@ -70,24 +78,25 @@ function parseRubyEngineAndVersion(rubyVersion) {
return [engine, version]
}
function validateRubyEngineAndVersion(platform, engineVersions, engine, version) {
function validateRubyEngineAndVersion(platform, engineVersions, engine, parsedVersion) {
if (!engineVersions) {
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 found = latestToFirstVersion.find(v => v !== 'head' && v.startsWith(version))
const found = latestToFirstVersion.find(v => !common.isHeadVersion(v) && v.startsWith(parsedVersion))
if (found) {
version = found
} 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(', ')}
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() {
@@ -97,7 +106,7 @@ function createGemRC() {
}
}
function setupPath(ruby, newPathEntries) {
function setupPath(newPathEntries) {
const originalPath = process.env['PATH'].split(path.delimiter)
let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry))
@@ -135,9 +144,6 @@ function readBundledWithFromGemfileLock() {
async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
var bundlerVersion = core.getInput('bundler')
if (bundlerVersion === 'none') {
return
}
if (bundlerVersion === 'default' || bundlerVersion === 'Gemfile.lock') {
bundlerVersion = readBundledWithFromGemfileLock()
@@ -159,7 +165,7 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
throw new Error(`Cannot parse bundler input: ${bundlerVersion}`)
}
if (engine === 'ruby' && isHeadVersion(rubyVersion) && bundlerVersion === '2') {
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}`)
@@ -171,8 +177,4 @@ async function installBundler(platform, rubyPrefix, engine, rubyVersion) {
}
}
function isHeadVersion(rubyVersion) {
return rubyVersion === 'head' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
}
if (__filename.endsWith('index.js')) { run() }
+1 -1
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.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",
"head"
"head", "debug",
],
"jruby": [
"9.1.17.0",
+12 -13
View File
@@ -13,10 +13,10 @@ export function getAvailableVersions(platform, engine) {
return rubyBuilderVersions.getVersions(platform)[engine]
}
export async function install(platform, ruby) {
const rubyPrefix = await downloadAndExtract(platform, ruby)
export async function install(platform, engine, version) {
const rubyPrefix = await downloadAndExtract(platform, engine, version)
let newPathEntries
if (ruby.startsWith('rubinius')) {
if (engine === 'rubinius') {
newPathEntries = [path.join(rubyPrefix, 'bin'), path.join(rubyPrefix, 'gems', 'bin')]
} else {
newPathEntries = [path.join(rubyPrefix, 'bin')]
@@ -24,12 +24,12 @@ export async function install(platform, ruby) {
return [rubyPrefix, newPathEntries]
}
async function downloadAndExtract(platform, ruby) {
async function downloadAndExtract(platform, engine, version) {
const rubiesDir = path.join(os.homedir(), '.rubies')
await io.mkdirP(rubiesDir)
const downloadPath = await common.measure('Downloading Ruby', async () => {
const url = getDownloadURL(platform, ruby)
const url = getDownloadURL(platform, engine, version)
console.log(url)
return await tc.downloadTool(url)
})
@@ -38,18 +38,17 @@ async function downloadAndExtract(platform, ruby) {
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) {
if (ruby.endsWith('-head')) {
return getLatestHeadBuildURL(platform, ruby)
function getDownloadURL(platform, engine, version) {
if (common.isHeadVersion(version)) {
return getLatestHeadBuildURL(platform, engine, version)
} else {
return `${releasesURL}/download/${builderReleaseTag}/${ruby}-${platform}.tar.gz`
return `${releasesURL}/download/${builderReleaseTag}/${engine}-${version}-${platform}.tar.gz`
}
}
function getLatestHeadBuildURL(platform, ruby) {
const engine = ruby.split('-')[0]
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-head-${platform}.tar.gz`
function getLatestHeadBuildURL(platform, engine, version) {
return `https://github.com/ruby/${engine}-dev-builder/releases/latest/download/${engine}-${version}-${platform}.tar.gz`
}
+1 -2
View File
@@ -33,8 +33,7 @@ export function getAvailableVersions(platform, engine) {
}
}
export async function install(platform, ruby) {
const version = ruby.split('-', 2)[1]
export async function install(platform, engine, version) {
const url = rubyInstallerVersions[version]
if (!url.endsWith('.7z')) {
Generated
+11 -11
View File
@@ -8,16 +8,16 @@
integrity sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w==
"@actions/exec@^1.0.0", "@actions/exec@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.0.3.tgz#b967f8700d6ff011dcc91243b58bafc1bb9ab95f"
integrity sha512-TogJGnueOmM7ntCi0ASTUj4LapRRtDfj57Ja4IhPmg2fls28uVOPbAn8N+JifaOumN2UG3oEO/Ixek2A4NcYSA==
version "1.0.4"
resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.0.4.tgz#99d75310e62e59fc37d2ee6dcff6d4bffadd3a5d"
integrity sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==
dependencies:
"@actions/io" "^1.0.1"
"@actions/http-client@^1.0.3":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.6.tgz#6f9267ca50e1d74d8581f4a894a943cd4c97b49a"
integrity sha512-LGmio4w98UyGX33b/W6V6Nx/sQHRXZ859YlMkn36wPsXPB82u8xTVlA/Dq2DXrm6lEq9RVmisRJa1c+HETAIJA==
"@actions/http-client@^1.0.8":
version "1.0.8"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.8.tgz#8bd76e8eca89dc8bcf619aa128eba85f7a39af45"
integrity sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==
dependencies:
tunnel "0.0.6"
@@ -27,13 +27,13 @@
integrity sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==
"@actions/tool-cache@^1.3.1":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.3.3.tgz#34cf87a0436a2178207a644932114a236194b0fd"
integrity sha512-AFVyTLcIxusDVI1gMhbZW8m/On7YNJG+xYaxorV+qic+f7lO7h37aT2mfzxqAq7mwHxtP1YlVFNrXe9QDf/bPg==
version "1.3.4"
resolved "https://registry.yarnpkg.com/@actions/tool-cache/-/tool-cache-1.3.4.tgz#2d2e3d109696edc7c12b0bd47ab6f66446428246"
integrity sha512-1Pfz4vDbKzqsWOi5CdNl377cwBNfsNrV3Wy8i94mw+49T+6JVqAH3gtFj/Woe93zyvlvzqM0rmQlPh5+jvKLag==
dependencies:
"@actions/core" "^1.2.0"
"@actions/exec" "^1.0.0"
"@actions/http-client" "^1.0.3"
"@actions/http-client" "^1.0.8"
"@actions/io" "^1.0.1"
semver "^6.1.0"
uuid "^3.3.2"