Improve on "Add Windows to the mix" (#52)

* Support more OTP+Windows versions (try to bridge the gap with gleam-lang/setup-erlang that seems to support pre-21 versions)
* Merge ci.yml and test.yml
* Add Elixir to the Windows mix
* Hopefully improve error/warning messages
* Adapt the doc.s to the current reality
* Add option version-type (loose by default, for compatibility)
This commit is contained in:
Paulo F. Oliveira
2021-07-08 15:35:25 +01:00
committed by GitHub
parent 82b4475ba2
commit e1758e1fd9
21 changed files with 499 additions and 258 deletions
@@ -1,5 +1,5 @@
---
name: ci
name: action
on:
push:
@@ -11,7 +11,7 @@ on:
jobs:
check_integrity:
name: Make sure expected pre-release actions are performed
name: Expected local npm actions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -30,3 +30,13 @@ jobs:
- run: npm run licenses
- name: Check if build left artifacts
run: git diff --exit-code
unit_test:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with: {node-version: '12'}
- run: npm ci
- run: npm test
@@ -1,5 +1,5 @@
---
name: test
name: ubuntu
on:
push:
@@ -10,23 +10,11 @@ on:
- main
jobs:
unit_test:
name: Pre-release unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with: {node-version: '12'}
- run: npm ci
- run: npm test
integration_test_ubuntu:
integration_test:
name: >
Pre-release integration tests
(Ubuntu ${{matrix.combo.os}},
Erlang/OTP ${{matrix.combo.otp-version}},
Elixir ${{matrix.combo.elixir-version}},
rebar3 ${{matrix.combo.rebar3-version}})
OTP ${{matrix.combo.otp-version}},
Elixir ${{matrix.combo.elixir-version}},
rebar3 ${{matrix.combo.rebar3-version}}
runs-on: ${{matrix.combo.os}}
strategy:
fail-fast: false
@@ -138,43 +126,3 @@ jobs:
cd test-projects/rebar3
rebar3 ct
if: ${{matrix.combo.rebar3-version}}
integration_test_windows:
name: >
Pre-release integration tests
(Windows ${{matrix.combo.os}},
Erlang/OTP ${{matrix.combo.otp-version}},
rebar3 ${{matrix.combo.rebar3-version}})
runs-on: ${{matrix.combo.os}}
strategy:
fail-fast: false
matrix:
combo:
- otp-version: '24.0.2'
rebar3-version: '3.16'
os: 'windows-2019'
- otp-version: '23.0'
rebar3-version: '3.15'
os: 'windows-2019'
- otp-version: '24.0.2'
rebar3-version: '3.16'
os: 'windows-2016'
- otp-version: '23.0'
rebar3-version: '3.15'
os: 'windows-2016'
steps:
- uses: actions/checkout@v2
- name: Use erlef/setup-beam
id: setup-beam
uses: ./
with:
otp-version: ${{matrix.combo.otp-version}}
rebar3-version: ${{matrix.combo.rebar3-version}}
- name: Erlang/OTP version (action)
run: echo "Erlang/OTP ${{steps.setup-beam.outputs.otp-version}}"
- name: rebar3 version (action)
run: echo "rebar3 ${{steps.setup-beam.outputs.rebar3-version}}"
- name: Run rebar3 project tests
run: |
cd test-projects/rebar3
rebar3 ct
+87
View File
@@ -0,0 +1,87 @@
---
name: windows
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
integration_test:
name: >
OTP ${{matrix.combo.otp-version}},
Elixir ${{matrix.combo.elixir-version}},
rebar3 ${{matrix.combo.rebar3-version}}
runs-on: ${{matrix.combo.os}}
strategy:
fail-fast: false
matrix:
combo:
- otp-version: '24.0.2'
rebar3-version: '3.16'
os: 'windows-2019'
- otp-version: '23.0'
rebar3-version: '3.15'
os: 'windows-2019'
- otp-version: '24.0.2'
rebar3-version: '3.16'
os: 'windows-2016'
- otp-version: '23.0'
rebar3-version: '3.15'
os: 'windows-2016'
- otp-version: '22.3'
rebar3-version: '3.15'
os: 'windows-2016'
- otp-version: '22.0'
rebar3-version: '3.15'
os: 'windows-2016'
- otp-version: '21.3'
rebar3-version: '3.15'
os: 'windows-2016'
- otp-version: '21.0'
rebar3-version: '3.15'
os: 'windows-2016'
- elixir-version: 'v1.10'
otp-version: '23'
rebar3-version: '3.14'
os: 'windows-latest'
- elixir-version: 'v1.11'
otp-version: '24'
rebar3-version: '3.15'
os: 'windows-latest'
steps:
- uses: actions/checkout@v2
- name: Use erlef/setup-beam
id: setup-beam
uses: ./
with:
otp-version: ${{matrix.combo.otp-version}}
elixir-version: ${{matrix.combo.elixir-version}}
rebar3-version: ${{matrix.combo.rebar3-version}}
- name: Erlang/OTP version (action)
run: echo "Erlang/OTP ${{steps.setup-beam.outputs.otp-version}}"
- name: Elixir version (action)
run: echo "Elixir ${{steps.setup-beam.outputs.elixir-version}}"
if: ${{matrix.combo.elixir-version}}
- name: rebar3 version (action)
run: echo "rebar3 ${{steps.setup-beam.outputs.rebar3-version}}"
- name: mix version and help (CLI)
run: |
mix -v
mix help local.rebar
mix help local.hex
if: ${{matrix.combo.elixir-version}}
- name: Run Mix project tests
run: |
cd test-projects/mix
mix deps.get
mix test
if: ${{matrix.combo.elixir-version}}
- name: Run rebar3 project tests
run: |
cd test-projects/rebar3
rebar3 ct
if: ${{matrix.combo.rebar3-version}}
+28 -23
View File
@@ -1,10 +1,12 @@
<!-- markdownlint-disable MD013 -->
# setup-beam [![GitHub Actions Test][test-img]][test] [![GitHub Actions CI][ci-img]][ci]
# setup-beam [![GitHub Actions][action-img]][action] [![GitHub Actions][ubuntu-img]][ubuntu] [![GitHub Actions][windows-img]][windows]
[test]: https://github.com/erlef/setup-beam
[test-img]: https://github.com/erlef/setup-beam/workflows/test/badge.svg
[ci]: https://github.com/erlef/setup-beam
[ci-img]: https://github.com/erlef/setup-beam/workflows/ci/badge.svg
[action]: https://github.com/erlef/setup-beam
[action-img]: https://github.com/erlef/setup-beam/workflows/action/badge.svg
[ubuntu]: https://github.com/erlef/setup-beam
[ubuntu-img]: https://github.com/erlef/setup-beam/workflows/ubuntu/badge.svg
[windows]: https://github.com/erlef/setup-beam
[windows-img]: https://github.com/erlef/setup-beam/workflows/windows/badge.svg
This action sets up an Erlang/OTP environment for use in a GitHub Actions
workflow by:
@@ -14,7 +16,7 @@ workflow by:
- optionally, installing `rebar3`
- optionally, installing `hex`
**Note** Currently, this action only supports Actions' `ubuntu-` runtimes.
**Note** Currently, this action only supports Actions' `ubuntu-` and `windows-` runtimes.
## Usage
@@ -23,9 +25,10 @@ See [action.yml](action.yml) for the action's specification.
**Note**: The Erlang/OTP release version specification is [relatively
complex](http://erlang.org/doc/system_principles/versions.html#version-scheme).
For best results, we recommend specifying exact Erlang/OTP, Elixir versions, and
`rebar3` versions.
`rebar3` versions, and setting option `version-type` to `strict`.
However, values like `22.x`, or even `>22`, are also accepted, and we attempt to resolve them
according to semantic versioning rules.
according to semantic versioning rules. This implicitly means `version-type` is `loose`,
which is also the default value for this option.
Additionally, it is recommended that one specifies Erlang/OTP, Elixir and `rebar3` versions
using YAML strings, as these examples do, so that numbers like `23.0` don't
@@ -35,20 +38,22 @@ For pre-release Elixir versions, such as `1.11.0-rc.0`, use the full version
specifier (`1.11.0-rc.0`). Pre-release versions are opt-in, so `1.11.x` will
not match a pre-release.
### Compatibility between Ubuntu and Erlang/OTP
### Compatibility between Operating System and Erlang/OTP
This list presents the known working version combos between Ubuntu
This list presents the known working version combos between the target operating system
and Erlang/OTP.
| Ubuntu | Erlang/OTP | Status
|- |- |-
| ubuntu-16.04 | 17 - 24 | ✅
| ubuntu-18.04 | 17 - 24 | ✅
| ubuntu-20.04 | 20 - 24 | ✅
| windows-2016 | 23 - 24 | ✅
| windows-2019 | 23 - 24 | ✅
| Operating system | Erlang/OTP | Status
|- |- |-
| ubuntu-16.04 | 17 - 24 | ✅
| ubuntu-18.04 | 17 - 24 | ✅
| ubuntu-20.04 | 20 - 24 | ✅
| windows-2016 | 21* - 24 | ✅
| windows-2019 | 21* - 24 | ✅
### Basic example (Elixir)
**Note** *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.
### Basic example (Erlang/OTP + Elixir, on Ubuntu)
```yaml
# create this in .github/workflows/ci.yml
@@ -67,7 +72,7 @@ jobs:
- run: mix test
```
### Basic example (`rebar3`)
### Basic example (Erlang/OTP + `rebar3`, on Ubuntu)
```yaml
# create this in .github/workflows/ci.yml
@@ -85,7 +90,7 @@ jobs:
- run: rebar3 ct
```
### Matrix example (Elixir)
### Matrix example (Erlang/OTP + Elixir, on Ubuntu)
```yaml
# create this in .github/workflows/ci.yml
@@ -109,7 +114,7 @@ jobs:
- run: mix test
```
### Matrix example (`rebar3`)
### Matrix example (Erlang/OTP + `rebar3`, on Ubuntu)
```yaml
# create this in .github/workflows/ci.yml
@@ -132,7 +137,7 @@ jobs:
- run: rebar3 ct
```
### Basic example (`rebar3` on Windows 2016)
### Basic example (Erlang/OTP + `rebar3`, on Windows)
```yaml
# create this in .github/workflows/ci.yml
@@ -145,7 +150,7 @@ jobs:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
with:
otp-version: '24.0.2'
otp-version: '24'
rebar3-version: '3.16.1'
- run: rebar3 ct
```
+158 -11
View File
@@ -16,6 +16,8 @@ async function all() {
await testOTPVersions()
await testElixirVersions()
await testRebar3Versions()
await testGetVersionFromSpec()
}
async function testFailInstallOTP() {
@@ -84,37 +86,37 @@ async function testOTPVersions() {
if (process.platform === 'linux') {
spec = '19.3.x'
osVersion = 'ubuntu-16.04'
expected = 'OTP-19.3.6'
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'
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'
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'
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'
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'
expected = 'OTP-20.0.5'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
@@ -134,13 +136,13 @@ async function testOTPVersions() {
spec = '23.2.x'
osVersion = 'windows-2016'
expected = '23.2.7'
expected = '23.2.7.4'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
spec = '23.0'
osVersion = 'windows-2019'
expected = '23.0'
expected = '23.0.4'
got = await setupBeam.getOTPVersion(spec, osVersion)
assert.deepStrictEqual(got, expected)
}
@@ -164,11 +166,13 @@ async function testElixirVersions() {
got = await setupBeam.getElixirVersion(spec, otpVersion)
assert.deepStrictEqual(got, expected)
spec = '1.11.0-rc.0'
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', 'loose')
}
async function testRebar3Versions() {
@@ -181,8 +185,8 @@ async function testRebar3Versions() {
got = await setupBeam.getRebar3Version(spec)
assert.deepStrictEqual(got, expected)
spec = '3.10.0'
expected = '3.10.0'
spec = '3.11'
expected = '3.11.1'
got = await setupBeam.getRebar3Version(spec)
assert.deepStrictEqual(got, expected)
@@ -192,6 +196,149 @@ async function testRebar3Versions() {
assert.deepStrictEqual(got, expected)
}
async function testGetVersionFromSpec() {
let got
let expected
let spec
const versions = [
'3.2.30.5',
'3.2.3.5',
'1',
'2',
'3.2.3.4.1',
'1.0.9',
'3.2.3.40.1',
'1.0.2',
'2.0',
'2.10',
'2.9',
'1.0',
'3.2.3.4.2',
'1.1.0',
'3.4.5.4',
'3.4.5.3',
'3.4.5.4.1',
'24.0-rc3',
'24.0-rc2',
'24.0',
'23.3.4',
'23.3.3',
'22.3.4.9.1',
'22.3.4.12.1',
'22.3.4.10.1',
'master',
'v11.11.0-rc.0-otp-23',
]
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)
simulateInput('version-type', 'strict')
spec = '1'
expected = '1'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', 'loose')
simulateInput('version-type', 'strict')
spec = '1.0'
expected = '1.0'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', 'loose')
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.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 = '24.0'
expected = '24.0'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', 'strict')
spec = '24.0-rc3'
expected = '24.0-rc3'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', 'loose')
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 = '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)
simulateInput('version-type', 'strict')
spec = 'master'
expected = 'master'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
simulateInput('version-type', 'loose')
spec = 'master'
expected = 'master'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
spec = '11.11'
expected = 'v11.11.0-rc.0-otp-23'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
spec = '11.11.0'
expected = 'v11.11.0-rc.0-otp-23'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
spec = 'v11.11'
expected = 'v11.11.0-rc.0-otp-23'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
spec = 'v11.11.0'
expected = 'v11.11.0-rc.0-otp-23'
got = setupBeam.getVersionFromSpec(spec, versions)
assert.deepStrictEqual(got, expected)
}
function simulateInput(key, value) {
process.env[`INPUT_${key.replace(/ /g, '_').toUpperCase()}`] = value
}
+7 -3
View File
@@ -1,5 +1,5 @@
---
name: Setup Erlang/OTP with optional Elixir and/or rebar3
name: Setup Erlang/OTP with optional Elixir (and mix) and/or rebar3
description: >
Set up a specific version of Erlang/OTP, Elixir, and/or rebar3
and add the command-line tools to the PATH
@@ -13,13 +13,17 @@ inputs:
otp-version:
description: Version range or exact version of Erlang/OTP to use
install-hex:
description: Whether to install Hex
description: Whether to install Hex (with Mix)
default: true
install-rebar:
description: Whether to install Rebar
description: Whether to install Rebar (with Mix)
default: true
rebar3-version:
description: Version range or exact version of rebar3 to use
version-type:
description: strict means the versions are take as-are; loose means we try
to guess versions based on semver rules
default: loose
outputs:
elixir-version:
description: Exact version of Elixir that was installed
+81 -62
View File
@@ -4599,7 +4599,7 @@ async function installOTP(osVersion, otpVersion) {
await exec(__nccwpck_require__.ab + "install-otp.sh", [osVersion, otpVersion])
} else if (OS === 'win32') {
const script = __nccwpck_require__.ab + "install-otp.ps1"
await exec(`powershell.exe ${script} -VSN:${otpVersion}`)
await exec(`pwsh.exe ${script} -VSN:${otpVersion}`)
}
}
@@ -4614,7 +4614,7 @@ async function installElixir(elixirVersion) {
await exec(__nccwpck_require__.ab + "install-elixir.sh", [elixirVersion])
} else if (OS === 'win32') {
const script = __nccwpck_require__.ab + "install-elixir.ps1"
await exec(`powershell.exe ${script} ${elixirVersion}`)
await exec(`pwsh.exe ${script} -VSN:${elixirVersion}`)
}
}
@@ -4629,7 +4629,7 @@ async function installRebar3(rebar3Version) {
await exec(__nccwpck_require__.ab + "install-rebar3.sh", [rebar3Version])
} else if (OS === 'win32') {
const script = __nccwpck_require__.ab + "install-rebar3.ps1"
await exec(`powershell.exe ${script} -VSN:${rebar3Version}`)
await exec(`pwsh.exe ${script} -VSN:${rebar3Version}`)
}
}
@@ -4659,6 +4659,7 @@ const { exec } = __nccwpck_require__(1514)
const path = __nccwpck_require__(5622)
const semver = __nccwpck_require__(1383)
const https = __nccwpck_require__(7211)
const fs = __nccwpck_require__(5747)
const installer = __nccwpck_require__(2127)
main().catch((err) => {
@@ -4673,19 +4674,15 @@ async function main() {
const otpVersion = await installOTP(otpSpec, osVersion)
const elixirSpec = core.getInput('elixir-version', { required: false })
const shouldMixHex = core.getInput('install-hex', {
required: false,
})
const elixirInstalled = await maybeInstallElixir(
elixirSpec,
otpVersion,
shouldMixHex,
)
const elixirInstalled = await maybeInstallElixir(elixirSpec, otpVersion)
if (elixirInstalled === true) {
const shouldMixRebar = core.getInput('install-rebar', {
required: false,
})
await mix(shouldMixRebar, 'rebar')
const shouldMixHex = core.getInput('install-hex', {
required: false,
})
await mix(shouldMixHex, 'hex')
}
@@ -4701,16 +4698,22 @@ async function installOTP(otpSpec, osVersion) {
await installer.installOTP(osVersion, otpVersion)
core.setOutput('otp-version', otpVersion)
if (process.platform === 'linux') {
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/otp/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/otp/bin`)
} else if (process.platform === 'win32') {
prependToPath(`C:/Program Files/erl-${otpVersion}/bin`)
const otpPath = fs.readFileSync(`${process.env.RUNNER_TEMP}/otp_path.txt`, {
encoding: 'utf8',
flag: 'r',
})
core.addPath(otpPath)
}
console.log('##[endgroup]')
return otpVersion
}
async function maybeInstallElixir(elixirSpec, otpVersion, shouldMixHex) {
async function maybeInstallElixir(elixirSpec, otpVersion) {
let installed = false
if (elixirSpec) {
const elixirVersion = await getElixirVersion(elixirSpec, otpVersion)
console.log(`##[group]Installing Elixir ${elixirVersion}`)
@@ -4720,19 +4723,13 @@ async function maybeInstallElixir(elixirSpec, otpVersion, shouldMixHex) {
console.log(
`##[add-matcher]${path.join(matchersPath, 'elixir-matchers.json')}`,
)
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/elixir/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/elixir/bin`)
console.log('##[endgroup]')
return true
installed = true
}
if (shouldMixHex) {
console.log(
"hex will not be installed (overriding default) since Elixir wasn't either",
)
}
return false
return installed
}
async function mix(shouldMix, what) {
@@ -4746,18 +4743,20 @@ async function mix(shouldMix, what) {
}
async function maybeInstallRebar3(rebar3Spec) {
let installed = false
if (rebar3Spec) {
const rebar3Version = await getRebar3Version(rebar3Spec)
console.log(`##[group]Installing rebar3 ${rebar3Version}`)
await installer.installRebar3(rebar3Version)
core.setOutput('rebar3-version', rebar3Version)
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/rebar3/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/rebar3/bin`)
console.log('##[endgroup]')
return true
installed = true
}
return false
return installed
}
async function getOTPVersion(otpSpec0, osVersion) {
@@ -4766,7 +4765,7 @@ async function getOTPVersion(otpSpec0, osVersion) {
let otpVersion
if (otpSpec[1]) {
throw new Error(
`Requested Erlang/OTP version (from spec ${otpSpec0}) ` +
`Requested Erlang/OTP version (${otpSpec0}) ` +
"should not contain 'OTP-'",
)
}
@@ -4778,7 +4777,7 @@ async function getOTPVersion(otpSpec0, osVersion) {
}
if (otpVersion === null) {
throw new Error(
`Requested Erlang/OTP version (from spec ${otpSpec0}) not found in build listing`,
`Requested Erlang/OTP version (${otpSpec0}) not found in version list`,
)
}
@@ -4793,7 +4792,7 @@ async function getElixirVersion(exSpec0, otpVersion) {
let elixirVersion
if (exSpec[2]) {
throw new Error(
`Requested Elixir / Erlang/OTP version (from spec ${exSpec0} / ${otpVersion}) ` +
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) ` +
"should not contain '-otp-...'",
)
}
@@ -4802,7 +4801,7 @@ async function getElixirVersion(exSpec0, otpVersion) {
}
if (!exSpec || elixirVersion === null) {
throw new Error(
`Requested Elixir version (from spec ${exSpec0}) not found in build listing`,
`Requested Elixir version (${exSpec0}) not found in version list`,
)
}
const otpMatch = otpVersion.match(/^(?:OTP-)?([^.]+)/)
@@ -4824,8 +4823,8 @@ async function getElixirVersion(exSpec0, otpVersion) {
}
} else {
throw new Error(
`Requested Elixir / Erlang/OTP version (from spec ${exSpec0} / ${otpVersion}) not ` +
'found in build listing',
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
'found in version list',
)
}
@@ -4837,7 +4836,7 @@ async function getRebar3Version(r3Spec) {
const rebar3Version = getVersionFromSpec(r3Spec, rebar3Versions)
if (rebar3Version === null) {
throw new Error(
`Requested rebar3 version (from spec ${r3Spec}) not found in build listing`,
`Requested rebar3 version (${r3Spec}) not found in version list`,
)
}
@@ -4865,11 +4864,7 @@ async function getOTPVersions(osVersion) {
.split('\n')
.forEach((line) => {
const otpMatch = line.match(/^(OTP-)?([^ ]+)/)
let otpVersion = otpMatch[2]
if (semver.validRange(otpVersion) && hasPatch(otpVersion)) {
otpVersion = semver.minVersion(otpVersion).version
}
const otpVersion = otpMatch[2]
otpVersions.set(otpVersion, otpMatch[0]) // we keep the original for later reference
})
} else if (process.platform === 'win32') {
@@ -4880,10 +4875,7 @@ async function getOTPVersions(osVersion) {
.filter((x) => x.name.match(/^otp_win64_.*.exe$/))
.forEach((x) => {
const otpMatch = x.name.match(/^otp_win64_(.*).exe$/)
let otpVersion = otpMatch[1]
if (semver.validRange(otpVersion) && hasPatch(otpVersion)) {
otpVersion = semver.minVersion(otpVersion).version
}
const otpVersion = otpMatch[1]
otpVersions.set(otpVersion, otpVersion)
})
})
@@ -4934,11 +4926,54 @@ async function getRebar3Versions() {
}
function getVersionFromSpec(spec, versions) {
if (versions.includes(spec)) {
return spec
let version = null
if (core.getInput('version-type', { required: false }) === 'strict') {
version = spec
}
return semver.maxSatisfying(versions, semver.validRange(spec))
if (version === null) {
// We keep a map of semver => "spec" in order to use semver ranges to find appropriate versions
const versionsMap = versions.sort(sortVersions).reduce((acc, v) => {
try {
acc[semver.coerce(v).version] = v
} catch {
// some stuff can't be coerced, like 'master'
acc[v] = v
}
return acc
}, {})
const rangeForMax = semver.validRange(spec)
if (rangeForMax) {
version =
versionsMap[semver.maxSatisfying(Object.keys(versionsMap), rangeForMax)]
} else {
version = versionsMap[spec]
}
}
return version
}
function sortVersions(left, right) {
let ret = 0
const newL = verAsComparableStr(left)
const newR = verAsComparableStr(right)
function verAsComparableStr(ver) {
const matchGroups = 5
const verSpec = /([^.]+)?\.?([^.]+)?\.?([^.]+)?\.?([^.]+)?\.?([^.]+)?/
const matches = ver.match(verSpec).splice(1, matchGroups)
return matches.reduce((acc, v) => acc + (v || '0').padStart(3, '0'), '')
}
if (newL < newR) {
ret = -1
} else if (newL > newR) {
ret = 1
}
return ret
}
function getRunnerOSVersion() {
@@ -4998,27 +5033,11 @@ async function get(url0, pageIdxs) {
return ret
}
function prependToPath(what) {
if (process.platform === 'linux') {
process.env.PATH = `${what}:${process.env.PATH}`
} else if (process.platform === 'win32') {
process.env.PATH = `${what};${process.env.PATH}`
}
}
function hasPatch(v) {
try {
semver.patch(v)
} catch {
return false
}
return true
}
module.exports = {
getOTPVersion,
getElixirVersion,
getRebar3Version,
getVersionFromSpec,
}
+16 -2
View File
@@ -1,5 +1,19 @@
Write-Output "Installer for Elixir for Windows not available"
param([Parameter(Mandatory=$true)][string]$VSN)
$ErrorActionPreference="Stop"
Exit 1
Set-Location $Env:RUNNER_TEMP
$FILE_INPUT="${VSN}.zip"
$FILE_OUTPUT="elixir.zip"
$DIR_FOR_BIN=".setup-beam/elixir"
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://repo.hex.pm/builds/elixir/${FILE_INPUT}" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null
$ProgressPreference="SilentlyContinue"
Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}"
$ProgressPreference="Continue"
Write-Output "Installed Erlang/OTP version follows"
& "$DIR_FOR_BIN/bin/iex" "-v" | Write-Output
-4
View File
@@ -9,12 +9,8 @@ FILE_INPUT="${VSN}.zip"
FILE_OUTPUT=elixir.zip
DIR_FOR_BIN=.setup-beam/elixir
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://repo.hex.pm/builds/elixir/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}"
unzip -q -d "${DIR_FOR_BIN}" "${FILE_OUTPUT}"
rm -f "${FILE_OUTPUT}"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed Elixir version follows"
${DIR_FOR_BIN}/bin/iex -v
+4 -3
View File
@@ -7,13 +7,14 @@ Set-Location $Env:RUNNER_TEMP
$FILE_OUTPUT="otp.exe"
$DIR_FOR_BIN=".setup-beam/otp"
Remove-Item -Recurse -Force "$DIR_FOR_BIN" -ErrorAction SilentlyContinue
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://github.com/erlang/otp/releases/download/OTP-$VSN/otp_win64_$VSN.exe" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null
Move-Item "$FILE_OUTPUT" "$DIR_FOR_BIN"
Start-Process "./$DIR_FOR_BIN/$FILE_OUTPUT" /S -Wait
Write-Output "C:/Program Files/erl-$VSN/bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
$ErlExec = Get-ChildItem -Path "C:/Program Files/" -Recurse -Depth 2 -Filter 'erl.exe' -Name | ForEach-Object { Write-Output "C:/Program Files/$_" }
$ErlPath = Split-Path -Path "$ErlExec"
Write-Output "$ErlPath" | Out-File -FilePath otp_path.txt -Encoding utf8 -NoNewline
Write-Output "Installed Erlang/OTP version follows"
& "C:/Program Files/erl-$VSN/bin/erl.exe" "+V" | Write-Output
& "$ErlPath/erl.exe" "+V" | Write-Output
-4
View File
@@ -10,13 +10,9 @@ FILE_INPUT="${VSN}.tar.gz"
FILE_OUTPUT=otp.tar.gz
DIR_FOR_BIN=.setup-beam/otp
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://repo.hex.pm/builds/otp/${OS}/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}"
tar zxf "${FILE_OUTPUT}" -C "${DIR_FOR_BIN}" --strip-components=1
rm -f "${FILE_OUTPUT}"
"${DIR_FOR_BIN}/Install" -minimal "$(pwd)/${DIR_FOR_BIN}"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed Erlang/OTP version follows"
${DIR_FOR_BIN}/bin/erl -version
-3
View File
@@ -9,8 +9,6 @@ $FILE_OUTPUT="rebar3"
$FILE_OUTPUT_PS1="rebar3.ps1"
$DIR_FOR_BIN=".setup-beam/rebar3"
Remove-Item -Force "$FILE_OUTPUT" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "$DIR_FOR_BIN" -ErrorAction SilentlyContinue
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://github.com/erlang/rebar3/releases/download/${VSN}/${FILE_INPUT}" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
@@ -19,6 +17,5 @@ Move-Item "$FILE_OUTPUT" "$DIR_FOR_BIN/bin"
Write-Output "& escript.exe $PWD/$DIR_FOR_BIN/bin/$FILE_OUTPUT `$args" | Out-File -FilePath "$FILE_OUTPUT_PS1" -Encoding utf8 -Append
type $FILE_OUTPUT_PS1
Move-Item "$FILE_OUTPUT_PS1" "$DIR_FOR_BIN/bin"
Write-Output "$PWD/$DIR_FOR_BIN/bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
Write-Output "Installed rebar3 version follows"
& "$DIR_FOR_BIN/bin/rebar3" "version" | Write-Output
-3
View File
@@ -9,12 +9,9 @@ FILE_INPUT=rebar3
FILE_OUTPUT=rebar3
DIR_FOR_BIN=.setup-beam/rebar3
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://github.com/erlang/rebar3/releases/download/${VSN}/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}/bin"
chmod +x "${FILE_OUTPUT}"
mv "${FILE_OUTPUT}" "${DIR_FOR_BIN}/bin"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed rebar3 version follows"
${DIR_FOR_BIN}/bin/rebar3 version
+16 -2
View File
@@ -1,5 +1,19 @@
Write-Output "Installer for Elixir for Windows not available"
param([Parameter(Mandatory=$true)][string]$VSN)
$ErrorActionPreference="Stop"
Exit 1
Set-Location $Env:RUNNER_TEMP
$FILE_INPUT="${VSN}.zip"
$FILE_OUTPUT="elixir.zip"
$DIR_FOR_BIN=".setup-beam/elixir"
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://repo.hex.pm/builds/elixir/${FILE_INPUT}" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null
$ProgressPreference="SilentlyContinue"
Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}"
$ProgressPreference="Continue"
Write-Output "Installed Erlang/OTP version follows"
& "$DIR_FOR_BIN/bin/iex" "-v" | Write-Output
-4
View File
@@ -9,12 +9,8 @@ FILE_INPUT="${VSN}.zip"
FILE_OUTPUT=elixir.zip
DIR_FOR_BIN=.setup-beam/elixir
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://repo.hex.pm/builds/elixir/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}"
unzip -q -d "${DIR_FOR_BIN}" "${FILE_OUTPUT}"
rm -f "${FILE_OUTPUT}"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed Elixir version follows"
${DIR_FOR_BIN}/bin/iex -v
+4 -3
View File
@@ -7,13 +7,14 @@ Set-Location $Env:RUNNER_TEMP
$FILE_OUTPUT="otp.exe"
$DIR_FOR_BIN=".setup-beam/otp"
Remove-Item -Recurse -Force "$DIR_FOR_BIN" -ErrorAction SilentlyContinue
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://github.com/erlang/otp/releases/download/OTP-$VSN/otp_win64_$VSN.exe" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null
Move-Item "$FILE_OUTPUT" "$DIR_FOR_BIN"
Start-Process "./$DIR_FOR_BIN/$FILE_OUTPUT" /S -Wait
Write-Output "C:/Program Files/erl-$VSN/bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
$ErlExec = Get-ChildItem -Path "C:/Program Files/" -Recurse -Depth 2 -Filter 'erl.exe' -Name | ForEach-Object { Write-Output "C:/Program Files/$_" }
$ErlPath = Split-Path -Path "$ErlExec"
Write-Output "$ErlPath" | Out-File -FilePath otp_path.txt -Encoding utf8 -NoNewline
Write-Output "Installed Erlang/OTP version follows"
& "C:/Program Files/erl-$VSN/bin/erl.exe" "+V" | Write-Output
& "$ErlPath/erl.exe" "+V" | Write-Output
-4
View File
@@ -10,13 +10,9 @@ FILE_INPUT="${VSN}.tar.gz"
FILE_OUTPUT=otp.tar.gz
DIR_FOR_BIN=.setup-beam/otp
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://repo.hex.pm/builds/otp/${OS}/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}"
tar zxf "${FILE_OUTPUT}" -C "${DIR_FOR_BIN}" --strip-components=1
rm -f "${FILE_OUTPUT}"
"${DIR_FOR_BIN}/Install" -minimal "$(pwd)/${DIR_FOR_BIN}"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed Erlang/OTP version follows"
${DIR_FOR_BIN}/bin/erl -version
-3
View File
@@ -9,8 +9,6 @@ $FILE_OUTPUT="rebar3"
$FILE_OUTPUT_PS1="rebar3.ps1"
$DIR_FOR_BIN=".setup-beam/rebar3"
Remove-Item -Force "$FILE_OUTPUT" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "$DIR_FOR_BIN" -ErrorAction SilentlyContinue
$ProgressPreference="SilentlyContinue"
Invoke-WebRequest "https://github.com/erlang/rebar3/releases/download/${VSN}/${FILE_INPUT}" -OutFile "$FILE_OUTPUT"
$ProgressPreference="Continue"
@@ -19,6 +17,5 @@ Move-Item "$FILE_OUTPUT" "$DIR_FOR_BIN/bin"
Write-Output "& escript.exe $PWD/$DIR_FOR_BIN/bin/$FILE_OUTPUT `$args" | Out-File -FilePath "$FILE_OUTPUT_PS1" -Encoding utf8 -Append
type $FILE_OUTPUT_PS1
Move-Item "$FILE_OUTPUT_PS1" "$DIR_FOR_BIN/bin"
Write-Output "$PWD/$DIR_FOR_BIN/bin" | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append
Write-Output "Installed rebar3 version follows"
& "$DIR_FOR_BIN/bin/rebar3" "version" | Write-Output
-3
View File
@@ -9,12 +9,9 @@ FILE_INPUT=rebar3
FILE_OUTPUT=rebar3
DIR_FOR_BIN=.setup-beam/rebar3
rm -f "${FILE_OUTPUT}"
rm -rf "${DIR_FOR_BIN}"
wget -q -O "${FILE_OUTPUT}" "https://github.com/erlang/rebar3/releases/download/${VSN}/${FILE_INPUT}"
mkdir -p "${DIR_FOR_BIN}/bin"
chmod +x "${FILE_OUTPUT}"
mv "${FILE_OUTPUT}" "${DIR_FOR_BIN}/bin"
echo "$(pwd)/${DIR_FOR_BIN}/bin" >> "$GITHUB_PATH"
echo "Installed rebar3 version follows"
${DIR_FOR_BIN}/bin/rebar3 version
+3 -3
View File
@@ -13,7 +13,7 @@ async function installOTP(osVersion, otpVersion) {
await exec(path.join(__dirname, 'install-otp.sh'), [osVersion, otpVersion])
} else if (OS === 'win32') {
const script = path.join(__dirname, 'install-otp.ps1')
await exec(`powershell.exe ${script} -VSN:${otpVersion}`)
await exec(`pwsh.exe ${script} -VSN:${otpVersion}`)
}
}
@@ -28,7 +28,7 @@ async function installElixir(elixirVersion) {
await exec(path.join(__dirname, 'install-elixir.sh'), [elixirVersion])
} else if (OS === 'win32') {
const script = path.join(__dirname, 'install-elixir.ps1')
await exec(`powershell.exe ${script} ${elixirVersion}`)
await exec(`pwsh.exe ${script} -VSN:${elixirVersion}`)
}
}
@@ -43,7 +43,7 @@ async function installRebar3(rebar3Version) {
await exec(path.join(__dirname, 'install-rebar3.sh'), [rebar3Version])
} else if (OS === 'win32') {
const script = path.join(__dirname, 'install-rebar3.ps1')
await exec(`powershell.exe ${script} -VSN:${rebar3Version}`)
await exec(`pwsh.exe ${script} -VSN:${rebar3Version}`)
}
}
+78 -59
View File
@@ -3,6 +3,7 @@ const { exec } = require('@actions/exec')
const path = require('path')
const semver = require('semver')
const https = require('https')
const fs = require('fs')
const installer = require('./installer')
main().catch((err) => {
@@ -17,19 +18,15 @@ async function main() {
const otpVersion = await installOTP(otpSpec, osVersion)
const elixirSpec = core.getInput('elixir-version', { required: false })
const shouldMixHex = core.getInput('install-hex', {
required: false,
})
const elixirInstalled = await maybeInstallElixir(
elixirSpec,
otpVersion,
shouldMixHex,
)
const elixirInstalled = await maybeInstallElixir(elixirSpec, otpVersion)
if (elixirInstalled === true) {
const shouldMixRebar = core.getInput('install-rebar', {
required: false,
})
await mix(shouldMixRebar, 'rebar')
const shouldMixHex = core.getInput('install-hex', {
required: false,
})
await mix(shouldMixHex, 'hex')
}
@@ -45,16 +42,22 @@ async function installOTP(otpSpec, osVersion) {
await installer.installOTP(osVersion, otpVersion)
core.setOutput('otp-version', otpVersion)
if (process.platform === 'linux') {
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/otp/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/otp/bin`)
} else if (process.platform === 'win32') {
prependToPath(`C:/Program Files/erl-${otpVersion}/bin`)
const otpPath = fs.readFileSync(`${process.env.RUNNER_TEMP}/otp_path.txt`, {
encoding: 'utf8',
flag: 'r',
})
core.addPath(otpPath)
}
console.log('##[endgroup]')
return otpVersion
}
async function maybeInstallElixir(elixirSpec, otpVersion, shouldMixHex) {
async function maybeInstallElixir(elixirSpec, otpVersion) {
let installed = false
if (elixirSpec) {
const elixirVersion = await getElixirVersion(elixirSpec, otpVersion)
console.log(`##[group]Installing Elixir ${elixirVersion}`)
@@ -64,19 +67,13 @@ async function maybeInstallElixir(elixirSpec, otpVersion, shouldMixHex) {
console.log(
`##[add-matcher]${path.join(matchersPath, 'elixir-matchers.json')}`,
)
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/elixir/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/elixir/bin`)
console.log('##[endgroup]')
return true
installed = true
}
if (shouldMixHex) {
console.log(
"hex will not be installed (overriding default) since Elixir wasn't either",
)
}
return false
return installed
}
async function mix(shouldMix, what) {
@@ -90,18 +87,20 @@ async function mix(shouldMix, what) {
}
async function maybeInstallRebar3(rebar3Spec) {
let installed = false
if (rebar3Spec) {
const rebar3Version = await getRebar3Version(rebar3Spec)
console.log(`##[group]Installing rebar3 ${rebar3Version}`)
await installer.installRebar3(rebar3Version)
core.setOutput('rebar3-version', rebar3Version)
prependToPath(`${process.env.RUNNER_TEMP}/.setup-beam/rebar3/bin`)
core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/rebar3/bin`)
console.log('##[endgroup]')
return true
installed = true
}
return false
return installed
}
async function getOTPVersion(otpSpec0, osVersion) {
@@ -110,7 +109,7 @@ async function getOTPVersion(otpSpec0, osVersion) {
let otpVersion
if (otpSpec[1]) {
throw new Error(
`Requested Erlang/OTP version (from spec ${otpSpec0}) ` +
`Requested Erlang/OTP version (${otpSpec0}) ` +
"should not contain 'OTP-'",
)
}
@@ -122,7 +121,7 @@ async function getOTPVersion(otpSpec0, osVersion) {
}
if (otpVersion === null) {
throw new Error(
`Requested Erlang/OTP version (from spec ${otpSpec0}) not found in build listing`,
`Requested Erlang/OTP version (${otpSpec0}) not found in version list`,
)
}
@@ -137,7 +136,7 @@ async function getElixirVersion(exSpec0, otpVersion) {
let elixirVersion
if (exSpec[2]) {
throw new Error(
`Requested Elixir / Erlang/OTP version (from spec ${exSpec0} / ${otpVersion}) ` +
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) ` +
"should not contain '-otp-...'",
)
}
@@ -146,7 +145,7 @@ async function getElixirVersion(exSpec0, otpVersion) {
}
if (!exSpec || elixirVersion === null) {
throw new Error(
`Requested Elixir version (from spec ${exSpec0}) not found in build listing`,
`Requested Elixir version (${exSpec0}) not found in version list`,
)
}
const otpMatch = otpVersion.match(/^(?:OTP-)?([^.]+)/)
@@ -168,8 +167,8 @@ async function getElixirVersion(exSpec0, otpVersion) {
}
} else {
throw new Error(
`Requested Elixir / Erlang/OTP version (from spec ${exSpec0} / ${otpVersion}) not ` +
'found in build listing',
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
'found in version list',
)
}
@@ -181,7 +180,7 @@ async function getRebar3Version(r3Spec) {
const rebar3Version = getVersionFromSpec(r3Spec, rebar3Versions)
if (rebar3Version === null) {
throw new Error(
`Requested rebar3 version (from spec ${r3Spec}) not found in build listing`,
`Requested rebar3 version (${r3Spec}) not found in version list`,
)
}
@@ -209,11 +208,7 @@ async function getOTPVersions(osVersion) {
.split('\n')
.forEach((line) => {
const otpMatch = line.match(/^(OTP-)?([^ ]+)/)
let otpVersion = otpMatch[2]
if (semver.validRange(otpVersion) && hasPatch(otpVersion)) {
otpVersion = semver.minVersion(otpVersion).version
}
const otpVersion = otpMatch[2]
otpVersions.set(otpVersion, otpMatch[0]) // we keep the original for later reference
})
} else if (process.platform === 'win32') {
@@ -224,10 +219,7 @@ async function getOTPVersions(osVersion) {
.filter((x) => x.name.match(/^otp_win64_.*.exe$/))
.forEach((x) => {
const otpMatch = x.name.match(/^otp_win64_(.*).exe$/)
let otpVersion = otpMatch[1]
if (semver.validRange(otpVersion) && hasPatch(otpVersion)) {
otpVersion = semver.minVersion(otpVersion).version
}
const otpVersion = otpMatch[1]
otpVersions.set(otpVersion, otpVersion)
})
})
@@ -278,11 +270,54 @@ async function getRebar3Versions() {
}
function getVersionFromSpec(spec, versions) {
if (versions.includes(spec)) {
return spec
let version = null
if (core.getInput('version-type', { required: false }) === 'strict') {
version = spec
}
return semver.maxSatisfying(versions, semver.validRange(spec))
if (version === null) {
// We keep a map of semver => "spec" in order to use semver ranges to find appropriate versions
const versionsMap = versions.sort(sortVersions).reduce((acc, v) => {
try {
acc[semver.coerce(v).version] = v
} catch {
// some stuff can't be coerced, like 'master'
acc[v] = v
}
return acc
}, {})
const rangeForMax = semver.validRange(spec)
if (rangeForMax) {
version =
versionsMap[semver.maxSatisfying(Object.keys(versionsMap), rangeForMax)]
} else {
version = versionsMap[spec]
}
}
return version
}
function sortVersions(left, right) {
let ret = 0
const newL = verAsComparableStr(left)
const newR = verAsComparableStr(right)
function verAsComparableStr(ver) {
const matchGroups = 5
const verSpec = /([^.]+)?\.?([^.]+)?\.?([^.]+)?\.?([^.]+)?\.?([^.]+)?/
const matches = ver.match(verSpec).splice(1, matchGroups)
return matches.reduce((acc, v) => acc + (v || '0').padStart(3, '0'), '')
}
if (newL < newR) {
ret = -1
} else if (newL > newR) {
ret = 1
}
return ret
}
function getRunnerOSVersion() {
@@ -342,25 +377,9 @@ async function get(url0, pageIdxs) {
return ret
}
function prependToPath(what) {
if (process.platform === 'linux') {
process.env.PATH = `${what}:${process.env.PATH}`
} else if (process.platform === 'win32') {
process.env.PATH = `${what};${process.env.PATH}`
}
}
function hasPatch(v) {
try {
semver.patch(v)
} catch {
return false
}
return true
}
module.exports = {
getOTPVersion,
getElixirVersion,
getRebar3Version,
getVersionFromSpec,
}