Skip to content
Open
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Not all combinations of runner images and versions are supported.
The list of available Ruby versions can be seen in [ruby-builder-versions.json](ruby-builder-versions.json) for Ubuntu and macOS
(although some combinations are not available, see [the full list](https://github.com/ruby/ruby-builder/releases/tag/toolcache))
and in [windows-versions.json](windows-versions.json) for Windows.
Newer runner images usually only have builds of the latest patch release of each series,
so prefer a short version like `'3.4'` over an exact one like `'3.4.2'` in `ruby-version` or `.ruby-version`.
For example, `ubuntu-26.04` (which `ubuntu-latest` moves to, see [this announcement](https://github.com/actions/runner-images/issues/14748))
only has builds of CRuby 3.2 and newer, as older CRuby versions do not compile on it.

The prebuilt releases are generated by [ruby-builder](https://github.com/ruby/ruby-builder)
and on Windows by [RubyInstaller2](https://github.com/oneclick/rubyinstaller2).
Expand Down
38 changes: 37 additions & 1 deletion dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 37 additions & 1 deletion ruby-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async function downloadAndExtract(platform, engine, version, rubyPrefix) {
} catch (error) {
if (error.message.includes('404')) {
throw new Error(`Unavailable version ${version} for ${engine} on ${platform}
You can request it at https://github.com/ruby/setup-ruby/issues
${await unavailableVersionHint(platform, engine, version)}
Cause: ${error.message}`)
} else {
throw error
Expand All @@ -100,6 +100,42 @@ async function downloadAndExtract(platform, engine, version, rubyPrefix) {
}
}

// Newer runner images usually only have builds of the latest patch release of each series,
// so point to that release if it is available, or explain that the series is not available.
async function unavailableVersionHint(platform, engine, version) {
const request = 'You can request it at https://github.com/ruby/setup-ruby/issues'
const series = version.split('.').slice(0, 2).join('.')
const latest = getAvailableVersions(platform, engine)
.filter(v => v.startsWith(`${series}.`) && common.isStableVersion(engine, v))
.pop()
if (common.isHeadVersion(version) || latest === undefined) {
return request
}

const input = v => engine === 'ruby' ? v : `${engine}-${v}`
if (latest !== version) {
let response
try {
response = await fetch(getDownloadURL(platform, engine, latest), { method: 'HEAD', signal: AbortSignal.timeout(10000) })
} catch {
return request
}
if (response.ok) {
return `Only the latest patch release of each series is built for newer runner images.
${engine}-${latest} is available on ${platform}: use ruby-version: '${input(latest)}', or '${input(series)}' to always use the latest ${series}.x release.`
} else if (response.status !== 404) {
return request
}
}

const latestUnavailable = latest === version
? `${engine}-${version} is the latest ${series}.x release.`
: `${engine}-${latest}, the latest ${series}.x release, is not available on ${platform} either.`
return `${latestUnavailable}
Use a newer ${engine} version on ${platform}, or an older runner image for ${engine} ${series}.
Note that ubuntu-latest and macos-latest move to newer runner images over time.`
}

function getDownloadURL(platform, engine, version) {
let builderPlatform = null
if (platform.startsWith('windows-')) {
Expand Down