Add ability to specify OTP architecture (#316)

3360bff · Gilbert Bishop-White · 2025-01-31 18:29

5 files +101 -14

Files changed

modified README.md
+26 −8
@@ -71,14 +71,14 @@ be the latest.
71 71 This list presents the known working version combos between the target operating system
72 72 and Erlang/OTP.
73 73
74 | Operating system | Erlang/OTP | Status
75 |- |- |-
76 | `ubuntu-18.04` | 17.0 - 25.3 | ✅
77 | `ubuntu-20.04` | 21.0 - 27 | ✅
78 | `ubuntu-22.04` | 24.2 - 27 | ✅
79 | `ubuntu-24.04` | 24.3 - 27 | ✅
80 | `windows-2019` | 21* - 25 | ✅
81 | `windows-2022` | 21* - 27 | ✅
74 +| Operating system | Erlang/OTP | OTP Architecture | Status
75 +|- |- | |-
76 +| `ubuntu-18.04` | 17.0 - 25.3 | x86_64, arm64 | ✅
77 +| `ubuntu-20.04` | 21.0 - 27 | x86_64, arm64 | ✅
78 +| `ubuntu-22.04` | 24.2 - 27 | x86_64, arm64 | ✅
79 +| `ubuntu-24.04` | 24.3 - 27 | x86_64, arm64 | ✅
80 +| `windows-2019` | 21\* - 25 | x86_64, x86 | ✅
81 +| `windows-2022` | 21\* - 27 | x86_64, x86 | ✅
82 82
83 83 **Note** \*: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3,
84 84 22.0, etc.
@@ -194,6 +194,24 @@ jobs:
194 194 https://cdn.jsdelivr.net/hex
195 195 ```
196 196
197 +### OTP Architecture
198 +
199 +On Windows you can specify the OTP architecture to install.
200 +
201 +```yaml
202 +# create this in .github/workflows/ci.yml
203 +on: push
204 +
205 +jobs:
206 + test:
207 + runs-on: windows-latest
208 + steps:
209 + - uses: erlef/setup-beam@v1
210 + with:
211 + otp-version: '26'
212 + otp-architecture: '32'
213 +```
214 +
197 215 ### Environment variables
198 216
199 217 Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following
modified action.yml
+3 −0
@@ -19,6 +19,9 @@ inputs:
19 19 otp-version:
20 20 description: Version range or exact version of Erlang/OTP to use,
21 21 or false when installing only Gleam without OTP
22 + otp-architecture:
23 + description: 32 or 64, to specify the architecture of the OTP to install. Only applies to Windows.
24 + default: 64
22 25 elixir-version:
23 26 description: Version range or exact version of Elixir to use
24 27 gleam-version:
modified dist/index.js
+24 −3
@@ -9119,6 +9119,7 @@ main().catch((err) => {
9119 9119
9120 9120 async function main() {
9121 9121 checkPlatform()
9122 + checkOtpArchitecture()
9122 9123
9123 9124 const versionFilePath = getInput('version-file', false)
9124 9125 let versions
@@ -9388,13 +9389,16 @@ async function getOTPVersions(osVersion) {
9388 9389 otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference
9389 9390 })
9390 9391 } else if (process.platform === 'win32') {
9392 + const file_regex = new RegExp(
9393 + `^otp_win${getInput('otp-architecture')}_(.*).exe$`,
9394 + )
9391 9395 otpVersionsListings.forEach((otpVersionsListing) => {
9392 9396 otpVersionsListing
9393 9397 .map((x) => x.assets)
9394 9398 .flat()
9395 .filter((x) => x.name.match(/^otp_win64_.*.exe$/))
9399 + .filter((x) => x.name.match(file_regex))
9396 9400 .forEach((x) => {
9397 const otpMatch = x.name.match(/^otp_win64_(.*).exe$/)
9401 + const otpMatch = x.name.match(file_regex)
9398 9402 const otpVersion = otpMatch[1]
9399 9403 debugLog('OTP line and parsing', [otpMatch, otpVersion])
9400 9404 otpVersions[otpVersion] = otpVersion
@@ -9899,7 +9903,9 @@ async function install(toolName, opts) {
9899 9903 win32: {
9900 9904 downloadToolURL: () =>
9901 9905 'https://github.com/erlang/otp/releases/download/' +
9902 `OTP-${toolVersion}/otp_win64_${toolVersion}.exe`,
9906 + `OTP-${toolVersion}/otp_win${getInput(
9907 + 'otp-architecture',
9908 + )}_${toolVersion}.exe`,
9903 9909 extract: async () => ['file', 'otp.exe'],
9904 9910 postExtract: async (cachePath) => {
9905 9911 const cmd = path.join(cachePath, 'otp.exe')
@@ -10155,6 +10161,21 @@ function checkPlatform() {
10155 10161 }
10156 10162 }
10157 10163
10164 +function checkOtpArchitecture() {
10165 + if (process.platform !== 'win32' && getInput('otp-architecture') == '32') {
10166 + throw new Error(
10167 + '@erlef/setup-beam only supports otp-architecture=32 on Windows',
10168 + )
10169 + }
10170 +
10171 + if (
10172 + getInput('otp-architecture') !== '32' &&
10173 + getInput('otp-architecture') !== '64'
10174 + ) {
10175 + throw new Error('otp-architecture must be 32 or 64')
10176 + }
10177 +}
10178 +
10158 10179 function debugLoggingEnabled() {
10159 10180 return !!process.env.RUNNER_DEBUG
10160 10181 }
modified src/setup-beam.js
+24 −3
@@ -14,6 +14,7 @@ main().catch((err) => {
14 14
15 15 async function main() {
16 16 checkPlatform()
17 + checkOtpArchitecture()
17 18
18 19 const versionFilePath = getInput('version-file', false)
19 20 let versions
@@ -288,13 +289,16 @@ async function getOTPVersions(osVersion) {
288 289 otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference
289 290 })
290 291 } else if (process.platform === 'win32') {
292 + const file_regex = new RegExp(
293 + `^otp_win${getInput('otp-architecture')}_(.*).exe$`,
294 + )
291 295 otpVersionsListings.forEach((otpVersionsListing) => {
292 296 otpVersionsListing
293 297 .map((x) => x.assets)
294 298 .flat()
295 .filter((x) => x.name.match(/^otp_win64_.*.exe$/))
299 + .filter((x) => x.name.match(file_regex))
296 300 .forEach((x) => {
297 const otpMatch = x.name.match(/^otp_win64_(.*).exe$/)
301 + const otpMatch = x.name.match(file_regex)
298 302 const otpVersion = otpMatch[1]
299 303 debugLog('OTP line and parsing', [otpMatch, otpVersion])
300 304 otpVersions[otpVersion] = otpVersion
@@ -799,7 +803,9 @@ async function install(toolName, opts) {
799 803 win32: {
800 804 downloadToolURL: () =>
801 805 'https://github.com/erlang/otp/releases/download/' +
802 `OTP-${toolVersion}/otp_win64_${toolVersion}.exe`,
806 + `OTP-${toolVersion}/otp_win${getInput(
807 + 'otp-architecture',
808 + )}_${toolVersion}.exe`,
803 809 extract: async () => ['file', 'otp.exe'],
804 810 postExtract: async (cachePath) => {
805 811 const cmd = path.join(cachePath, 'otp.exe')
@@ -1055,6 +1061,21 @@ function checkPlatform() {
1055 1061 }
1056 1062 }
1057 1063
1064 +function checkOtpArchitecture() {
1065 + if (process.platform !== 'win32' && getInput('otp-architecture') == '32') {
1066 + throw new Error(
1067 + '@erlef/setup-beam only supports otp-architecture=32 on Windows',
1068 + )
1069 + }
1070 +
1071 + if (
1072 + getInput('otp-architecture') !== '32' &&
1073 + getInput('otp-architecture') !== '64'
1074 + ) {
1075 + throw new Error('otp-architecture must be 32 or 64')
1076 + }
1077 +}
1078 +
1058 1079 function debugLoggingEnabled() {
1059 1080 return !!process.env.RUNNER_DEBUG
1060 1081 }
modified test/setup-beam.test.js
+24 −0
@@ -1,4 +1,5 @@
1 1 simulateInput('otp-version', '25.1.2')
2 +simulateInput('otp-architecture', '64')
2 3 simulateInput('elixir-version', '1.14.2')
3 4 simulateInput('rebar3-version', '3.20')
4 5 simulateInput('install-rebar', 'true')
@@ -283,6 +284,29 @@ async function testOTPVersions() {
283 284 expected = '23.0.4'
284 285 got = await setupBeam.getOTPVersion(spec, osVersion)
285 286 assert.deepStrictEqual(got, expected)
287 +
288 + // Check we get the same results for 32-bit OTP
289 + before = simulateInput('otp-architecture', '32')
290 +
291 + spec = '24.0.1'
292 + osVersion = 'windows-latest'
293 + expected = '24.0.1'
294 + got = await setupBeam.getOTPVersion(spec, osVersion)
295 + assert.deepStrictEqual(got, expected)
296 +
297 + spec = '23.2.x'
298 + osVersion = 'windows-2016'
299 + expected = '23.2.7'
300 + got = await setupBeam.getOTPVersion(spec, osVersion)
301 + assert.deepStrictEqual(got, expected)
302 +
303 + spec = '23.0'
304 + osVersion = 'windows-2019'
305 + expected = '23.0.4'
306 + got = await setupBeam.getOTPVersion(spec, osVersion)
307 + assert.deepStrictEqual(got, expected)
308 +
309 + simulateInput('otp-architecture', before)
286 310 }
287 311
288 312 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })

Parents: e5b6619