diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8186c50f..89e910aa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -43,12 +43,6 @@ jobs: elixir-version: '1.14.3' os: 'macos-latest' version-type: 'strict' - - otp-version: '27' - os: 'macos-15' - version-type: 'strict' - - otp-version: '26' - os: 'macos-15' - version-type: 'strict' - otp-version: '25' os: 'macos-15' - otp-version: '26' diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 8051d670..c59f3ed4 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -53,12 +53,6 @@ jobs: elixir-version: '1.14.3' os: 'ubuntu-latest' version-type: 'strict' - - otp-version: '27' - os: 'ubuntu-24.04' - version-type: 'strict' - - otp-version: '26' - os: 'ubuntu-24.04' - version-type: 'strict' - otp-version: '25' os: 'ubuntu-24.04' - otp-version: '26' diff --git a/dist/index.js b/dist/index.js index ed5e5f27..80b5d53a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -26045,10 +26045,14 @@ async function maybeInstallRebar3(rebar3Spec) { return installed } +function maybeRemoveOTPPrefix(otpSpec) { + return otpSpec.replace(/^OTP-/, '') +} + async function getOTPVersion(otpSpec0, osVersion) { const [otpVersions, originListing, hexMirrors] = await getOTPVersions(osVersion) - let spec = otpSpec0.replace(/^OTP-/, '') + let spec = maybeRemoveOTPPrefix(otpSpec0) const versions = otpVersions const otpVersion = getVersionFromSpec(spec, versions) @@ -26224,12 +26228,9 @@ async function getOTPVersions(osVersion) { .trim() .split('\n') .forEach((line) => { - const otpMatch = line - .match(/^([^ ]+)?( .+)/)[1] - .match(/^([^-]+-)?(.+)$/) - const otpVersion = otpMatch[2] - const otpVersionOrig = otpMatch[0] - debugLog('OTP line and parsing', [line, otpVersion, otpMatch]) + const otpVersionOrig = line.match(/^([^ ]+)?( .+)/)[1] + const otpVersion = maybeRemoveOTPPrefix(otpVersionOrig) + debugLog('OTP line and parsing', [line, otpVersion, otpVersionOrig]) otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } else if (process.platform === 'win32') { @@ -26243,10 +26244,10 @@ async function getOTPVersions(osVersion) { .flat() .filter((x) => x.name.match(file_regex)) .forEach((x) => { - const otpMatch = x.name.match(file_regex) - const otpVersion = otpMatch[1] - debugLog('OTP line and parsing', [otpMatch, otpVersion]) - otpVersions[otpVersion] = otpVersion + const otpVersionOrig = x.name.match(file_regex)[1] + const otpVersion = otpVersionOrig + debugLog('OTP line and parsing', [x.name, otpVersion, otpVersionOrig]) + otpVersions[otpVersion] = otpVersionOrig }) }) } else if (process.platform === 'darwin') { @@ -26255,10 +26256,9 @@ async function getOTPVersions(osVersion) { columns: true, }) .forEach((line) => { - const otpMatch = line.ref_name.match(/^([^-]+-)?(.+)$/) - const otpVersion = otpMatch[2] - const otpVersionOrig = otpMatch[0] - debugLog('OTP line and parsing', [line, otpVersion, otpMatch]) + const otpVersionOrig = line.ref_name + const otpVersion = maybeRemoveOTPPrefix(otpVersionOrig) + debugLog('OTP line and parsing', [line, otpVersion, otpVersionOrig]) otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } @@ -26384,7 +26384,8 @@ function getVersionFromSpec(spec0, versions0) { isKnownBranch(version) || isKnownVerBranch(version) ) { - // If `version-type: strict` or version is RC, we just try to remove a potential initial v + // If `version-type: strict`, version is an RC, or version is "a branch" + // we just try to remove a potential initial v coerced = maybeRemoveVPrefix(version) } else { // Otherwise, we place the version into a version bucket @@ -26401,18 +26402,19 @@ function getVersionFromSpec(spec0, versions0) { const rangeMax = semver.maxSatisfying(versions, rangeForMax) let version = null - if ( + if (spec0 === 'latest') { + version = versions0[versions0.latest] + } else if ( isStrictVersion() || isRC(spec0) || isKnownBranch(spec0) || - isKnownVerBranch(spec0) + isKnownVerBranch(spec0) || + spec0 === 'nightly' ) { if (versions0[spec]) { // We obtain it directly version = versions0[spec] } - } else if (spec0 === 'latest') { - version = versions0[versions0.latest] } else if (rangeMax !== null) { // Otherwise, we compare alt. versions' semver ranges to this version, from highest to lowest const thatVersion = spec diff --git a/src/setup-beam.js b/src/setup-beam.js index dff6fbdb..5f55a1e7 100644 --- a/src/setup-beam.js +++ b/src/setup-beam.js @@ -170,10 +170,14 @@ async function maybeInstallRebar3(rebar3Spec) { return installed } +function maybeRemoveOTPPrefix(otpSpec) { + return otpSpec.replace(/^OTP-/, '') +} + async function getOTPVersion(otpSpec0, osVersion) { const [otpVersions, originListing, hexMirrors] = await getOTPVersions(osVersion) - let spec = otpSpec0.replace(/^OTP-/, '') + let spec = maybeRemoveOTPPrefix(otpSpec0) const versions = otpVersions const otpVersion = getVersionFromSpec(spec, versions) @@ -349,12 +353,9 @@ async function getOTPVersions(osVersion) { .trim() .split('\n') .forEach((line) => { - const otpMatch = line - .match(/^([^ ]+)?( .+)/)[1] - .match(/^([^-]+-)?(.+)$/) - const otpVersion = otpMatch[2] - const otpVersionOrig = otpMatch[0] - debugLog('OTP line and parsing', [line, otpVersion, otpMatch]) + const otpVersionOrig = line.match(/^([^ ]+)?( .+)/)[1] + const otpVersion = maybeRemoveOTPPrefix(otpVersionOrig) + debugLog('OTP line and parsing', [line, otpVersion, otpVersionOrig]) otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } else if (process.platform === 'win32') { @@ -368,10 +369,10 @@ async function getOTPVersions(osVersion) { .flat() .filter((x) => x.name.match(file_regex)) .forEach((x) => { - const otpMatch = x.name.match(file_regex) - const otpVersion = otpMatch[1] - debugLog('OTP line and parsing', [otpMatch, otpVersion]) - otpVersions[otpVersion] = otpVersion + const otpVersionOrig = x.name.match(file_regex)[1] + const otpVersion = otpVersionOrig + debugLog('OTP line and parsing', [x.name, otpVersion, otpVersionOrig]) + otpVersions[otpVersion] = otpVersionOrig }) }) } else if (process.platform === 'darwin') { @@ -380,10 +381,9 @@ async function getOTPVersions(osVersion) { columns: true, }) .forEach((line) => { - const otpMatch = line.ref_name.match(/^([^-]+-)?(.+)$/) - const otpVersion = otpMatch[2] - const otpVersionOrig = otpMatch[0] - debugLog('OTP line and parsing', [line, otpVersion, otpMatch]) + const otpVersionOrig = line.ref_name + const otpVersion = maybeRemoveOTPPrefix(otpVersionOrig) + debugLog('OTP line and parsing', [line, otpVersion, otpVersionOrig]) otpVersions[otpVersion] = otpVersionOrig // we keep the original for later reference }) } @@ -509,7 +509,8 @@ function getVersionFromSpec(spec0, versions0) { isKnownBranch(version) || isKnownVerBranch(version) ) { - // If `version-type: strict` or version is RC, we just try to remove a potential initial v + // If `version-type: strict`, version is an RC, or version is "a branch" + // we just try to remove a potential initial v coerced = maybeRemoveVPrefix(version) } else { // Otherwise, we place the version into a version bucket @@ -526,18 +527,19 @@ function getVersionFromSpec(spec0, versions0) { const rangeMax = semver.maxSatisfying(versions, rangeForMax) let version = null - if ( + if (spec0 === 'latest') { + version = versions0[versions0.latest] + } else if ( isStrictVersion() || isRC(spec0) || isKnownBranch(spec0) || - isKnownVerBranch(spec0) + isKnownVerBranch(spec0) || + spec0 === 'nightly' ) { if (versions0[spec]) { // We obtain it directly version = versions0[spec] } - } else if (spec0 === 'latest') { - version = versions0[versions0.latest] } else if (rangeMax !== null) { // Otherwise, we compare alt. versions' semver ranges to this version, from highest to lowest const thatVersion = spec diff --git a/test/setup-beam.test.js b/test/setup-beam.test.js index ac0733b7..2ad9d3ea 100644 --- a/test/setup-beam.test.js +++ b/test/setup-beam.test.js @@ -77,7 +77,7 @@ describe('OTP install', () => { const otpOSVersion = 'ubuntu-08.04' const otpVersion = 'OTP-23.2' - assert.rejects( + await assert.rejects( async () => { await setupBeam.install('otp', { hexMirror: 'https://builds.hex.pm', @@ -97,7 +97,7 @@ describe('OTP install', () => { describe('Elixir install', () => { it('fails for version 0.11 without OTP', async () => { const exVersion = '0.11' - assert.rejects( + await assert.rejects( async () => { await setupBeam.install('elixir', { hexMirror: 'https://builds.hex.pm', @@ -114,7 +114,7 @@ describe('Elixir install', () => { it('fails for version 1.0.0 on OTP 17 (without OTP)', async () => { const exVersion = 'v1.0.0-otp-17' - assert.rejects( + await assert.rejects( async () => { await setupBeam.install('elixir', { hexMirror: 'https://builds.hex.pm', @@ -133,7 +133,7 @@ describe('Elixir install', () => { describe('Gleam install', () => { it('fails for unknown OTP', async () => { const gleamVersion = '0.1.3' - assert.rejects( + await assert.rejects( async () => { await setupBeam.install('gleam', { gleamVersion }) }, @@ -149,7 +149,7 @@ describe('Gleam install', () => { describe('rebar3 install', () => { it('fails for unknown OTP', async () => { const r3Version = '0.14.4' - assert.rejects( + await assert.rejects( async () => { await setupBeam.install('rebar3', { r3Version }) }, @@ -179,14 +179,6 @@ describe('.getOTPVersion(_) - Erlang', () => { process.env.RUNNER_ARCH = 'X64' it('is Ok for known linux version', async () => { - before = simulateInput('version-type', 'strict') - spec = '26' - osVersion = 'ubuntu-24.04' - expected = 'maint-26' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') spec = '27.0' osVersion = 'ubuntu-24.04' @@ -311,19 +303,46 @@ describe('.getOTPVersion(_) - Erlang', () => { } if (process.platform === 'linux') { - it('is Ok for known linux ARM64 version', async () => { + it('is main-... only if strict/maint-... is used as input', async () => { const arm64Options = setupBeam.githubARMRunnerArchs() process.env.RUNNER_ARCH = arm64Options[Math.floor(Math.random() * arm64Options.length)] before = simulateInput('version-type', 'strict') - spec = '26' - osVersion = 'ubuntu-24.04' - expected = 'maint-26' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) + await assert.rejects( + async () => { + await setupBeam.getOTPVersion('27', 'ubuntu-24.04') + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Fetching strict OTP version maint- with input is supposed to fail`, + ) simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + assert.strictEqual( + await setupBeam.getOTPVersion('maint-27', 'ubuntu-24.04'), + 'maint-27', + ) + simulateInput('version-type', before) + + before = simulateInput('version-type', 'loose') + assert.strictEqual( + await setupBeam.getOTPVersion('maint-27', 'ubuntu-24.04'), + 'maint-27', + ) + simulateInput('version-type', before) + + process.env.RUNNER_ARCH = previousRunnerArch + }) + + it('is Ok for known linux ARM64 version', async () => { + const arm64Options = setupBeam.githubARMRunnerArchs() + process.env.RUNNER_ARCH = + arm64Options[Math.floor(Math.random() * arm64Options.length)] + before = simulateInput('version-type', 'strict') spec = '27.0' osVersion = 'ubuntu-24.04' @@ -388,14 +407,6 @@ describe('.getOTPVersion(_) - Erlang', () => { process.env.RUNNER_ARCH = amd64Options[Math.floor(Math.random() * amd64Options.length)] - before = simulateInput('version-type', 'strict') - spec = '26' - osVersion = 'ubuntu-24.04' - expected = 'maint-26' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') spec = '27.0' osVersion = 'ubuntu-24.04' @@ -475,6 +486,35 @@ describe('.getOTPVersion(_) - Erlang', () => { } if (process.platform === 'darwin') { + it('is main-... only if strict/maint-... is used as input', async () => { + const arm64Options = setupBeam.githubARMRunnerArchs() + process.env.RUNNER_ARCH = + arm64Options[Math.floor(Math.random() * arm64Options.length)] + + before = simulateInput('version-type', 'strict') + await assert.rejects( + async () => { + await setupBeam.getOTPVersion('27') + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Fetching strict OTP version maint- with input is supposed to fail`, + ) + simulateInput('version-type', before) + + before = simulateInput('version-type', 'strict') + assert.strictEqual(await setupBeam.getOTPVersion('maint-27'), 'maint-27') + simulateInput('version-type', before) + + before = simulateInput('version-type', 'loose') + assert.strictEqual(await setupBeam.getOTPVersion('maint-27'), 'maint-27') + simulateInput('version-type', before) + + process.env.RUNNER_ARCH = previousRunnerArch + }) + it('is Ok for known macos ARM64 version', async () => { const arm64Options = setupBeam.githubARMRunnerArchs() process.env.RUNNER_ARCH = @@ -517,7 +557,7 @@ describe('OTP arch-specific install', () => { const spec = '26' const osVersion = 'ubuntu-24.04' - assert.rejects( + await assert.rejects( async () => { await setupBeam.getOTPVersion(spec, osVersion) }, @@ -583,7 +623,7 @@ describe('.getOTPVersion(_) - Elixir', () => { before = simulateInput('version-type', 'strict') spec = 'v1.15.0-rc.2' - otpVersion = 'OTP-26' + otpVersion = 'OTP-26.0' expected = 'v1.15.0-rc.2-otp-26' await setupBeam.installOTP(otpVersion) got = await setupBeam.getElixirVersion(spec, otpVersion) @@ -617,6 +657,12 @@ describe('.getOTPVersion(_) - Gleam', () => { got = await setupBeam.getGleamVersion(spec, otpVersion) assert.deepStrictEqual(got, expected) + spec = 'nightly' + otpVersion = '28' + expected = 'nightly' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + spec = '0.13.2' otpVersion = 'OTP-24' expected = 'v0.13.2' @@ -870,11 +916,6 @@ describe('.getVersionFromSpec(_)', () => { got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04']) assert.deepStrictEqual(got, expected) - spec = 'maint-24' - expected = 'maint-24' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) - assert.deepStrictEqual(got, expected) - spec = '> 0' expected = 'OTP-26.2.5' got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) @@ -885,11 +926,6 @@ describe('.getVersionFromSpec(_)', () => { got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) assert.deepStrictEqual(got, expected) - spec = 'maint-26' - expected = 'maint-26' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) - assert.deepStrictEqual(got, expected) - spec = '> 0' expected = 'OTP-27.0' got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04'])