diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index df7e35c..3142042 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -69,47 +69,11 @@ jobs: - otp-version: '26' rebar3-version: 'nightly' os: 'ubuntu-latest' - - elixir-version: 'v1.6' - otp-version: '21' - rebar3-version: '3.12' - os: 'ubuntu-20.04' - - elixir-version: 'v1.7' - otp-version: '22' - rebar3-version: '3.13' - os: 'ubuntu-20.04' - - elixir-version: 'v1.10' - otp-version: '23' - rebar3-version: '3.14' - os: 'ubuntu-20.04' - - elixir-version: 'v1.13.4' - otp-version: '25.0.2' - rebar3-version: '3.19' - os: 'ubuntu-20.04' - - elixir-version: 'v1.12' - otp-version: '24' - rebar3-version: '3.15' - os: 'ubuntu-20.04' - - elixir-version: 'v1.11.0' - otp-version: '22.3.4.2' - os: 'ubuntu-20.04' - version-type: 'strict' - - elixir-version: '1.10.3' - otp-version: '22.3.4.1' - os: 'ubuntu-20.04' - version-type: 'strict' - - elixir-version: 'main' - otp-version: '23.1' - os: 'ubuntu-20.04' - version-type: 'strict' - - elixir-version: 'main' - otp-version: '25' - os: 'ubuntu-20.04' - version-type: 'strict' - - gleam-version: '1.5.1' + - gleam-version: '1.9.0' otp-version: '27' os: 'ubuntu-latest' disable_problem_matchers: true - - gleam-version: '1.5.1' + - gleam-version: '1.9.0' otp-version: false os: 'ubuntu-latest' disable_problem_matchers: true diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6825bbd..f8367c4 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -58,7 +58,7 @@ jobs: otp-version: '24' rebar3-version: '3.15' os: 'windows-latest' - - gleam-version: '1.5.1' + - gleam-version: '1.9.0' otp-version: '27' os: 'windows-latest' - elixir-version: 'v1.13' diff --git a/README.md b/README.md index e39d114..83e2908 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ jobs: test: runs-on: self-hosted env: - ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04 + ImageOS: ubuntu24 # equivalent to runs-on ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: erlef/setup-beam@v1 @@ -241,12 +241,12 @@ on: push jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}} strategy: matrix: - otp: ['21.1', '22.2', '23.3'] - elixir: ['1.8.2', '1.9.4'] + otp: ['25.3.2', '26.2.5', '27.3.3'] + elixir: ['1.17.3', '1.18.3'] steps: - uses: actions/checkout@v4 - uses: erlef/setup-beam@v1 @@ -265,12 +265,12 @@ on: push jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}} strategy: matrix: - otp: ['21.1', '22.2', '23.3'] - rebar3: ['3.14.1', '3.14.3'] + otp: ['25.3.2', '26.2.5', '27.3.3'] + rebar3: ['3.23.0', '3.24.0'] steps: - uses: actions/checkout@v4 - uses: erlef/setup-beam@v1 @@ -312,7 +312,7 @@ jobs: - uses: erlef/setup-beam@v1 with: otp-version: '27' - gleam-version: '1.5.1' + gleam-version: '1.9.0' - run: gleam test ``` @@ -330,7 +330,7 @@ jobs: - uses: erlef/setup-beam@v1 with: otp-version: false - gleam-version: '1.5.1' + gleam-version: '1.9.0' - run: gleam check ``` diff --git a/package.json b/package.json index 7f0a507..483f7cc 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "licenses": "yarn licenses generate-disclaimer > 3RD_PARTY_LICENSES", "markdownlint": "markdownlint *.md ./github/**/*.md", "shellcheck": "shellcheck .github/workflows/*.sh", - "test": "node test/setup-beam.test.js", + "test": "node --test --test-reporter=spec", "yamllint": "yamllint .github/workflows/**.yml && yamllint .*.yml && yamllint *.yml", "clean-dist": "rm -rf ./dist", "lint": "npm run markdownlint && npm run shellcheck && npm run yamllint && npm run jslint", diff --git a/test/setup-beam.test.js b/test/setup-beam.test.js index ee31e6d..0ded269 100644 --- a/test/setup-beam.test.js +++ b/test/setup-beam.test.js @@ -12,9 +12,9 @@ const http = require('http') const fs = require('fs') const os = require('os') const path = require('path') -const core = require('@actions/core') const setupBeam = require('../src/setup-beam') const { problemMatcher } = require('../matchers/elixir-matchers.json') +const { describe, it } = require('node:test') const matrix = { otp: { @@ -58,475 +58,437 @@ function parseReleases(version) { } } -async function all() { - await testFailInstallOTP() - await testFailInstallElixir() - await testFailInstallGleam() - await testFailInstallRebar3() - await testFailGetOTPVersion() - - await testOTPVersions() - await testLinuxARM64OTPVersions() - await testLinuxAMD64OTPVersions() - await testElixirVersions() - await testGleamVersions() - await testRebar3Versions() - - await testGetVersionFromSpec() - await testParseVersionFile() - await testGetRetry() - - await testElixirMixCompileError() - await testElixirMixCompileWarning() - await testElixirMixTestFailure() - await testElixirCredoOutputDefault() -} - -async function testFailInstallOTP() { - const otpOSVersion = 'ubuntu-08.04' - const otpVersion = 'OTP-23.2' - assert.rejects( - async () => { - await setupBeam.install('otp', { - hexMirror: 'https://builds.hex.pm', - otpOSVersion, - otpVersion, - }) - }, - (err) => { - assert.ok(err instanceof Error) - return true - }, - `Installing Erlang/OTP ${otpVersion} over ${otpOSVersion} is supposed to fail`, - ) -} - -async function testFailInstallElixir() { - let exVersion - - exVersion = '0.11' - assert.rejects( - async () => { - await setupBeam.install('elixir', { - hexMirror: 'https://builds.hex.pm', - exVersion, - }) - }, - (err) => { - assert.ok(err instanceof Error) - return true - }, - `Installing Elixir ${exVersion} is supposed to fail`, - ) - - exVersion = 'v1.0.0-otp-17' - assert.rejects( - async () => { - await setupBeam.install('elixir', { - hexMirror: 'https://builds.hex.pm', - exVersion, - }) - }, - (err) => { - assert.ok(err instanceof Error) - return true - }, - `Installing Elixir ${exVersion} is supposed to fail`, - ) -} - -async function testFailInstallGleam() { - const gleamVersion = '0.1.3' - assert.rejects( - async () => { - await setupBeam.install('gleam', { gleamVersion }) - }, - (err) => { - assert.ok(err instanceof Error) - return true - }, - `Installing Gleam ${gleamVersion} is supposed to fail`, - ) -} - -async function testFailInstallRebar3() { - const r3Version = '0.14.4' - assert.rejects( - async () => { - await setupBeam.install('rebar3', { r3Version }) - }, - (err) => { - assert.ok(err instanceof Error) - return true - }, - `Installing rebar3 ${r3Version} is supposed to fail`, - ) -} - -async function testOTPVersions() { - 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 }, - ) - - 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' - 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' - expected = 'OTP-27.0' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - - before = simulateInput('version-type', 'strict') - spec = '25.3.2.1' - osVersion = 'ubuntu-20.04' - expected = 'OTP-25.3.2.1' - got = await setupBeam.getOTPVersion(spec, osVersion) - 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) - 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) - assert.deepStrictEqual(got, expected) - - spec = 'master' - osVersion = 'ubuntu-22.04' - expected = 'master' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - - process.env.RUNNER_ARCH = previousRunnerArch - } - - if (process.platform === 'win32') { - 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) - - // 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 }) -} - -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) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - - before = simulateInput('version-type', 'strict') - spec = '27.0' - osVersion = 'ubuntu-24.04' - expected = 'OTP-27.0' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - - before = simulateInput('version-type', 'strict') - spec = '25.3.2.1' - osVersion = 'ubuntu-20.04' - expected = 'OTP-25.3.2.1' - got = await setupBeam.getOTPVersion(spec, osVersion) - 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) - 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) - assert.deepStrictEqual(got, expected) - - spec = 'master' - osVersion = 'ubuntu-22.04' - expected = 'master' - got = await setupBeam.getOTPVersion(spec, osVersion) - 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) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - - before = simulateInput('version-type', 'strict') - spec = '27.0' - osVersion = 'ubuntu-24.04' - expected = 'OTP-27.0' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) - - before = simulateInput('version-type', 'strict') - spec = '25.3.2.1' - osVersion = 'ubuntu-20.04' - expected = 'OTP-25.3.2.1' - got = await setupBeam.getOTPVersion(spec, osVersion) - 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) - 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) - assert.deepStrictEqual(got, expected) - - spec = 'master' - osVersion = 'ubuntu-22.04' - expected = 'master' - got = await setupBeam.getOTPVersion(spec, osVersion) - assert.deepStrictEqual(got, expected) - } - - simulateInput('hexpm-mirrors', hexMirrors, { multiline: true }) -} - -async function testFailGetOTPVersion() { - const previousRunnerArch = process.env.RUNNER_ARCH - process.env.RUNNER_ARCH = 'invalid' - - if (process.platform === 'linux') { - const spec = '26' - const osVersion = 'ubuntu-24.04' +describe('OTP install', () => { + it('fails for invalid OS version', async () => { + const otpOSVersion = 'ubuntu-08.04' + const otpVersion = 'OTP-23.2' assert.rejects( async () => { - await setupBeam.getOTPVersion(spec, osVersion) + await setupBeam.install('otp', { + hexMirror: 'https://builds.hex.pm', + otpOSVersion, + otpVersion, + }) }, (err) => { assert.ok(err instanceof Error) return true }, - `Fetching OTP Version with invalid Github runner architecture is supposed to fail`, + `Installing Erlang/OTP ${otpVersion} over ${otpOSVersion} is supposed to fail`, ) - } - process.env.RUNNER_ARCH = previousRunnerArch -} + }) +}) -async function testElixirVersions() { +describe('Elixir install', () => { + it('fails for version 0.11 without OTP', async () => { + const exVersion = '0.11' + assert.rejects( + async () => { + await setupBeam.install('elixir', { + hexMirror: 'https://builds.hex.pm', + exVersion, + }) + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Installing Elixir ${exVersion} is supposed to fail`, + ) + }) + + it('fails for version 1.0.0 on OTP 17 (without OTP)', async () => { + const exVersion = 'v1.0.0-otp-17' + assert.rejects( + async () => { + await setupBeam.install('elixir', { + hexMirror: 'https://builds.hex.pm', + exVersion, + }) + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Installing Elixir ${exVersion} is supposed to fail`, + ) + }) +}) + +describe('Gleam install', () => { + it('fails for unknown OTP', async () => { + const gleamVersion = '0.1.3' + assert.rejects( + async () => { + await setupBeam.install('gleam', { gleamVersion }) + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Installing Gleam ${gleamVersion} is supposed to fail`, + ) + }) +}) + +describe('rebar3 install', () => { + it('fails for unknown OTP', async () => { + const r3Version = '0.14.4' + assert.rejects( + async () => { + await setupBeam.install('rebar3', { r3Version }) + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Installing rebar3 ${r3Version} is supposed to fail`, + ) + }) +}) + +describe('.getOTPVersion(_) - Erlang', () => { + 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 previousRunnerArch = process.env.RUNNER_ARCH + + if (process.platform === 'linux') { + 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' + expected = 'OTP-27.0' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) + + before = simulateInput('version-type', 'strict') + spec = '25.3.2.1' + osVersion = 'ubuntu-20.04' + expected = 'OTP-25.3.2.1' + got = await setupBeam.getOTPVersion(spec, osVersion) + 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) + 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) + assert.deepStrictEqual(got, expected) + + spec = 'master' + osVersion = 'ubuntu-22.04' + expected = 'master' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + }) + } + + if (process.platform === 'win32') { + it('is Ok for known win32 version', async () => { + 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) + + // 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) + }) + } + + if (process.platform === 'linux') { + 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 = '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' + expected = 'OTP-27.0' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) + + before = simulateInput('version-type', 'strict') + spec = '25.3.2.1' + osVersion = 'ubuntu-20.04' + expected = 'OTP-25.3.2.1' + got = await setupBeam.getOTPVersion(spec, osVersion) + 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) + 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) + assert.deepStrictEqual(got, expected) + + spec = 'master' + osVersion = 'ubuntu-22.04' + expected = 'master' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + }) + + it('is Ok for known linux AMD64 version', async () => { + const amd64Options = setupBeam.githubAMDRunnerArchs() + 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' + expected = 'OTP-27.0' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) + + before = simulateInput('version-type', 'strict') + spec = '25.3.2.1' + osVersion = 'ubuntu-20.04' + expected = 'OTP-25.3.2.1' + got = await setupBeam.getOTPVersion(spec, osVersion) + 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) + 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) + assert.deepStrictEqual(got, expected) + + spec = 'master' + osVersion = 'ubuntu-22.04' + expected = 'master' + got = await setupBeam.getOTPVersion(spec, osVersion) + assert.deepStrictEqual(got, expected) + }) + } + + simulateInput('hexpm-mirrors', hexMirrors, { multiline: true }) + process.env.RUNNER_ARCH = previousRunnerArch +}) + +describe('OTP arch-specific install', () => { + it('fails for invalid GitHub runner arch.', async () => { + 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) + }, + (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 + }) +}) + +describe('.getOTPVersion(_) - Elixir', () => { let got let expected let spec @@ -536,116 +498,122 @@ async function testElixirVersions() { multiline: true, }) - spec = '1.1.x' - otpVersion = 'OTP-17' - expected = 'v1.1.1-otp-17' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) + it('returns the expected value', async () => { + spec = '1.1.x' + otpVersion = 'OTP-17' + expected = 'v1.1.1-otp-17' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) - spec = '1.10.4' - otpVersion = 'OTP-23' - expected = 'v1.10.4-otp-23' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) + spec = '1.10.4' + otpVersion = 'OTP-23' + expected = 'v1.10.4-otp-23' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) - spec = '1.12.1' - otpVersion = 'OTP-24.0.2' - expected = 'v1.12.1-otp-24' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) + spec = '1.12.1' + otpVersion = 'OTP-24.0.2' + expected = 'v1.12.1-otp-24' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) - before = simulateInput('version-type', 'strict') - spec = '1.14.0' - otpVersion = 'main' - expected = 'v1.14.0' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '1.14.0' + otpVersion = 'main' + expected = 'v1.14.0' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = 'v1.11.0-rc.0' - otpVersion = 'OTP-23' - expected = 'v1.11.0-rc.0-otp-23' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = 'v1.11.0-rc.0' + otpVersion = 'OTP-23' + expected = 'v1.11.0-rc.0-otp-23' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = 'v1.11.0-rc.0-otp-23' - otpVersion = 'OTP-23' - expected = 'v1.11.0-rc.0-otp-23' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = 'v1.11.0-rc.0-otp-23' + otpVersion = 'OTP-23' + expected = 'v1.11.0-rc.0-otp-23' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = 'v1.11.0' - otpVersion = '22.3.4.2' - expected = 'v1.11.0-otp-22' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = 'v1.11.0' + otpVersion = '22.3.4.2' + expected = 'v1.11.0-otp-22' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = 'main' - otpVersion = '23.1' - expected = 'main-otp-23' - got = await setupBeam.getElixirVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = 'main' + otpVersion = '23.1' + expected = 'main-otp-23' + got = await setupBeam.getElixirVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) + }) simulateInput('hexpm-mirrors', hexMirrors, { multiline: true }) -} +}) -async function testGleamVersions() { +describe('.getOTPVersion(_) - Gleam', () => { let got let expected let spec let otpVersion - spec = 'v0.3.0' - otpVersion = 'OTP-23' - expected = 'v0.3.0' - got = await setupBeam.getGleamVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) + it('returns the expected value', async () => { + spec = 'v0.3.0' + otpVersion = 'OTP-23' + expected = 'v0.3.0' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) - spec = '0.13.2' - otpVersion = 'OTP-24' - expected = 'v0.13.2' - got = await setupBeam.getGleamVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) + spec = '0.13.2' + otpVersion = 'OTP-24' + expected = 'v0.13.2' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) - const before = simulateInput('version-type', 'strict') - spec = 'v0.14.0-rc2' - otpVersion = 'OTP-22' - expected = 'v0.14.0-rc2' - got = await setupBeam.getGleamVersion(spec, otpVersion) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) -} + const before = simulateInput('version-type', 'strict') + spec = 'v0.14.0-rc2' + otpVersion = 'OTP-22' + expected = 'v0.14.0-rc2' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) + }) +}) -async function testRebar3Versions() { +describe('.getOTPVersion(_) - rebar3', () => { let got let expected let spec - spec = '3.10.x' - expected = '3.10.0' - got = await setupBeam.getRebar3Version(spec) - assert.deepStrictEqual(got, expected) + it('returns the expected value', async () => { + spec = '3.10.x' + expected = '3.10.0' + got = await setupBeam.getRebar3Version(spec) + assert.deepStrictEqual(got, expected) - spec = '3.11' - expected = '3.11.1' - got = await setupBeam.getRebar3Version(spec) - assert.deepStrictEqual(got, expected) + spec = '3.11' + expected = '3.11.1' + got = await setupBeam.getRebar3Version(spec) + assert.deepStrictEqual(got, expected) - spec = '3.10' - expected = '3.10.0' - got = await setupBeam.getRebar3Version(spec) - assert.deepStrictEqual(got, expected) -} + spec = '3.10' + expected = '3.10.0' + got = await setupBeam.getRebar3Version(spec) + assert.deepStrictEqual(got, expected) + }) +}) -async function testGetVersionFromSpec() { +describe('.getVersionFromSpec(_)', () => { let got let expected let spec @@ -691,339 +659,347 @@ async function testGetVersionFromSpec() { versions[version] = version }) - spec = '1' - expected = '1.1.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + it('returns the expected value', async () => { + spec = '1' + expected = '1.1.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '1.0' - expected = '1.0.9' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '1.0' + expected = '1.0.9' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - before = simulateInput('version-type', 'strict') - spec = '1' - expected = '1' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '1' + expected = '1' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = '1.0' - expected = '1.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '1.0' + expected = '1.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - spec = '2' - expected = '2.10' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '2' + expected = '2.10' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '3' - expected = '3.4.5.4.1' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '3' + expected = '3.4.5.4.1' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '3.2' - expected = '3.2.30.5' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '3.2' + expected = '3.2.30.5' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '>20' - expected = '24.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '>20' + expected = '24.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '24.0' - expected = '24.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '24.0' + expected = '24.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - before = simulateInput('version-type', 'strict') - spec = '24.0-rc3' - expected = '24.0-rc3' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '24.0-rc3' + expected = '24.0-rc3' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - spec = '24.0-rc2' - expected = '24.0-rc2' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '24.0-rc2' + expected = '24.0-rc2' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '22.3' - expected = '22.3.4.12.1' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '22.3' + expected = '22.3.4.12.1' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '23.3.3' - expected = '23.3.3' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '23.3.3' + expected = '23.3.3' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '24' - expected = '24.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '24' + expected = '24.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '23.3' - expected = '23.3.4' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '23.3' + expected = '23.3.4' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - before = simulateInput('version-type', 'strict') - spec = 'main' - expected = 'main' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = 'main' + expected = 'main' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - before = simulateInput('version-type', 'strict') - spec = '22.3.4.2' - expected = '22.3.4.2' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '22.3.4.2' + expected = '22.3.4.2' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - spec = '22.3.4.2' - expected = '22.3.4.2.1.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '22.3.4.2' + expected = '22.3.4.2.1.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '22.3.4.2.1' - expected = '22.3.4.2.1.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '22.3.4.2.1' + expected = '22.3.4.2.1.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '22.3.4.2.1.0' - expected = '22.3.4.2.1.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '22.3.4.2.1.0' + expected = '22.3.4.2.1.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '12.1.2.3' - expected = '12.1.2.3.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '12.1.2.3' + expected = '12.1.2.3.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = '22.3.4.2.1.0.1' - expected = null - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = '22.3.4.2.1.0.1' + expected = null + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - before = simulateInput('version-type', 'strict') - spec = '22.3.4.3' - expected = null - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) - simulateInput('version-type', before) + before = simulateInput('version-type', 'strict') + spec = '22.3.4.3' + expected = null + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', before) - spec = 'latest' - expected = '24.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = '24.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - versions = { - '27.0.0-rc3': '27.0.0-rc3', - '27.0.0-rc2': '27.0.0-rc2', - } - spec = 'latest' - expected = '27.0.0-rc3' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + versions = { + '27.0.0-rc3': '27.0.0-rc3', + '27.0.0-rc2': '27.0.0-rc2', + } + spec = 'latest' + expected = '27.0.0-rc3' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - versions = { - '27.0.0-rc3': '27.0.0-rc3', - '27.0.0-rc2': '27.0.0-rc2', - '27.0.0': '27.0.0', - } - spec = 'latest' - expected = '27.0.0' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + versions = { + '27.0.0-rc3': '27.0.0-rc3', + '27.0.0-rc2': '27.0.0-rc2', + '27.0.0': '27.0.0', + } + spec = 'latest' + expected = '27.0.0' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - versions = { '25.3.2.8': '25.3.2.8', '25.3.2.12': '25.3.2.12' } - spec = 'latest' - expected = '25.3.2.12' - got = setupBeam.getVersionFromSpec(spec, versions) - assert.deepStrictEqual(got, expected) + versions = { '25.3.2.8': '25.3.2.8', '25.3.2.12': '25.3.2.12' } + spec = 'latest' + expected = '25.3.2.12' + got = setupBeam.getVersionFromSpec(spec, versions) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'OTP-26.2.1' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-18.04']) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'OTP-26.2.1' + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-18.04']) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'OTP-27.0-rc3' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04']) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'OTP-27.0-rc3' + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04']) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'OTP-27.0-rc3' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'OTP-27.0-rc3' + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04']) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'OTP-27.0' - got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04']) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'OTP-27.0' + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04']) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = '27.0-rc3' - got = setupBeam.getVersionFromSpec(spec, matrix.otp.windows) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = '27.0-rc3' + got = setupBeam.getVersionFromSpec(spec, matrix.otp.windows) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'v1.16.2' - got = setupBeam.getVersionFromSpec(spec, matrix.elixir) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'v1.16.2' + got = setupBeam.getVersionFromSpec(spec, matrix.elixir) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = 'v1.1.0' - got = setupBeam.getVersionFromSpec(spec, matrix.gleam) - assert.deepStrictEqual(got, expected) + spec = 'latest' + expected = 'v1.1.0' + got = setupBeam.getVersionFromSpec(spec, matrix.gleam) + assert.deepStrictEqual(got, expected) - spec = 'latest' - expected = '3.23.0' - got = setupBeam.getVersionFromSpec(spec, matrix.rebar3) - assert.deepStrictEqual(got, expected) -} + spec = 'latest' + expected = '3.23.0' + got = setupBeam.getVersionFromSpec(spec, matrix.rebar3) + assert.deepStrictEqual(got, expected) + }) +}) -async function testParseVersionFile() { +describe('version file', () => { const otpVersion = unsimulateInput('otp-version') const elixirVersion = unsimulateInput('elixir-version') const gleamVersion = unsimulateInput('gleam-version') const rebar3Version = unsimulateInput('rebar3-version') - const erlang = '27' - const elixir = '1.17.0' - const gleam = '0.23.0' - const rebar3 = '3.24.0' - const toolVersions = `# a comment + it('is parsed correctly', async () => { + const erlang = '27' + const elixir = '1.17.0' + const gleam = '0.23.0' + const rebar3 = '3.24.0' + const toolVersions = `# a comment erlang ref:v${erlang}# comment, no space, and ref:v elixir ref:${elixir} # comment, with space and ref: not-gleam 0.23 # not picked up gleam ${gleam} \nrebar ${rebar3}` - const filename = 'test/.tool-versions' - fs.writeFileSync(filename, toolVersions) - process.env.GITHUB_WORKSPACE = '' - const appVersions = setupBeam.parseVersionFile(filename) - assert.strictEqual(appVersions.get('erlang'), erlang) - assert.strictEqual(appVersions.get('elixir'), elixir) + const filename = 'test/.tool-versions' + fs.writeFileSync(filename, toolVersions) + process.env.GITHUB_WORKSPACE = '' + const appVersions = setupBeam.parseVersionFile(filename) + assert.strictEqual(appVersions.get('erlang'), erlang) + assert.strictEqual(appVersions.get('elixir'), elixir) - const absoluteFilename = path.join(os.tmpdir(), '.tool-versions') - fs.writeFileSync(absoluteFilename, toolVersions) + const absoluteFilename = path.join(os.tmpdir(), '.tool-versions') + fs.writeFileSync(absoluteFilename, toolVersions) - process.env.GITHUB_WORKSPACE = process.cwd() - const absoluteAppVersions = setupBeam.parseVersionFile(absoluteFilename) - assert.strictEqual(absoluteAppVersions.get('erlang'), erlang) - assert.strictEqual(absoluteAppVersions.get('elixir'), elixir) + process.env.GITHUB_WORKSPACE = process.cwd() + const absoluteAppVersions = setupBeam.parseVersionFile(absoluteFilename) + assert.strictEqual(absoluteAppVersions.get('erlang'), erlang) + assert.strictEqual(absoluteAppVersions.get('elixir'), elixir) - assert.ok(async () => { - await setupBeam.install('otp', { toolVersion: erlang }) - }) - assert.ok(async () => { - await setupBeam.install('elixir', { toolVersion: elixir }) - }) - assert.ok(async () => { - await setupBeam.install('gleam', { toolVersion: gleam }) - }) - assert.ok(async () => { - await setupBeam.install('rebar3', { toolVersion: rebar3 }) + assert.ok(async () => { + await setupBeam.install('otp', { toolVersion: erlang }) + }) + assert.ok(async () => { + await setupBeam.install('elixir', { toolVersion: elixir }) + }) + assert.ok(async () => { + await setupBeam.install('gleam', { toolVersion: gleam }) + }) + assert.ok(async () => { + await setupBeam.install('rebar3', { toolVersion: rebar3 }) + }) }) simulateInput('otp-version', otpVersion) simulateInput('elixir-version', elixirVersion) simulateInput('gleam-version', gleamVersion) simulateInput('rebar3-version', rebar3Version) -} +}) -async function testGetRetry() { - let attempt = 0 - const server = http.createServer((req, res) => { - attempt++ - if (attempt == 2) { - res.write('correct!') - res.end() +describe('.get(_)', () => { + it('retries as expected', async () => { + let attempt = 0 + const server = http.createServer((req, res) => { + attempt++ + if (attempt == 2) { + res.write('correct!') + res.end() + } + }) + + try { + server.listen(0) + const port = server.address().port + + const response = await setupBeam.get(`http://localhost:${port}`, []) + assert.equal(response, 'correct!') + assert.equal(attempt, 2) + } finally { + server.close() } }) +}) - try { - server.listen(0) - const port = server.address().port +describe("Elixir Mix matcher's", () => { + it('errors are properly matched', async () => { + const [matcher] = problemMatcher.find( + ({ owner }) => owner === 'elixir-mixCompileError', + ).pattern - const response = await setupBeam.get(`http://localhost:${port}`, []) - assert.equal(response, 'correct!') - assert.equal(attempt, 2) - } finally { - server.close() - } -} + const output = '** (CompileError) lib/test.ex:16: undefined function err/0' + const [message, , file, line] = output.match(matcher.regexp) + assert.equal(file, 'lib/test.ex') + assert.equal(line, '16') + assert.equal(message, output) + }) -async function testElixirMixCompileError() { - const [matcher] = problemMatcher.find( - ({ owner }) => owner === 'elixir-mixCompileError', - ).pattern + it('warnings are properly matched', async () => { + const [messagePattern, filePattern] = problemMatcher.find( + ({ owner }) => owner === 'elixir-mixCompileWarning', + ).pattern - const output = '** (CompileError) lib/test.ex:16: undefined function err/0' - const [message, , file, line] = output.match(matcher.regexp) - assert.equal(file, 'lib/test.ex') - assert.equal(line, '16') - assert.equal(message, output) -} + const firstOutput = + 'warning: variable "err" does not exist and is being expanded to "err()"' + const secondOutput = ' lib/test.ex:16: Test.hello/0' -async function testElixirMixCompileWarning() { - const [messagePattern, filePattern] = problemMatcher.find( - ({ owner }) => owner === 'elixir-mixCompileWarning', - ).pattern + const [, message] = firstOutput.match(messagePattern.regexp) + assert.equal( + message, + 'variable "err" does not exist and is being expanded to "err()"', + ) - const firstOutput = - 'warning: variable "err" does not exist and is being expanded to "err()"' - const secondOutput = ' lib/test.ex:16: Test.hello/0' + const [, file, line] = secondOutput.match(filePattern.regexp) + assert.equal(file, 'lib/test.ex') + assert.equal(line, '16') + }) - const [, message] = firstOutput.match(messagePattern.regexp) - assert.equal( - message, - 'variable "err" does not exist and is being expanded to "err()"', - ) + it('failures are properly matched', async () => { + const [messagePattern, filePattern] = problemMatcher.find( + ({ owner }) => owner === 'elixir-mixTestFailure', + ).pattern - const [, file, line] = secondOutput.match(filePattern.regexp) - assert.equal(file, 'lib/test.ex') - assert.equal(line, '16') -} + const firstOutput = '1) test throws (TestTest)' + const secondOutput = ' test/test_test.exs:9' -async function testElixirMixTestFailure() { - const [messagePattern, filePattern] = problemMatcher.find( - ({ owner }) => owner === 'elixir-mixTestFailure', - ).pattern + const [, message] = firstOutput.match(messagePattern.regexp) + assert.equal(message, 'test throws (TestTest)') - const firstOutput = '1) test throws (TestTest)' - const secondOutput = ' test/test_test.exs:9' + const [, file, line] = secondOutput.match(filePattern.regexp) + assert.equal(file, 'test/test_test.exs') + assert.equal(line, '9') + }) - const [, message] = firstOutput.match(messagePattern.regexp) - assert.equal(message, 'test throws (TestTest)') + it('Credo output is properly matched', async () => { + const [messagePattern, filePattern] = problemMatcher.find( + ({ owner }) => owner === 'elixir-credoOutputDefault', + ).pattern - const [, file, line] = secondOutput.match(filePattern.regexp) - assert.equal(file, 'test/test_test.exs') - assert.equal(line, '9') -} + const firstOutput = '┃ [F] → Function is too complex (CC is 29, max is 9).' + const secondOutput = '┃ lib/test.ex:15:7 #(Test.hello)' -async function testElixirCredoOutputDefault() { - const [messagePattern, filePattern] = problemMatcher.find( - ({ owner }) => owner === 'elixir-credoOutputDefault', - ).pattern + const [, message] = firstOutput.match(messagePattern.regexp) + assert.equal(message, 'Function is too complex (CC is 29, max is 9).') - const firstOutput = '┃ [F] → Function is too complex (CC is 29, max is 9).' - const secondOutput = '┃ lib/test.ex:15:7 #(Test.hello)' - - const [, message] = firstOutput.match(messagePattern.regexp) - assert.equal(message, 'Function is too complex (CC is 29, max is 9).') - - const [, file, line, column] = secondOutput.match(filePattern.regexp) - assert.equal(file, 'lib/test.ex') - assert.equal(line, '15') - assert.equal(column, '7') -} + const [, file, line, column] = secondOutput.match(filePattern.regexp) + assert.equal(file, 'lib/test.ex') + assert.equal(line, '15') + assert.equal(column, '7') + }) +}) function unsimulateInput(key) { return simulateInput(key, '') @@ -1047,10 +1023,3 @@ function simulateInput(key, value0, opts) { function input(key) { return `INPUT_${key.replace(/ /g, '_').toUpperCase()}` } - -all() - .then(() => process.exit(0)) - .catch((err) => { - core.error(err) - process.exit(1) - })