From 8c52539465b2a0faaf807512f00e8db641a723c6 Mon Sep 17 00:00:00 2001 From: Gilbert Bishop-White Date: Wed, 15 Jan 2025 10:38:11 +0000 Subject: [PATCH 1/2] Add ability to specify OTP architecture --- README.md | 34 ++++++++++++++++++++++++++-------- action.yml | 3 +++ dist/index.js | 27 ++++++++++++++++++++++++--- src/setup-beam.js | 27 ++++++++++++++++++++++++--- test/setup-beam.test.js | 24 ++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b073f508..3ed24be2 100644 --- a/README.md +++ b/README.md @@ -71,14 +71,14 @@ be the latest. This list presents the known working version combos between the target operating system and Erlang/OTP. -| Operating system | Erlang/OTP | Status -|- |- |- -| `ubuntu-18.04` | 17.0 - 25.3 | ✅ -| `ubuntu-20.04` | 21.0 - 27 | ✅ -| `ubuntu-22.04` | 24.2 - 27 | ✅ -| `ubuntu-24.04` | 24.3 - 27 | ✅ -| `windows-2019` | 21* - 25 | ✅ -| `windows-2022` | 21* - 27 | ✅ +| Operating system | Erlang/OTP | OTP Architecture | Status +|- |- | |- +| `ubuntu-18.04` | 17.0 - 25.3 | 32 bit | ✅ +| `ubuntu-20.04` | 21.0 - 27 | 32 bit | ✅ +| `ubuntu-22.04` | 24.2 - 27 | 32 bit | ✅ +| `ubuntu-24.04` | 24.3 - 27 | 32/64 bit | ✅ +| `windows-2019` | 21\* - 25 | 32/64 bit | ✅ +| `windows-2022` | 21\* - 27 | 32/64 bit | ✅ **Note** \*: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc. @@ -194,6 +194,24 @@ jobs: https://cdn.jsdelivr.net/hex ``` +### OTP Architecture + +On Windows you can specify the OTP architecture to install. + +```yaml +# create this in .github/workflows/ci.yml +on: push + +jobs: + test: + runs-on: windows-latest + steps: + - uses: erlef/setup-beam@v1 + with: + otp-version: '26' + otp-architecture: '32' +``` + ### Environment variables Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following diff --git a/action.yml b/action.yml index 7fb60bcf..50958aa3 100644 --- a/action.yml +++ b/action.yml @@ -19,6 +19,9 @@ inputs: otp-version: description: Version range or exact version of Erlang/OTP to use, or false when installing only Gleam without OTP + otp-architecture: + description: 32 or 64, to specify the architecture of the OTP to install. Only applies to Windows. + default: 64 elixir-version: description: Version range or exact version of Elixir to use gleam-version: diff --git a/dist/index.js b/dist/index.js index 9abcb884..623829a8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9119,6 +9119,7 @@ main().catch((err) => { async function main() { checkPlatform() + checkOtpArchitecture() const versionFilePath = getInput('version-file', false) let versions @@ -9388,13 +9389,16 @@ async function getOTPVersions(osVersion) { otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } else if (process.platform === 'win32') { + const file_regex = new RegExp( + `^otp_win${getInput('otp-architecture')}_(.*).exe$/`, + ) otpVersionsListings.forEach((otpVersionsListing) => { otpVersionsListing .map((x) => x.assets) .flat() - .filter((x) => x.name.match(/^otp_win64_.*.exe$/)) + .filter((x) => x.name.match(file_regex)) .forEach((x) => { - const otpMatch = x.name.match(/^otp_win64_(.*).exe$/) + const otpMatch = x.name.match(file_regex) const otpVersion = otpMatch[1] debugLog('OTP line and parsing', [otpMatch, otpVersion]) otpVersions[otpVersion] = otpVersion @@ -9899,7 +9903,9 @@ async function install(toolName, opts) { win32: { downloadToolURL: () => 'https://github.com/erlang/otp/releases/download/' + - `OTP-${toolVersion}/otp_win64_${toolVersion}.exe`, + `OTP-${toolVersion}/otp_win${getInput( + 'otp-architecture', + )}_${toolVersion}.exe`, extract: async () => ['file', 'otp.exe'], postExtract: async (cachePath) => { const cmd = path.join(cachePath, 'otp.exe') @@ -10155,6 +10161,21 @@ function checkPlatform() { } } +function checkOtpArchitecture() { + if (process.platform !== 'win32' && getInput('otp-architecture') == '32') { + throw new Error( + '@erlef/setup-beam only supports otp-architecture=32 on Windows', + ) + } + + if ( + getInput('otp-architecture') !== '32' && + getInput('otp-architecture') !== '64' + ) { + throw new Error('otp-architecture must be 32 or 64') + } +} + function debugLoggingEnabled() { return !!process.env.RUNNER_DEBUG } diff --git a/src/setup-beam.js b/src/setup-beam.js index ebd83cb2..814eac2f 100644 --- a/src/setup-beam.js +++ b/src/setup-beam.js @@ -14,6 +14,7 @@ main().catch((err) => { async function main() { checkPlatform() + checkOtpArchitecture() const versionFilePath = getInput('version-file', false) let versions @@ -288,13 +289,16 @@ async function getOTPVersions(osVersion) { otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } else if (process.platform === 'win32') { + const file_regex = new RegExp( + `^otp_win${getInput('otp-architecture')}_(.*).exe$/`, + ) otpVersionsListings.forEach((otpVersionsListing) => { otpVersionsListing .map((x) => x.assets) .flat() - .filter((x) => x.name.match(/^otp_win64_.*.exe$/)) + .filter((x) => x.name.match(file_regex)) .forEach((x) => { - const otpMatch = x.name.match(/^otp_win64_(.*).exe$/) + const otpMatch = x.name.match(file_regex) const otpVersion = otpMatch[1] debugLog('OTP line and parsing', [otpMatch, otpVersion]) otpVersions[otpVersion] = otpVersion @@ -799,7 +803,9 @@ async function install(toolName, opts) { win32: { downloadToolURL: () => 'https://github.com/erlang/otp/releases/download/' + - `OTP-${toolVersion}/otp_win64_${toolVersion}.exe`, + `OTP-${toolVersion}/otp_win${getInput( + 'otp-architecture', + )}_${toolVersion}.exe`, extract: async () => ['file', 'otp.exe'], postExtract: async (cachePath) => { const cmd = path.join(cachePath, 'otp.exe') @@ -1055,6 +1061,21 @@ function checkPlatform() { } } +function checkOtpArchitecture() { + if (process.platform !== 'win32' && getInput('otp-architecture') == '32') { + throw new Error( + '@erlef/setup-beam only supports otp-architecture=32 on Windows', + ) + } + + if ( + getInput('otp-architecture') !== '32' && + getInput('otp-architecture') !== '64' + ) { + throw new Error('otp-architecture must be 32 or 64') + } +} + function debugLoggingEnabled() { return !!process.env.RUNNER_DEBUG } diff --git a/test/setup-beam.test.js b/test/setup-beam.test.js index 0f77e66b..ee31e6db 100644 --- a/test/setup-beam.test.js +++ b/test/setup-beam.test.js @@ -1,4 +1,5 @@ simulateInput('otp-version', '25.1.2') +simulateInput('otp-architecture', '64') simulateInput('elixir-version', '1.14.2') simulateInput('rebar3-version', '3.20') simulateInput('install-rebar', 'true') @@ -283,6 +284,29 @@ async function testOTPVersions() { expected = '23.0.4' got = await setupBeam.getOTPVersion(spec, osVersion) assert.deepStrictEqual(got, expected) + + // Check we get the same results for 32-bit OTP + before = simulateInput('otp-architecture', '32') + + spec = '24.0.1' + osVersion = 'windows-latest' + expected = '24.0.1' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + + spec = '23.2.x' + osVersion = 'windows-2016' + expected = '23.2.7' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + + spec = '23.0' + osVersion = 'windows-2019' + expected = '23.0.4' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + + simulateInput('otp-architecture', before) } simulateInput('hexpm-mirrors', hexMirrors, { multiline: true }) From 72bde2297f957469b0c16f29e1c180de7939ebeb Mon Sep 17 00:00:00 2001 From: Gilbert Bishop-White Date: Wed, 15 Jan 2025 14:29:58 +0000 Subject: [PATCH 2/2] Fix regex --- dist/index.js | 2 +- src/setup-beam.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 623829a8..259b5646 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9390,7 +9390,7 @@ async function getOTPVersions(osVersion) { }) } else if (process.platform === 'win32') { const file_regex = new RegExp( - `^otp_win${getInput('otp-architecture')}_(.*).exe$/`, + `^otp_win${getInput('otp-architecture')}_(.*).exe$`, ) otpVersionsListings.forEach((otpVersionsListing) => { otpVersionsListing diff --git a/src/setup-beam.js b/src/setup-beam.js index 814eac2f..fc82096f 100644 --- a/src/setup-beam.js +++ b/src/setup-beam.js @@ -290,7 +290,7 @@ async function getOTPVersions(osVersion) { }) } else if (process.platform === 'win32') { const file_regex = new RegExp( - `^otp_win${getInput('otp-architecture')}_(.*).exe$/`, + `^otp_win${getInput('otp-architecture')}_(.*).exe$`, ) otpVersionsListings.forEach((otpVersionsListing) => { otpVersionsListing