Skip to content
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
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))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(although some combinations are not available, see [the full list](https://github.com/ruby/ruby-builder/releases/tag/toolcache))
(although some combinations are not available, see [the full list](https://github.com/ruby/ruby-builder/releases))

Unfortunately that full list is no longer accurate, so let's just point to the release list.
(not related to this PR but changing wording around it so fixing it together anyway)

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,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Newer runner images usually only have builds of the latest patch release of each series,
Newer runner images 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`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
so prefer a short version like `'3.4'` over an exact one like `'3.4.2'` in `ruby-version` or `.ruby-version`.
so prefer a short version like `'3.4'` over an exact one like `'3.4.2'`, or pin to a specific runner version (e.g. `ubuntu-24.04`).

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