mirror of
https://github.com/erlef/setup-beam.git
synced 2026-07-22 22:56:07 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6389fe58dc | |||
| 8fc1380bb7 | |||
| 3c915dd1b0 | |||
| e5d50587ee | |||
| b1273cf7cc | |||
| 9308cafcbf | |||
| 2971b073e5 | |||
| a0b139a890 | |||
| 6a38171948 | |||
| 75edbb8287 | |||
| a8bc27ec39 |
@@ -76,6 +76,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
install-rebar: false
|
||||
install-hex: false
|
||||
version-file: test/.tool-versions
|
||||
version-type: strict
|
||||
|
||||
|
||||
@@ -25,6 +25,15 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
combo:
|
||||
- otp-version: '<26'
|
||||
elixir-version: '<1.17'
|
||||
os: 'ubuntu-22.04'
|
||||
- otp-version: 'master'
|
||||
elixir-version: '> 0'
|
||||
os: 'ubuntu-24.04'
|
||||
- otp-version: 'master'
|
||||
elixir-version: 'main'
|
||||
os: 'ubuntu-24.04'
|
||||
- otp-version: '27'
|
||||
elixir-version: 'v1.17.0'
|
||||
rebar3-version: '3.23'
|
||||
|
||||
@@ -25,6 +25,12 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
combo:
|
||||
- otp-version: '<26'
|
||||
elixir-version: '<1.17'
|
||||
os: 'ubuntu-22.04'
|
||||
- otp-version: 'master'
|
||||
elixir-version: '> 0'
|
||||
os: 'ubuntu-24.04'
|
||||
- otp-version: '27'
|
||||
elixir-version: 'v1.17.0'
|
||||
rebar3-version: '3.23'
|
||||
|
||||
@@ -53,19 +53,25 @@ end up being parsed as `23`, which is not equivalent.
|
||||
|
||||
#### Pre-release versions
|
||||
|
||||
For pre-release versions, such as `v1.11.0-rc.0`, use the full version
|
||||
specifier (`v1.11.0-rc.0`) and set option `version-type` to `strict`. Pre-release versions are
|
||||
opt-in, so `1.11.x` will not match a pre-release.
|
||||
To use a pre-release version such as `v1.11.0-rc.0`, specify the exact version
|
||||
(`v1.11.0-rc.0`) and set `version-type` to `strict`.
|
||||
Note that pre-release versions are opt-in by default.
|
||||
Patterns like `1.11.x` do not include pre-release versions unless `latest` is specified.
|
||||
|
||||
#### "Latest" versions
|
||||
|
||||
Set a tool's version to `latest` to retrieve the latest version of a given tool.
|
||||
The latest version is (locally) calculated by the action based on the (retrieved) versions
|
||||
it knows (**note**: it is not the same as [GitHub considers it](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)
|
||||
and some repositories might propose).
|
||||
To retrieve the most recent available version of a tool, set the version to `latest`.
|
||||
This may include pre-release versions such as release candidates.
|
||||
|
||||
If in doubt do a test run and compare the obtained release with the one you were expecting to
|
||||
be the latest.
|
||||
If you want to target only the latest stable release and exclude pre-releases, use a
|
||||
version range like `> 0` instead.
|
||||
|
||||
Note that the `latest` version is determined locally by the action based on the versions it
|
||||
has retrieved. This may differ from how [GitHub defines "latest"](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository),
|
||||
and some repositories may present different interpretations.
|
||||
|
||||
If you're unsure, perform a test run and compare the resolved version against the version you
|
||||
expect to be considered the latest.
|
||||
|
||||
### Compatibility between Operating System and Erlang/OTP
|
||||
|
||||
|
||||
Vendored
+100
-41
@@ -25890,9 +25890,11 @@ const _ = __nccwpck_require__(2356)
|
||||
|
||||
const MAX_HTTP_RETRIES = 3
|
||||
|
||||
main().catch((err) => {
|
||||
core.setFailed(err.message)
|
||||
})
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
main().catch((err) => {
|
||||
core.setFailed(err.message)
|
||||
})
|
||||
}
|
||||
|
||||
async function main() {
|
||||
checkOtpArchitecture()
|
||||
@@ -25908,15 +25910,14 @@ async function main() {
|
||||
versions = parseVersionFile(versionFilePath)
|
||||
}
|
||||
|
||||
const osVersion = getRunnerOSVersion()
|
||||
const otpSpec = getInput('otp-version', true, 'erlang', versions)
|
||||
const elixirSpec = getInput('elixir-version', false, 'elixir', versions)
|
||||
const gleamSpec = getInput('gleam-version', false, 'gleam', versions)
|
||||
const rebar3Spec = getInput('rebar3-version', false, 'rebar', versions)
|
||||
|
||||
if (otpSpec !== 'false') {
|
||||
await installOTP(otpSpec, osVersion)
|
||||
const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
|
||||
await installOTP(otpSpec)
|
||||
const elixirInstalled = await maybeInstallElixir(elixirSpec)
|
||||
if (elixirInstalled === true) {
|
||||
const shouldMixRebar = getInput('install-rebar', false)
|
||||
await mix(shouldMixRebar, 'rebar')
|
||||
@@ -25932,11 +25933,12 @@ async function main() {
|
||||
await maybeInstallRebar3(rebar3Spec)
|
||||
|
||||
// undefined is replaced by a function, post- main branch merge
|
||||
const setupBeamVersion = 'abd725c'
|
||||
const setupBeamVersion = '8fc1380'
|
||||
core.setOutput('setup-beam-version', setupBeamVersion)
|
||||
}
|
||||
|
||||
async function installOTP(otpSpec, osVersion) {
|
||||
async function installOTP(otpSpec) {
|
||||
const osVersion = getRunnerOSVersion()
|
||||
const otpVersion = await getOTPVersion(otpSpec, osVersion)
|
||||
core.startGroup(
|
||||
`Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
|
||||
@@ -25958,10 +25960,10 @@ async function installOTP(otpSpec, osVersion) {
|
||||
return otpVersion
|
||||
}
|
||||
|
||||
async function maybeInstallElixir(elixirSpec, otpSpec) {
|
||||
async function maybeInstallElixir(elixirSpec) {
|
||||
let installed = false
|
||||
if (elixirSpec) {
|
||||
const elixirVersion = await getElixirVersion(elixirSpec, otpSpec)
|
||||
const elixirVersion = await getElixirVersion(elixirSpec)
|
||||
core.startGroup(`Installing Elixir ${elixirVersion}`)
|
||||
await doWithMirrors({
|
||||
hexMirrors: hexMirrorsInput(),
|
||||
@@ -26070,16 +26072,30 @@ function requestedVersionFor(tool, version, originListing, mirrors) {
|
||||
const knownBranches = ['main', 'master', 'maint']
|
||||
const nonSpecificVersions = ['nightly', 'latest']
|
||||
|
||||
async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
const otpVersion = otpVersion0.match(/^(?:OTP-)?(.+)$/)[1]
|
||||
const regex = `^(\\d{1,3}|${knownBranches.join('|')}|${nonSpecificVersions.join('|')})?.*$`
|
||||
let otpVersionMajor = otpVersion.match(new RegExp(regex))[1]
|
||||
|
||||
async function getElixirVersion(exSpec0) {
|
||||
const otpSuffix = /-otp-(\d+)/
|
||||
const userSuppliedOtp = exSpec0.match(otpSuffix)?.[1] ?? null
|
||||
let otpVersionMajor = ''
|
||||
|
||||
if (userSuppliedOtp && isVersion(userSuppliedOtp)) {
|
||||
otpVersionMajor = userSuppliedOtp
|
||||
} else {
|
||||
let cmd = 'erl'
|
||||
if (process.platform === 'win32') {
|
||||
cmd = 'erl.exe'
|
||||
}
|
||||
const args = [
|
||||
'-noshell',
|
||||
'-eval',
|
||||
'io:format(erlang:system_info(otp_release)), halt().',
|
||||
]
|
||||
await exec(cmd, args, {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
otpVersionMajor = data.toString()
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const [otpVersionsForElixirMap, elixirVersions, originListing, hexMirrors] =
|
||||
@@ -26094,17 +26110,29 @@ async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
)
|
||||
}
|
||||
|
||||
const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
|
||||
if (
|
||||
(elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
|
||||
!isVersion(otpVersionMajor)
|
||||
) {
|
||||
core.info(
|
||||
`Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
|
||||
)
|
||||
} else {
|
||||
let foundCombo = false
|
||||
let otpVersionMajorIter = parseInt(otpVersionMajor)
|
||||
let otpVersionsMajor = []
|
||||
while (otpVersionMajorIter > otpVersionMajor - 3) {
|
||||
otpVersionMajorIter += ''
|
||||
otpVersionsMajor.push(otpVersionMajorIter)
|
||||
const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
|
||||
if (
|
||||
(elixirVersionComp && elixirVersionComp.includes(otpVersionMajorIter)) ||
|
||||
!isVersion(otpVersionMajorIter)
|
||||
) {
|
||||
core.info(
|
||||
`Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajorIter})`,
|
||||
)
|
||||
foundCombo = true
|
||||
break
|
||||
}
|
||||
otpVersionMajorIter = parseInt(otpVersionMajorIter) - 1
|
||||
}
|
||||
|
||||
if (!foundCombo) {
|
||||
throw new Error(
|
||||
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
|
||||
`Requested Elixir / Erlang/OTP version (${exSpec0} / tried ${otpVersionsMajor}) not ` +
|
||||
'found in version list (did you check Compatibility between Elixir and Erlang/OTP?).' +
|
||||
'Elixir and Erlang/OTP compatibility can be found at: ' +
|
||||
'https://hexdocs.pm/elixir/compatibility-and-deprecations.html',
|
||||
@@ -26113,8 +26141,8 @@ async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
|
||||
let elixirVersionForDownload = elixirVersionFromSpec
|
||||
|
||||
if (isVersion(otpVersionMajor)) {
|
||||
elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
|
||||
if (isVersion(otpVersionMajorIter)) {
|
||||
elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajorIter}`
|
||||
}
|
||||
|
||||
return maybePrependWithV(elixirVersionForDownload)
|
||||
@@ -26323,6 +26351,7 @@ function validVersion(v) {
|
||||
v.match(
|
||||
new RegExp(`${knownBranches.join('|')}|${nonSpecificVersions.join('|')}`),
|
||||
) == null &&
|
||||
// these ones are for rebar3, which has alpha and beta releases
|
||||
!v.startsWith('a') &&
|
||||
!v.startsWith('b')
|
||||
)
|
||||
@@ -26349,7 +26378,12 @@ function getVersionFromSpec(spec0, versions0) {
|
||||
const altVersions = {}
|
||||
Object.entries(versions0).forEach(([version, altVersion]) => {
|
||||
let coerced
|
||||
if (isStrictVersion() || isRC(version)) {
|
||||
if (
|
||||
isStrictVersion() ||
|
||||
isRC(version) ||
|
||||
isKnownBranch(version) ||
|
||||
isKnownVerBranch(version)
|
||||
) {
|
||||
// If `version-type: strict` or version is RC, we just try to remove a potential initial v
|
||||
coerced = maybeRemoveVPrefix(version)
|
||||
} else {
|
||||
@@ -26367,9 +26401,14 @@ function getVersionFromSpec(spec0, versions0) {
|
||||
const rangeMax = semver.maxSatisfying(versions, rangeForMax)
|
||||
let version = null
|
||||
|
||||
if (isStrictVersion() || isRC(spec0) || isKnownBranch(spec0)) {
|
||||
if (
|
||||
isStrictVersion() ||
|
||||
isRC(spec0) ||
|
||||
isKnownBranch(spec0) ||
|
||||
isKnownVerBranch(spec0)
|
||||
) {
|
||||
if (versions0[spec]) {
|
||||
// If `version-type: strict` or version is RC, we obtain it directly
|
||||
// We obtain it directly
|
||||
version = versions0[spec]
|
||||
}
|
||||
} else if (spec0 === 'latest') {
|
||||
@@ -26486,17 +26525,33 @@ function getRunnerOSVersion() {
|
||||
macos14: 'macOS-14',
|
||||
macos15: 'macOS-15',
|
||||
}
|
||||
const deprecatedImageOSToContainer = {
|
||||
ubuntu18: 'ubuntu-18.04',
|
||||
ubuntu20: 'ubuntu-20.04',
|
||||
}
|
||||
const containerFromEnvImageOS = ImageOSToContainer[process.env.ImageOS]
|
||||
if (!containerFromEnvImageOS) {
|
||||
throw new Error(
|
||||
"Tried to map a target OS from env. variable 'ImageOS' (got " +
|
||||
`${process.env.ImageOS}` +
|
||||
"), but failed. If you're using a " +
|
||||
"self-hosted runner, you should set 'env': 'ImageOS': ... to one of the following: " +
|
||||
"['" +
|
||||
`${Object.keys(ImageOSToContainer).join("', '")}` +
|
||||
"']",
|
||||
)
|
||||
const deprecatedContainerFromEnvImageOS =
|
||||
deprecatedImageOSToContainer[process.env.ImageOS]
|
||||
if (deprecatedContainerFromEnvImageOS) {
|
||||
core.warning(
|
||||
`You are using deprecated ImageOS ${deprecatedContainerFromEnvImageOS}. ` +
|
||||
'Support for maintenance is very limited. Consider a non-deprecated version as ' +
|
||||
'mentioned in the README.md.',
|
||||
)
|
||||
|
||||
return deprecatedContainerFromEnvImageOS
|
||||
} else {
|
||||
throw new Error(
|
||||
"Tried to map a target OS from env. variable 'ImageOS' (got " +
|
||||
`${process.env.ImageOS}` +
|
||||
"), but failed. If you're using a " +
|
||||
"self-hosted runner, you should set 'env': 'ImageOS': ... to one of the following: " +
|
||||
"['" +
|
||||
`${Object.keys(ImageOSToContainer).join("', '")}` +
|
||||
"']",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return containerFromEnvImageOS
|
||||
@@ -26576,7 +26631,7 @@ function xyzAbcVersion(pref, suf) {
|
||||
// https://www.erlang.org/doc/system_principles/versions.html
|
||||
const dd = '\\.?(\\d+)?'
|
||||
return new RegExp(
|
||||
`${pref}v?(\\d+)${dd}${dd}${dd}${dd}${dd}(?:-rc\\.?\\d+)?(?:-otp-\\d+)?${suf}`,
|
||||
`${pref}(?:OTP-)?v?(\\d+)${dd}${dd}${dd}${dd}${dd}(?:-rc\\.?\\d+)?(?:-otp-\\d+)?${suf}`,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27046,14 +27101,18 @@ function debugLoggingEnabled() {
|
||||
|
||||
module.exports = {
|
||||
get,
|
||||
getOTPVersion,
|
||||
getElixirVersion,
|
||||
getGleamVersion,
|
||||
getOTPVersion,
|
||||
getRebar3Version,
|
||||
getVersionFromSpec,
|
||||
githubAMDRunnerArchs,
|
||||
githubARMRunnerArchs,
|
||||
install,
|
||||
installOTP,
|
||||
maybeInstallElixir,
|
||||
maybeInstallGleam,
|
||||
maybeInstallRebar3,
|
||||
parseVersionFile,
|
||||
}
|
||||
|
||||
|
||||
Generated
+21
-27
@@ -15,13 +15,13 @@
|
||||
"semver": "7.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.29.0",
|
||||
"@eslint/js": "9.30.0",
|
||||
"@vercel/ncc": "0.38.3",
|
||||
"eslint": "9.29.0",
|
||||
"eslint": "9.30.0",
|
||||
"eslint-plugin-yml": "1.18.0",
|
||||
"globals": "16.2.0",
|
||||
"markdownlint-cli": "0.45.0",
|
||||
"prettier": "3.6.0",
|
||||
"prettier": "3.6.2",
|
||||
"shellcheck": "3.1.0",
|
||||
"yarn": "1.22.22"
|
||||
},
|
||||
@@ -116,11 +116,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-array": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz",
|
||||
"integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==",
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
|
||||
"integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@eslint/object-schema": "^2.1.6",
|
||||
"debug": "^4.3.1",
|
||||
@@ -131,11 +130,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-helpers": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz",
|
||||
"integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==",
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
|
||||
"integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
@@ -191,11 +189,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz",
|
||||
"integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==",
|
||||
"version": "9.30.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.0.tgz",
|
||||
"integrity": "sha512-Wzw3wQwPvc9sHM+NjakWTcPx11mbZyiYHuwWa/QfZ7cIRX7WK54PSk7bdyXDaoaopUcMatv1zaQvOAAO8hCdww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
@@ -208,7 +205,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
|
||||
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
@@ -967,19 +963,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.29.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz",
|
||||
"integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
|
||||
"version": "9.30.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.0.tgz",
|
||||
"integrity": "sha512-iN/SiPxmQu6EVkf+m1qpBxzUhE12YqFLOSySuOyVLJLEF9nzTf+h/1AJYc1JWzCnktggeNrjvQGLngDzXirU6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
"@eslint/config-array": "^0.20.1",
|
||||
"@eslint/config-helpers": "^0.2.1",
|
||||
"@eslint/config-array": "^0.21.0",
|
||||
"@eslint/config-helpers": "^0.3.0",
|
||||
"@eslint/core": "^0.14.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "9.29.0",
|
||||
"@eslint/js": "9.30.0",
|
||||
"@eslint/plugin-kit": "^0.3.1",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
@@ -2777,11 +2772,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.0.tgz",
|
||||
"integrity": "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
|
||||
+3
-3
@@ -25,11 +25,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.38.3",
|
||||
"eslint": "9.29.0",
|
||||
"@eslint/js": "9.29.0",
|
||||
"eslint": "9.30.0",
|
||||
"@eslint/js": "9.30.0",
|
||||
"globals": "16.2.0",
|
||||
"markdownlint-cli": "0.45.0",
|
||||
"prettier": "3.6.0",
|
||||
"prettier": "3.6.2",
|
||||
"shellcheck": "3.1.0",
|
||||
"eslint-plugin-yml": "1.18.0",
|
||||
"yarn": "1.22.22"
|
||||
|
||||
+100
-41
@@ -10,9 +10,11 @@ const _ = require('lodash')
|
||||
|
||||
const MAX_HTTP_RETRIES = 3
|
||||
|
||||
main().catch((err) => {
|
||||
core.setFailed(err.message)
|
||||
})
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
main().catch((err) => {
|
||||
core.setFailed(err.message)
|
||||
})
|
||||
}
|
||||
|
||||
async function main() {
|
||||
checkOtpArchitecture()
|
||||
@@ -28,15 +30,14 @@ async function main() {
|
||||
versions = parseVersionFile(versionFilePath)
|
||||
}
|
||||
|
||||
const osVersion = getRunnerOSVersion()
|
||||
const otpSpec = getInput('otp-version', true, 'erlang', versions)
|
||||
const elixirSpec = getInput('elixir-version', false, 'elixir', versions)
|
||||
const gleamSpec = getInput('gleam-version', false, 'gleam', versions)
|
||||
const rebar3Spec = getInput('rebar3-version', false, 'rebar', versions)
|
||||
|
||||
if (otpSpec !== 'false') {
|
||||
await installOTP(otpSpec, osVersion)
|
||||
const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
|
||||
await installOTP(otpSpec)
|
||||
const elixirInstalled = await maybeInstallElixir(elixirSpec)
|
||||
if (elixirInstalled === true) {
|
||||
const shouldMixRebar = getInput('install-rebar', false)
|
||||
await mix(shouldMixRebar, 'rebar')
|
||||
@@ -52,11 +53,12 @@ async function main() {
|
||||
await maybeInstallRebar3(rebar3Spec)
|
||||
|
||||
// undefined is replaced by a function, post- main branch merge
|
||||
const setupBeamVersion = 'abd725c'
|
||||
const setupBeamVersion = '8fc1380'
|
||||
core.setOutput('setup-beam-version', setupBeamVersion)
|
||||
}
|
||||
|
||||
async function installOTP(otpSpec, osVersion) {
|
||||
async function installOTP(otpSpec) {
|
||||
const osVersion = getRunnerOSVersion()
|
||||
const otpVersion = await getOTPVersion(otpSpec, osVersion)
|
||||
core.startGroup(
|
||||
`Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
|
||||
@@ -78,10 +80,10 @@ async function installOTP(otpSpec, osVersion) {
|
||||
return otpVersion
|
||||
}
|
||||
|
||||
async function maybeInstallElixir(elixirSpec, otpSpec) {
|
||||
async function maybeInstallElixir(elixirSpec) {
|
||||
let installed = false
|
||||
if (elixirSpec) {
|
||||
const elixirVersion = await getElixirVersion(elixirSpec, otpSpec)
|
||||
const elixirVersion = await getElixirVersion(elixirSpec)
|
||||
core.startGroup(`Installing Elixir ${elixirVersion}`)
|
||||
await doWithMirrors({
|
||||
hexMirrors: hexMirrorsInput(),
|
||||
@@ -195,16 +197,30 @@ function requestedVersionFor(tool, version, originListing, mirrors) {
|
||||
const knownBranches = ['main', 'master', 'maint']
|
||||
const nonSpecificVersions = ['nightly', 'latest']
|
||||
|
||||
async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
const otpVersion = otpVersion0.match(/^(?:OTP-)?(.+)$/)[1]
|
||||
const regex = `^(\\d{1,3}|${knownBranches.join('|')}|${nonSpecificVersions.join('|')})?.*$`
|
||||
let otpVersionMajor = otpVersion.match(new RegExp(regex))[1]
|
||||
|
||||
async function getElixirVersion(exSpec0) {
|
||||
const otpSuffix = /-otp-(\d+)/
|
||||
const userSuppliedOtp = exSpec0.match(otpSuffix)?.[1] ?? null
|
||||
let otpVersionMajor = ''
|
||||
|
||||
if (userSuppliedOtp && isVersion(userSuppliedOtp)) {
|
||||
otpVersionMajor = userSuppliedOtp
|
||||
} else {
|
||||
let cmd = 'erl'
|
||||
if (process.platform === 'win32') {
|
||||
cmd = 'erl.exe'
|
||||
}
|
||||
const args = [
|
||||
'-noshell',
|
||||
'-eval',
|
||||
'io:format(erlang:system_info(otp_release)), halt().',
|
||||
]
|
||||
await exec(cmd, args, {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
otpVersionMajor = data.toString()
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const [otpVersionsForElixirMap, elixirVersions, originListing, hexMirrors] =
|
||||
@@ -219,17 +235,29 @@ async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
)
|
||||
}
|
||||
|
||||
const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
|
||||
if (
|
||||
(elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
|
||||
!isVersion(otpVersionMajor)
|
||||
) {
|
||||
core.info(
|
||||
`Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
|
||||
)
|
||||
} else {
|
||||
let foundCombo = false
|
||||
let otpVersionMajorIter = parseInt(otpVersionMajor)
|
||||
let otpVersionsMajor = []
|
||||
while (otpVersionMajorIter > otpVersionMajor - 3) {
|
||||
otpVersionMajorIter += ''
|
||||
otpVersionsMajor.push(otpVersionMajorIter)
|
||||
const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
|
||||
if (
|
||||
(elixirVersionComp && elixirVersionComp.includes(otpVersionMajorIter)) ||
|
||||
!isVersion(otpVersionMajorIter)
|
||||
) {
|
||||
core.info(
|
||||
`Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajorIter})`,
|
||||
)
|
||||
foundCombo = true
|
||||
break
|
||||
}
|
||||
otpVersionMajorIter = parseInt(otpVersionMajorIter) - 1
|
||||
}
|
||||
|
||||
if (!foundCombo) {
|
||||
throw new Error(
|
||||
`Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
|
||||
`Requested Elixir / Erlang/OTP version (${exSpec0} / tried ${otpVersionsMajor}) not ` +
|
||||
'found in version list (did you check Compatibility between Elixir and Erlang/OTP?).' +
|
||||
'Elixir and Erlang/OTP compatibility can be found at: ' +
|
||||
'https://hexdocs.pm/elixir/compatibility-and-deprecations.html',
|
||||
@@ -238,8 +266,8 @@ async function getElixirVersion(exSpec0, otpVersion0) {
|
||||
|
||||
let elixirVersionForDownload = elixirVersionFromSpec
|
||||
|
||||
if (isVersion(otpVersionMajor)) {
|
||||
elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
|
||||
if (isVersion(otpVersionMajorIter)) {
|
||||
elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajorIter}`
|
||||
}
|
||||
|
||||
return maybePrependWithV(elixirVersionForDownload)
|
||||
@@ -448,6 +476,7 @@ function validVersion(v) {
|
||||
v.match(
|
||||
new RegExp(`${knownBranches.join('|')}|${nonSpecificVersions.join('|')}`),
|
||||
) == null &&
|
||||
// these ones are for rebar3, which has alpha and beta releases
|
||||
!v.startsWith('a') &&
|
||||
!v.startsWith('b')
|
||||
)
|
||||
@@ -474,7 +503,12 @@ function getVersionFromSpec(spec0, versions0) {
|
||||
const altVersions = {}
|
||||
Object.entries(versions0).forEach(([version, altVersion]) => {
|
||||
let coerced
|
||||
if (isStrictVersion() || isRC(version)) {
|
||||
if (
|
||||
isStrictVersion() ||
|
||||
isRC(version) ||
|
||||
isKnownBranch(version) ||
|
||||
isKnownVerBranch(version)
|
||||
) {
|
||||
// If `version-type: strict` or version is RC, we just try to remove a potential initial v
|
||||
coerced = maybeRemoveVPrefix(version)
|
||||
} else {
|
||||
@@ -492,9 +526,14 @@ function getVersionFromSpec(spec0, versions0) {
|
||||
const rangeMax = semver.maxSatisfying(versions, rangeForMax)
|
||||
let version = null
|
||||
|
||||
if (isStrictVersion() || isRC(spec0) || isKnownBranch(spec0)) {
|
||||
if (
|
||||
isStrictVersion() ||
|
||||
isRC(spec0) ||
|
||||
isKnownBranch(spec0) ||
|
||||
isKnownVerBranch(spec0)
|
||||
) {
|
||||
if (versions0[spec]) {
|
||||
// If `version-type: strict` or version is RC, we obtain it directly
|
||||
// We obtain it directly
|
||||
version = versions0[spec]
|
||||
}
|
||||
} else if (spec0 === 'latest') {
|
||||
@@ -611,17 +650,33 @@ function getRunnerOSVersion() {
|
||||
macos14: 'macOS-14',
|
||||
macos15: 'macOS-15',
|
||||
}
|
||||
const deprecatedImageOSToContainer = {
|
||||
ubuntu18: 'ubuntu-18.04',
|
||||
ubuntu20: 'ubuntu-20.04',
|
||||
}
|
||||
const containerFromEnvImageOS = ImageOSToContainer[process.env.ImageOS]
|
||||
if (!containerFromEnvImageOS) {
|
||||
throw new Error(
|
||||
"Tried to map a target OS from env. variable 'ImageOS' (got " +
|
||||
`${process.env.ImageOS}` +
|
||||
"), but failed. If you're using a " +
|
||||
"self-hosted runner, you should set 'env': 'ImageOS': ... to one of the following: " +
|
||||
"['" +
|
||||
`${Object.keys(ImageOSToContainer).join("', '")}` +
|
||||
"']",
|
||||
)
|
||||
const deprecatedContainerFromEnvImageOS =
|
||||
deprecatedImageOSToContainer[process.env.ImageOS]
|
||||
if (deprecatedContainerFromEnvImageOS) {
|
||||
core.warning(
|
||||
`You are using deprecated ImageOS ${deprecatedContainerFromEnvImageOS}. ` +
|
||||
'Support for maintenance is very limited. Consider a non-deprecated version as ' +
|
||||
'mentioned in the README.md.',
|
||||
)
|
||||
|
||||
return deprecatedContainerFromEnvImageOS
|
||||
} else {
|
||||
throw new Error(
|
||||
"Tried to map a target OS from env. variable 'ImageOS' (got " +
|
||||
`${process.env.ImageOS}` +
|
||||
"), but failed. If you're using a " +
|
||||
"self-hosted runner, you should set 'env': 'ImageOS': ... to one of the following: " +
|
||||
"['" +
|
||||
`${Object.keys(ImageOSToContainer).join("', '")}` +
|
||||
"']",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return containerFromEnvImageOS
|
||||
@@ -701,7 +756,7 @@ function xyzAbcVersion(pref, suf) {
|
||||
// https://www.erlang.org/doc/system_principles/versions.html
|
||||
const dd = '\\.?(\\d+)?'
|
||||
return new RegExp(
|
||||
`${pref}v?(\\d+)${dd}${dd}${dd}${dd}${dd}(?:-rc\\.?\\d+)?(?:-otp-\\d+)?${suf}`,
|
||||
`${pref}(?:OTP-)?v?(\\d+)${dd}${dd}${dd}${dd}${dd}(?:-rc\\.?\\d+)?(?:-otp-\\d+)?${suf}`,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,13 +1226,17 @@ function debugLoggingEnabled() {
|
||||
|
||||
module.exports = {
|
||||
get,
|
||||
getOTPVersion,
|
||||
getElixirVersion,
|
||||
getGleamVersion,
|
||||
getOTPVersion,
|
||||
getRebar3Version,
|
||||
getVersionFromSpec,
|
||||
githubAMDRunnerArchs,
|
||||
githubARMRunnerArchs,
|
||||
install,
|
||||
installOTP,
|
||||
maybeInstallElixir,
|
||||
maybeInstallGleam,
|
||||
maybeInstallRebar3,
|
||||
parseVersionFile,
|
||||
}
|
||||
|
||||
+78
-69
@@ -1,3 +1,5 @@
|
||||
process.env.NODE_ENV = 'test'
|
||||
|
||||
simulateInput('otp-version', '25.1.2')
|
||||
simulateInput('otp-architecture', '64')
|
||||
simulateInput('elixir-version', '1.14.2')
|
||||
@@ -536,77 +538,70 @@ describe('.getOTPVersion(_) - Elixir', () => {
|
||||
let spec
|
||||
let otpVersion
|
||||
let before
|
||||
const hexMirrors = simulateInput('hexpm-mirrors', 'https://repo.hex.pm', {
|
||||
multiline: true,
|
||||
})
|
||||
const previousRunnerArch = process.env.RUNNER_ARCH
|
||||
|
||||
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)
|
||||
if (process.platform === 'linux') {
|
||||
process.env.RUNNER_ARCH = 'X64'
|
||||
|
||||
spec = '1.10.4'
|
||||
otpVersion = 'OTP-23'
|
||||
expected = 'v1.10.4-otp-23'
|
||||
got = await setupBeam.getElixirVersion(spec, otpVersion)
|
||||
assert.deepStrictEqual(got, expected)
|
||||
it('returns the expected value', async () => {
|
||||
spec = '1.18.x'
|
||||
otpVersion = 'OTP-27'
|
||||
expected = 'v1.18.4-otp-27'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
got = await setupBeam.getElixirVersion(spec, otpVersion)
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
spec = '1.16.2-otp-26'
|
||||
otpVersion = 'OTP-27'
|
||||
expected = 'v1.16.2-otp-26'
|
||||
got = await setupBeam.getElixirVersion(spec, otpVersion)
|
||||
assert.deepStrictEqual(got, expected)
|
||||
spec = '1.18.2'
|
||||
otpVersion = 'OTP-27'
|
||||
expected = 'v1.18.2-otp-27'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
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.16.2-otp-26'
|
||||
otpVersion = 'OTP-27'
|
||||
expected = 'v1.16.2-otp-26'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
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)
|
||||
spec = '1.12.1'
|
||||
otpVersion = 'OTP-24.3.4'
|
||||
expected = 'v1.12.1-otp-24'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
got = await setupBeam.getElixirVersion(spec, otpVersion)
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
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 = '1.17'
|
||||
otpVersion = 'master'
|
||||
expected = 'v1.17-otp-27'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
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.15.0-rc.2'
|
||||
otpVersion = 'OTP-26'
|
||||
expected = 'v1.15.0-rc.2-otp-26'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
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 = '25.2'
|
||||
expected = 'main-otp-25'
|
||||
await setupBeam.installOTP(otpVersion)
|
||||
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 })
|
||||
process.env.RUNNER_ARCH = previousRunnerArch
|
||||
})
|
||||
|
||||
describe('.getOTPVersion(_) - Gleam', () => {
|
||||
@@ -875,11 +870,31 @@ describe('.getVersionFromSpec(_)', () => {
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04'])
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
spec = 'maint-24'
|
||||
expected = 'maint-24'
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04'])
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
spec = '> 0'
|
||||
expected = 'OTP-26.2.5'
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04'])
|
||||
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 = 'maint-26'
|
||||
expected = 'maint-26'
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04'])
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
spec = '> 0'
|
||||
expected = 'OTP-27.0'
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04'])
|
||||
assert.deepStrictEqual(got, expected)
|
||||
|
||||
spec = 'latest'
|
||||
expected = 'OTP-27.0'
|
||||
got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04'])
|
||||
@@ -921,18 +936,16 @@ describe('version file', () => {
|
||||
const otpVersion = unsimulateInput('otp-version')
|
||||
const elixirVersion = unsimulateInput('elixir-version')
|
||||
const gleamVersion = unsimulateInput('gleam-version')
|
||||
const rebar3Version = unsimulateInput('rebar3-version')
|
||||
|
||||
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}`
|
||||
gleam ${gleam} \n`
|
||||
const filename = 'test/.tool-versions'
|
||||
fs.writeFileSync(filename, toolVersions)
|
||||
process.env.GITHUB_WORKSPACE = ''
|
||||
@@ -957,15 +970,11 @@ gleam ${gleam} \nrebar ${rebar3}`
|
||||
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)
|
||||
})
|
||||
|
||||
describe('.get(_)', () => {
|
||||
|
||||
Reference in New Issue
Block a user