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) { async function installOTP(otpSpec, osVersion) {
const otpVersion = await getOTPVersion(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({ await doWithMirrors({
hexMirrors: hexMirrorsInput(), hexMirrors: hexMirrorsInput(),
actionTitle: `install Erlang/OTP ${otpVersion}`, actionTitle: `install Erlang/OTP ${otpVersion}`,
@@ -9354,7 +9356,7 @@ async function getOTPVersions(osVersion) {
let otpVersionsListings let otpVersionsListings
let originListing let originListing
if (process.platform === 'linux') { if (process.platform === 'linux') {
originListing = `/builds/otp/${osVersion}/builds.txt` originListing = `/builds/otp/${getRunnerOSArchitecture()}/${osVersion}/builds.txt`
otpVersionsListings = await doWithMirrors({ otpVersionsListings = await doWithMirrors({
hexMirrors: hexMirrorsInput(), hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`, actionTitle: `fetch ${originListing}`,
@@ -9605,6 +9607,32 @@ function isKnownBranch(ver) {
return ['main', 'master', 'maint', 'latest'].includes(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() { function getRunnerOSVersion() {
const ImageOSToContainer = { const ImageOSToContainer = {
ubuntu18: 'ubuntu-18.04', ubuntu18: 'ubuntu-18.04',
@@ -9843,7 +9871,7 @@ async function install(toolName, opts) {
tool: 'Erlang/OTP', tool: 'Erlang/OTP',
linux: { linux: {
downloadToolURL: () => downloadToolURL: () =>
`${hexMirror}/builds/otp/${versionSpec}.tar.gz`, `${hexMirror}/builds/otp/${getRunnerOSArchitecture()}/${versionSpec}.tar.gz`,
extract: async (file) => { extract: async (file) => {
const dest = undefined const dest = undefined
const flags = ['zx', '--strip-components=1'] const flags = ['zx', '--strip-components=1']
@@ -10133,6 +10161,8 @@ module.exports = {
getGleamVersion, getGleamVersion,
getRebar3Version, getRebar3Version,
getVersionFromSpec, getVersionFromSpec,
githubAMDRunnerArchs,
githubARMRunnerArchs,
install, install,
parseVersionFile, parseVersionFile,
} }
+33 -3
View File
@@ -55,7 +55,9 @@ async function main() {
async function installOTP(otpSpec, osVersion) { async function installOTP(otpSpec, osVersion) {
const otpVersion = await getOTPVersion(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({ await doWithMirrors({
hexMirrors: hexMirrorsInput(), hexMirrors: hexMirrorsInput(),
actionTitle: `install Erlang/OTP ${otpVersion}`, actionTitle: `install Erlang/OTP ${otpVersion}`,
@@ -254,7 +256,7 @@ async function getOTPVersions(osVersion) {
let otpVersionsListings let otpVersionsListings
let originListing let originListing
if (process.platform === 'linux') { if (process.platform === 'linux') {
originListing = `/builds/otp/${osVersion}/builds.txt` originListing = `/builds/otp/${getRunnerOSArchitecture()}/${osVersion}/builds.txt`
otpVersionsListings = await doWithMirrors({ otpVersionsListings = await doWithMirrors({
hexMirrors: hexMirrorsInput(), hexMirrors: hexMirrorsInput(),
actionTitle: `fetch ${originListing}`, actionTitle: `fetch ${originListing}`,
@@ -505,6 +507,32 @@ function isKnownBranch(ver) {
return ['main', 'master', 'maint', 'latest'].includes(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() { function getRunnerOSVersion() {
const ImageOSToContainer = { const ImageOSToContainer = {
ubuntu18: 'ubuntu-18.04', ubuntu18: 'ubuntu-18.04',
@@ -743,7 +771,7 @@ async function install(toolName, opts) {
tool: 'Erlang/OTP', tool: 'Erlang/OTP',
linux: { linux: {
downloadToolURL: () => downloadToolURL: () =>
`${hexMirror}/builds/otp/${versionSpec}.tar.gz`, `${hexMirror}/builds/otp/${getRunnerOSArchitecture()}/${versionSpec}.tar.gz`,
extract: async (file) => { extract: async (file) => {
const dest = undefined const dest = undefined
const flags = ['zx', '--strip-components=1'] const flags = ['zx', '--strip-components=1']
@@ -1033,6 +1061,8 @@ module.exports = {
getGleamVersion, getGleamVersion,
getRebar3Version, getRebar3Version,
getVersionFromSpec, getVersionFromSpec,
githubAMDRunnerArchs,
githubARMRunnerArchs,
install, install,
parseVersionFile, parseVersionFile,
} }
+224
View File
@@ -61,8 +61,11 @@ async function all() {
await testFailInstallElixir() await testFailInstallElixir()
await testFailInstallGleam() await testFailInstallGleam()
await testFailInstallRebar3() await testFailInstallRebar3()
await testFailGetOTPVersion()
await testOTPVersions() await testOTPVersions()
await testLinuxARM64OTPVersions()
await testLinuxAMD64OTPVersions()
await testElixirVersions() await testElixirVersions()
await testGleamVersions() await testGleamVersions()
await testRebar3Versions() await testRebar3Versions()
@@ -171,6 +174,9 @@ async function testOTPVersions() {
) )
if (process.platform === 'linux') { if (process.platform === 'linux') {
const previousRunnerArch = process.env.RUNNER_ARCH
process.env.RUNNER_ARCH = 'X64'
before = simulateInput('version-type', 'strict') before = simulateInput('version-type', 'strict')
spec = '26' spec = '26'
osVersion = 'ubuntu-24.04' osVersion = 'ubuntu-24.04'
@@ -252,6 +258,8 @@ async function testOTPVersions() {
expected = 'master' expected = 'master'
got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors) got = await setupBeam.getOTPVersion(spec, osVersion, hexMirrors)
assert.deepStrictEqual(got, expected) assert.deepStrictEqual(got, expected)
process.env.RUNNER_ARCH = previousRunnerArch
} }
if (process.platform === 'win32') { if (process.platform === 'win32') {
@@ -277,6 +285,222 @@ async function testOTPVersions() {
simulateInput('hexpm-mirrors', hexMirrors, { multiline: true }) 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() { async function testElixirVersions() {
let got let got
let expected let expected