Skip to content

Commit 66dc012

Browse files
committed
Detect self-hosted runners not matching a GitHub-hosted runner image
* And give instructions for that case. * Get the OS and OS version ourselves since some users set ImageOS incorrectly. * This partially reverts commit ad1ebae.
1 parent 2789f85 commit 66dc012

File tree

9 files changed

+437
-137
lines changed

9 files changed

+437
-137
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,17 +252,16 @@ This action might work with [self-hosted runners](https://docs.github.com/en/act
252252
if the [Runner Image](https://github.com/actions/runner-images) is very similar to the ones used by GitHub runners. Notably:
253253

254254
* Make sure to use the same operating system and version.
255-
* 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.
256255
* Make sure to use the same version of libssl.
257256
* 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
258257
* The default tool cache directory (`/opt/hostedtoolcache` on Linux, `/Users/runner/hostedtoolcache` on macOS,
259258
`C:/hostedtoolcache/windows` on Windows) must be writable by the `runner` user.
260259
This is necessary since the Ruby builds embed the install path when built and cannot be moved around.
261260
* `/home/runner` must be writable by the `runner` user.
262261

263-
In other cases, please use a system Ruby or [install Ruby manually](https://github.com/postmodern/chruby/wiki#installing-rubies) instead.
264-
265-
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)).
262+
In other cases, you will need to install Ruby in the runner tool cache as shown by the action when it detects that case
263+
(run it so it will show you where to install Ruby).
264+
You could of course also not use this action and e.g. use Ruby from a system package or use a Docker image instead.
266265

267266
## History
268267

bundler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ async function computeBaseKey(platform, engine, version, lockFile, cacheVersion)
235235
const cwd = process.cwd()
236236
const bundleWith = process.env['BUNDLE_WITH'] || ''
237237
const bundleWithout = process.env['BUNDLE_WITHOUT'] || ''
238-
let key = `setup-ruby-bundler-cache-v5-${platform}-${engine}-${version}-wd-${cwd}-with-${bundleWith}-without-${bundleWithout}`
238+
let key = `setup-ruby-bundler-cache-v5-${common.getOSNameVersionArch()}-${engine}-${version}-wd-${cwd}-with-${bundleWith}-without-${bundleWithout}`
239239

240240
if (cacheVersion !== DEFAULT_CACHE_VERSION) {
241241
key += `-v-${cacheVersion}`

common.js

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const stream = require('stream')
66
const crypto = require('crypto')
77
const core = require('@actions/core')
88
const { performance } = require('perf_hooks')
9+
const linuxOSInfo = require('linux-os-info')
10+
import macosRelease from 'macos-release'
911

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

154-
function getImageOS() {
155-
const imageOS = process.env['ImageOS']
156-
if (!imageOS) {
157-
throw new Error('The environment variable ImageOS must be set')
158-
}
159-
return imageOS
156+
const GitHubHostedPlatforms = [
157+
'ubuntu-20.04-x64',
158+
'ubuntu-22.04-x64',
159+
'macos-11-x64',
160+
'macos-12-x64',
161+
'windows-2019-x64',
162+
'windows-2022-x64',
163+
]
164+
165+
// Actually a self-hosted runner which does not correspond to a GitHub-hosted runner image
166+
export function isSelfHostedRunner() {
167+
return !GitHubHostedPlatforms.includes(getOSNameVersionArch())
160168
}
161169

162-
export const supportedPlatforms = [
163-
'ubuntu-20.04',
164-
'ubuntu-22.04',
165-
'macos-11',
166-
'macos-12',
167-
'windows-2019',
168-
'windows-2022',
169-
]
170+
let virtualEnvironmentName = undefined
170171

171172
export function getVirtualEnvironmentName() {
172-
const imageOS = getImageOS()
173-
174-
let match = imageOS.match(/^ubuntu(\d+)/) // e.g. ubuntu18
175-
if (match) {
176-
return `ubuntu-${match[1]}.04`
173+
if (virtualEnvironmentName !== undefined) {
174+
return virtualEnvironmentName
177175
}
178176

179-
match = imageOS.match(/^macos(\d{2})(\d+)?/) // e.g. macos1015, macos11
180-
if (match) {
181-
if (match[2]) {
182-
return `macos-${match[1]}.${match[2]}`
183-
} else {
184-
return `macos-${match[1]}`
185-
}
177+
const platform = os.platform()
178+
let osName
179+
let osVersion
180+
if (platform === 'linux') {
181+
const info = linuxOSInfo({mode: 'sync'})
182+
osName = info.id
183+
osVersion = info.version_id
184+
} else if (platform === 'darwin') {
185+
osName = 'macos'
186+
osVersion = macosRelease().version
187+
} else if (platform === 'win32') {
188+
osName = 'windows'
189+
osVersion = findWindowsVersion()
190+
} else {
191+
throw new Error(`Unknown platform ${platform}`)
186192
}
187193

188-
match = imageOS.match(/^win(\d+)/) // e.g. win19
194+
virtualEnvironmentName = `${osName}-${osVersion}`
195+
return virtualEnvironmentName
196+
}
197+
198+
export function getOSNameVersionArch() {
199+
return `${getVirtualEnvironmentName()}-${os.arch()}`
200+
}
201+
202+
function findWindowsVersion() {
203+
const version = os.version();
204+
const match = version.match(/^Windows Server (\d+) Datacenter/)
189205
if (match) {
190-
return `windows-20${match[1]}`
206+
return match[1]
207+
} else {
208+
throw new Error('Could not find Windows version')
191209
}
192-
193-
throw new Error(`Unknown ImageOS ${imageOS}`)
194210
}
195211

196212
export function shouldUseToolCache(engine, version) {
197-
return engine === 'ruby' && !isHeadVersion(version)
213+
return (engine === 'ruby' && !isHeadVersion(version)) || isSelfHostedRunner()
198214
}
199215

200216
function getPlatformToolCache(platform) {
217+
if (isSelfHostedRunner()) {
218+
const runnerToolCache = process.env['RUNNER_TOOL_CACHE']
219+
if (!runnerToolCache) {
220+
throw new Error('$RUNNER_TOOL_CACHE must be set on self-hosted runners')
221+
}
222+
return runnerToolCache
223+
}
201224
// Hardcode paths rather than using $RUNNER_TOOL_CACHE because the prebuilt Rubies cannot be moved anyway
202225
if (platform.startsWith('ubuntu-')) {
203226
return '/opt/hostedtoolcache'
@@ -210,14 +233,23 @@ function getPlatformToolCache(platform) {
210233
}
211234
}
212235

213-
export function getToolCacheRubyPrefix(platform, version) {
236+
export function getToolCacheRubyPrefix(platform, engine, version) {
214237
const toolCache = getPlatformToolCache(platform)
215-
return path.join(toolCache, 'Ruby', version, 'x64')
238+
const name = {
239+
ruby: 'Ruby',
240+
jruby: 'JRuby',
241+
truffleruby: 'TruffleRuby',
242+
"truffleruby+graalvm": 'TruffleRubyGraalVM'
243+
}[engine]
244+
return path.join(toolCache, name, version, os.arch())
245+
}
246+
247+
export function toolCacheCompleteFile(toolCacheRubyPrefix) {
248+
return `${toolCacheRubyPrefix}.complete`
216249
}
217250

218251
export function createToolCacheCompleteFile(toolCacheRubyPrefix) {
219-
const completeFile = `${toolCacheRubyPrefix}.complete`
220-
fs.writeFileSync(completeFile, '')
252+
fs.writeFileSync(toolCacheCompleteFile(toolCacheRubyPrefix), '')
221253
}
222254

223255
// convert windows path like C:\Users\runneradmin to /c/Users/runneradmin

0 commit comments

Comments
 (0)