Add support for ARM builds (#278)

This commit is contained in:
Favio Manriquez
2024-06-16 05:19:26 -07:00
committed by GitHub
parent c54ac46332
commit 6ab5719d32
3 changed files with 290 additions and 6 deletions
+33 -3
View File
@@ -9160,7 +9160,9 @@ async function main() {
async function installOTP(otpSpec, osVersion) {
const otpVersion = await getOTPVersion(otpSpec, osVersion)
core.startGroup(`Installing Erlang/OTP ${otpVersion} - built on ${osVersion}`)
core.startGroup(
`Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
)
await doWithMirrors({
hexMirrors: hexMirrorsInput(),
actionTitle: `install Erlang/OTP ${otpVersion}`,
@@ -9354,7 +9356,7 @@ async function getOTPVersions(osVersion) {
let otpVersionsListings
let originListing
if (process.platform === 'linux') {
originListing = `/builds/otp/${osVersion}/builds.txt`
originListing = `/builds/otp/${getRunnerOSArchitecture()}/${osVersion}/builds.txt`
otpVersionsListings = await doWithMirrors({
hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`,
@@ -9605,6 +9607,32 @@ function isKnownBranch(ver) {
return ['main', 'master', 'maint', 'latest'].includes(ver)
}
function githubARMRunnerArchs() {
return ['ARM', 'ARM64']
}
function githubAMDRunnerArchs() {
return ['X86', 'X64']
}
function getRunnerOSArchitecture() {
// These options come from:
// https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
if (githubARMRunnerArchs().includes(process.env.RUNNER_ARCH)) {
return 'arm64'
}
if (githubAMDRunnerArchs().includes(process.env.RUNNER_ARCH)) {
return 'amd64'
}
throw new Error(
'Invalid Github runner architecture, expected one of ' +
`${githubAMDRunnerArchs().concat(githubARMRunnerArchs()).join(', ')} ` +
`but got process.env.RUNNER_ARCH = ${process.env.RUNNER_ARCH}`,
)
}
function getRunnerOSVersion() {
const ImageOSToContainer = {
ubuntu18: 'ubuntu-18.04',
@@ -9843,7 +9871,7 @@ async function install(toolName, opts) {
tool: 'Erlang/OTP',
linux: {
downloadToolURL: () =>
`${hexMirror}/builds/otp/${versionSpec}.tar.gz`,
`${hexMirror}/builds/otp/${getRunnerOSArchitecture()}/${versionSpec}.tar.gz`,
extract: async (file) => {
const dest = undefined
const flags = ['zx', '--strip-components=1']
@@ -10133,6 +10161,8 @@ module.exports = {
getGleamVersion,
getRebar3Version,
getVersionFromSpec,
githubAMDRunnerArchs,
githubARMRunnerArchs,
install,
parseVersionFile,
}
+33 -3
View File
@@ -55,7 +55,9 @@ async function main() {
async function installOTP(otpSpec, osVersion) {
const otpVersion = await getOTPVersion(otpSpec, osVersion)
core.startGroup(`Installing Erlang/OTP ${otpVersion} - built on ${osVersion}`)
core.startGroup(
`Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
)
await doWithMirrors({
hexMirrors: hexMirrorsInput(),
actionTitle: `install Erlang/OTP ${otpVersion}`,
@@ -254,7 +256,7 @@ async function getOTPVersions(osVersion) {
let otpVersionsListings
let originListing
if (process.platform === 'linux') {
originListing = `/builds/otp/${osVersion}/builds.txt`
originListing = `/builds/otp/${getRunnerOSArchitecture()}/${osVersion}/builds.txt`
otpVersionsListings = await doWithMirrors({
hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`,
@@ -505,6 +507,32 @@ function isKnownBranch(ver) {
return ['main', 'master', 'maint', 'latest'].includes(ver)
}
function githubARMRunnerArchs() {
return ['ARM', 'ARM64']
}
function githubAMDRunnerArchs() {
return ['X86', 'X64']
}
function getRunnerOSArchitecture() {
// These options come from:
// https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
if (githubARMRunnerArchs().includes(process.env.RUNNER_ARCH)) {
return 'arm64'
}
if (githubAMDRunnerArchs().includes(process.env.RUNNER_ARCH)) {
return 'amd64'
}
throw new Error(
'Invalid Github runner architecture, expected one of ' +
`${githubAMDRunnerArchs().concat(githubARMRunnerArchs()).join(', ')} ` +
`but got process.env.RUNNER_ARCH = ${process.env.RUNNER_ARCH}`,
)
}
function getRunnerOSVersion() {
const ImageOSToContainer = {
ubuntu18: 'ubuntu-18.04',
@@ -743,7 +771,7 @@ async function install(toolName, opts) {
tool: 'Erlang/OTP',
linux: {
downloadToolURL: () =>
`${hexMirror}/builds/otp/${versionSpec}.tar.gz`,
`${hexMirror}/builds/otp/${getRunnerOSArchitecture()}/${versionSpec}.tar.gz`,
extract: async (file) => {
const dest = undefined
const flags = ['zx', '--strip-components=1']
@@ -1033,6 +1061,8 @@ module.exports = {
getGleamVersion,
getRebar3Version,
getVersionFromSpec,
githubAMDRunnerArchs,
githubARMRunnerArchs,
install,
parseVersionFile,
}
+224
View File
@@ -61,8 +61,11 @@ async function all() {
await testFailInstallElixir()
await testFailInstallGleam()
await testFailInstallRebar3()
await testFailGetOTPVersion()
await testOTPVersions()
await testLinuxARM64OTPVersions()
await testLinuxAMD64OTPVersions()
await testElixirVersions()
await testGleamVersions()
await testRebar3Versions()
@@ -171,6 +174,9 @@ async function testOTPVersions() {
)
if (process.platform === 'linux') {
const previousRunnerArch = process.env.RUNNER_ARCH
process.env.RUNNER_ARCH = 'X64'
before = simulateInput('version-type', 'strict')
spec = '26'
osVersion = 'ubuntu-24.04'
@@ -252,6 +258,8 @@ async function testOTPVersions() {
expected = 'master'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
process.env.RUNNER_ARCH = previousRunnerArch
}
if (process.platform === 'win32') {
@@ -277,6 +285,222 @@ async function testOTPVersions() {
simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
}
async function testLinuxARM64OTPVersions() {
let got
let expected
let spec
let osVersion
let before
const hexMirrors = simulateInput(
'hexpm-mirrors',
'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
{ multiline: true },
)
const arm64Options = setupBeam.githubARMRunnerArchs()
process.env.RUNNER_ARCH =
arm64Options[Math.floor(Math.random() * arm64Options.length)]
if (process.platform === 'linux') {
before = simulateInput('version-type', 'strict')
spec = '26'
osVersion = 'ubuntu-24.04'
expected = 'maint-26'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '27.0'
osVersion = 'ubuntu-24.04'
expected = 'OTP-27.0'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '25.3.2.1'
osVersion = 'ubuntu-20.04'
expected = 'OTP-25.3.2.1'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '20'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.3.8.26'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
spec = '20.x'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.0'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.0.5'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.0.x'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.0.5'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = 'maint'
osVersion = 'ubuntu-22.04'
expected = 'maint'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
spec = 'master'
osVersion = 'ubuntu-22.04'
expected = 'master'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
}
simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
}
async function testLinuxAMD64OTPVersions() {
let got
let expected
let spec
let osVersion
let before
const hexMirrors = simulateInput(
'hexpm-mirrors',
'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
{ multiline: true },
)
const amd64Options = setupBeam.githubAMDRunnerArchs()
process.env.RUNNER_ARCH =
amd64Options[Math.floor(Math.random() * amd64Options.length)]
if (process.platform === 'linux') {
before = simulateInput('version-type', 'strict')
spec = '26'
osVersion = 'ubuntu-24.04'
expected = 'maint-26'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '27.0'
osVersion = 'ubuntu-24.04'
expected = 'OTP-27.0'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '25.3.2.1'
osVersion = 'ubuntu-20.04'
expected = 'OTP-25.3.2.1'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', before)
spec = '19.3.x'
osVersion = 'ubuntu-16.04'
expected = 'OTP-19.3.6.13'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '^19.3.6'
osVersion = 'ubuntu-16.04'
expected = 'OTP-19.3.6.13'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '^19.3'
osVersion = 'ubuntu-18.04'
expected = 'OTP-19.3.6.13'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.3.8.26'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
spec = '20.x'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.3.8.26'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.0'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.0.5'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '20.0.x'
osVersion = 'ubuntu-20.04'
expected = 'OTP-20.0.5'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = 'maint'
osVersion = 'ubuntu-22.04'
expected = 'maint'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
spec = 'master'
osVersion = 'ubuntu-22.04'
expected = 'master'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected)
}
simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
}
async function testFailGetOTPVersion() {
const hexMirrors = simulateInput(
'hexpm-mirrors',
'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
{ multiline: true },
)
const previousRunnerArch = process.env.RUNNER_ARCH
process.env.RUNNER_ARCH = 'invalid'
if (process.platform === 'linux') {
const spec = '26'
const osVersion = 'ubuntu-24.04'
assert.rejects(
async () => {
await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
},
(err) => {
assert.ok(err instanceof Error)
return true
},
`Fetching OTP Version with invalid Github runner architecture is supposed to fail`,
)
}
process.env.RUNNER_ARCH = previousRunnerArch
}
async function testElixirVersions() {
let got
let expected