Skip to content
Closed
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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ The action works on these [GitHub-hosted runners](https://docs.github.com/en/act
| Operating System | Supported |
| ---------------- | --------- |
| Ubuntu | `ubuntu-22.04`, `ubuntu-24.04`, `ubuntu-26.04`, `ubuntu-22.04-arm`, `ubuntu-24.04-arm`, `ubuntu-26.04-arm` |
| Debian | `debian-12` (Ubuntu 22.04 builds), `debian-13` (Ubuntu 24.04 builds), x64 and arm64 |
| macOS | `macos-14` and newer versions |
| Windows | `windows-2022`, `windows-2025`, `windows-11-arm` |

Debian is included so this action can run on Forgejo `act_runner` job containers. There are no Debian-specific ruby-builder artifacts; the action downloads the Ubuntu builds listed above. That works because Debian 12/13 have a newer glibc than those Ubuntu images and still ship `libssl.so.3`. `/opt/hostedtoolcache` must be writable. Missing CRuby runtime packages (`libssl3`, `libyaml-0-2`, `libgmp10`, …) are installed with `apt-get` when the job is root.

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))
Expand Down Expand Up @@ -273,7 +276,8 @@ This follows the [recommendations](https://github.com/actions/toolkit/blob/maste

## Using self-hosted runners

This action might work with [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners)
Debian 12 and 13 runners (including Forgejo) are supported directly; see [Supported Platforms](#supported-platforms).
For other self-hosted Linux, this action might work with [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners)
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.
Expand Down
30 changes: 30 additions & 0 deletions common.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,41 @@ const GitHubHostedPlatforms = [
'windows-11-arm64'
]

// ruby-builder artifacts are Ubuntu-specific. Debian can run them when its glibc
// is newer than the builder image and libssl is still SONAME 3.
// Debian 12 (glibc 2.36) → Ubuntu 22.04 (glibc 2.35).
// Debian 13 (glibc 2.41) → Ubuntu 24.04 (glibc 2.39).
const DebianToUbuntuBuilder = {
'12': 'ubuntu-22.04',
'13': 'ubuntu-24.04',
}

function debianMajorVersion() {
return getOSVersion().split('.')[0]
}

// Platform string used in ruby-builder download URLs (ubuntu-XX.YY, not debian-N).
export function getRubyBuilderPlatform() {
const name = getOSName()
if (name === 'debian') {
const mapped = DebianToUbuntuBuilder[debianMajorVersion()]
if (mapped) {
return mapped
}
}
return getOSNameVersion()
}

// Precisely: whether we have builds for that platform and there are GitHub-hosted runners to test it
function isSupportedPlatform() {
const platform = getOSName()
switch (platform) {
case 'ubuntu':
return GitHubHostedPlatforms.includes(getOSNameVersionArch())
case 'debian': {
const mapped = DebianToUbuntuBuilder[debianMajorVersion()]
return mapped !== undefined && GitHubHostedPlatforms.includes(`${mapped}-${os.arch()}`)
}
case 'macos':
// See https://github.com/ruby/ruby-builder/blob/master/README.md#naming
// 13 on arm64 because of old macos-arm-oss runners
Expand Down Expand Up @@ -318,6 +347,7 @@ function getDefaultToolCachePath() {
const platform = getOSName()
switch (platform) {
case 'ubuntu':
case 'debian':
return '/opt/hostedtoolcache'
case 'macos':
return '/Users/runner/hostedtoolcache'
Expand Down
64 changes: 62 additions & 2 deletions dist/index.js

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

33 changes: 31 additions & 2 deletions ruby-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ export function getAvailableVersions(platform, engine) {
}

export async function install(platform, engine, version) {
const builderPlatform = common.getRubyBuilderPlatform()
if (builderPlatform !== platform) {
console.log(`Detected ${common.getOSNameVersionArch()}; using ${builderPlatform} prebuilt Ruby binaries`)
}

if (platform.startsWith('debian-')) {
await ensureDebianRuntimeLibs()
}

let rubyPrefix, inToolCache
if (common.shouldUseToolCache(engine, version)) {
inToolCache = common.toolCacheFind(engine, version)
Expand Down Expand Up @@ -106,8 +115,8 @@ function getDownloadURL(platform, engine, version) {
builderPlatform = `windows-${os.arch()}`
} else if (platform.startsWith('macos-')) {
builderPlatform = `darwin-${os.arch()}`
} else if (platform.startsWith('ubuntu-')) {
builderPlatform = `${platform}-${os.arch()}`
} else if (platform.startsWith('ubuntu-') || platform.startsWith('debian-')) {
builderPlatform = `${common.getRubyBuilderPlatform()}-${os.arch()}`
}

if (builderPlatform === null || !['x64', 'arm64'].includes(os.arch())) {
Expand All @@ -121,6 +130,26 @@ function getDownloadURL(platform, engine, version) {
}
}

const debianRuntimePackages = ['libssl3', 'libyaml-0-2', 'libgmp10', 'zlib1g', 'libcrypt1', 'libffi8']

async function ensureDebianRuntimeLibs() {
const missing = []
for (const pkg of debianRuntimePackages) {
const status = await exec.exec('dpkg', ['-s', pkg], { ignoreReturnCode: true, silent: true })
if (status !== 0) {
missing.push(pkg)
}
}
if (missing.length === 0) {
return
}

await common.measure(`Installing Ruby runtime libraries (${missing.join(', ')})`, async () => {
await exec.exec('apt-get', ['update', '-qq'])
await exec.exec('apt-get', ['install', '-y', '-qq', ...missing])
})
}

function getLatestHeadBuildURL(platform, engine, version) {
var repo = `${engine}-dev-builder`
if (engine === 'truffleruby+graalvm') {
Expand Down