Skip to content

Commit

Permalink
Detect self-hosted runners not matching a GitHub-hosted runner image
Browse files Browse the repository at this point in the history
* And give instructions for that case.
* Get the OS and OS version ourselves since some users set ImageOS incorrectly.
* This partially reverts commit ad1ebae.
  • Loading branch information
eregon committed Mar 3, 2023
1 parent 2789f85 commit 66dc012
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 137 deletions.
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

0 comments on commit 66dc012

Please sign in to comment.