Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Detect self-hosted runners not matching a GitHub-hosted runner image #473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,16 @@ This action might work with [self-hosted runners](https://docs.github.com/en/act
if the [Runner Image](https://github.com/actions/runner-images) is very similar to the ones used by GitHub runners. Notably:

* Make sure to use the same operating system and version.
* Set the environment variable `ImageOS` on the runner to the corresponding value on GitHub-hosted runners (e.g. `ubuntu18`/`macos1015`/`win19`). This is necessary to detect the operating system and version.
* Make sure to use the same version of libssl.
* Make sure that the operating system has `libyaml-0` and [`libgmp`](https://stackoverflow.com/questions/26555902/ruby-v-dyld-library-not-loaded-usr-local-lib-libgmp-10-dylib) installed
* The default tool cache directory (`/opt/hostedtoolcache` on Linux, `/Users/runner/hostedtoolcache` on macOS,
`C:/hostedtoolcache/windows` on Windows) must be writable by the `runner` user.
This is necessary since the Ruby builds embed the install path when built and cannot be moved around.
* `/home/runner` must be writable by the `runner` user.

In other cases, please use a system Ruby or [install Ruby manually](https://github.com/postmodern/chruby/wiki#installing-rubies) instead.

On a self-hosted runner you need to define the `ImageOs` as an evironment variable on the host, you can do this in the `~/actions-runner/.env` file (See [#230](https://github.com/ruby/setup-ruby/issues/230)).
In other cases, you will need to install Ruby in the runner tool cache as shown by the action when it detects that case
(run it so it will show you where to install Ruby).
You could of course also not use this action and e.g. use Ruby from a system package or use a Docker image instead.

## History

Expand Down
2 changes: 1 addition & 1 deletion bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ async function computeBaseKey(platform, engine, version, lockFile, cacheVersion)
const cwd = process.cwd()
const bundleWith = process.env['BUNDLE_WITH'] || ''
const bundleWithout = process.env['BUNDLE_WITHOUT'] || ''
let key = `setup-ruby-bundler-cache-v5-${platform}-${engine}-${version}-wd-${cwd}-with-${bundleWith}-without-${bundleWithout}`
let key = `setup-ruby-bundler-cache-v5-${common.getOSNameVersionArch()}-${engine}-${version}-wd-${cwd}-with-${bundleWith}-without-${bundleWithout}`

if (cacheVersion !== DEFAULT_CACHE_VERSION) {
key += `-v-${cacheVersion}`
Expand Down
102 changes: 67 additions & 35 deletions common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const stream = require('stream')
const crypto = require('crypto')
const core = require('@actions/core')
const { performance } = require('perf_hooks')
const linuxOSInfo = require('linux-os-info')
import macosRelease from 'macos-release'

export const windows = (os.platform() === 'win32')
// Extract to SSD on Windows, see https://github.com/ruby/setup-ruby/pull/14
Expand Down Expand Up @@ -151,53 +153,74 @@ export async function hashFile(file) {
return hash.digest('hex')
}

function getImageOS() {
const imageOS = process.env['ImageOS']
if (!imageOS) {
throw new Error('The environment variable ImageOS must be set')
}
return imageOS
const GitHubHostedPlatforms = [
'ubuntu-20.04-x64',
'ubuntu-22.04-x64',
'macos-11-x64',
'macos-12-x64',
'windows-2019-x64',
'windows-2022-x64',
]

// Actually a self-hosted runner which does not correspond to a GitHub-hosted runner image
export function isSelfHostedRunner() {
return !GitHubHostedPlatforms.includes(getOSNameVersionArch())
}

export const supportedPlatforms = [
'ubuntu-20.04',
'ubuntu-22.04',
'macos-11',
'macos-12',
'windows-2019',
'windows-2022',
]
let virtualEnvironmentName = undefined

export function getVirtualEnvironmentName() {
const imageOS = getImageOS()

let match = imageOS.match(/^ubuntu(\d+)/) // e.g. ubuntu18
if (match) {
return `ubuntu-${match[1]}.04`
if (virtualEnvironmentName !== undefined) {
return virtualEnvironmentName
}

match = imageOS.match(/^macos(\d{2})(\d+)?/) // e.g. macos1015, macos11
if (match) {
if (match[2]) {
return `macos-${match[1]}.${match[2]}`
} else {
return `macos-${match[1]}`
}
const platform = os.platform()
let osName
let osVersion
if (platform === 'linux') {
const info = linuxOSInfo({mode: 'sync'})
osName = info.id
osVersion = info.version_id
} else if (platform === 'darwin') {
osName = 'macos'
osVersion = macosRelease().version
} else if (platform === 'win32') {
osName = 'windows'
osVersion = findWindowsVersion()
} else {
throw new Error(`Unknown platform ${platform}`)
}

match = imageOS.match(/^win(\d+)/) // e.g. win19
virtualEnvironmentName = `${osName}-${osVersion}`
return virtualEnvironmentName
}

export function getOSNameVersionArch() {
return `${getVirtualEnvironmentName()}-${os.arch()}`
}

function findWindowsVersion() {
const version = os.version();
const match = version.match(/^Windows Server (\d+) Datacenter/)
if (match) {
return `windows-20${match[1]}`
return match[1]
} else {
throw new Error('Could not find Windows version')
}

throw new Error(`Unknown ImageOS ${imageOS}`)
}

export function shouldUseToolCache(engine, version) {
return engine === 'ruby' && !isHeadVersion(version)
return (engine === 'ruby' && !isHeadVersion(version)) || isSelfHostedRunner()
}

function getPlatformToolCache(platform) {
if (isSelfHostedRunner()) {
const runnerToolCache = process.env['RUNNER_TOOL_CACHE']
if (!runnerToolCache) {
throw new Error('$RUNNER_TOOL_CACHE must be set on self-hosted runners')
}
return runnerToolCache
}
// Hardcode paths rather than using $RUNNER_TOOL_CACHE because the prebuilt Rubies cannot be moved anyway
if (platform.startsWith('ubuntu-')) {
return '/opt/hostedtoolcache'
Expand All @@ -210,14 +233,23 @@ function getPlatformToolCache(platform) {
}
}

export function getToolCacheRubyPrefix(platform, version) {
export function getToolCacheRubyPrefix(platform, engine, version) {
const toolCache = getPlatformToolCache(platform)
return path.join(toolCache, 'Ruby', version, 'x64')
const name = {
ruby: 'Ruby',
jruby: 'JRuby',
truffleruby: 'TruffleRuby',
"truffleruby+graalvm": 'TruffleRubyGraalVM'
}[engine]
return path.join(toolCache, name, version, os.arch())
}

export function toolCacheCompleteFile(toolCacheRubyPrefix) {
return `${toolCacheRubyPrefix}.complete`
}

export function createToolCacheCompleteFile(toolCacheRubyPrefix) {
const completeFile = `${toolCacheRubyPrefix}.complete`
fs.writeFileSync(completeFile, '')
fs.writeFileSync(toolCacheCompleteFile(toolCacheRubyPrefix), '')
}

// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin
Expand Down
Loading