Files
setup-elixir/src/setup-elixir.js

166 lines
4.3 KiB
JavaScript
Raw Normal View History

2019-08-28 00:00:01 -04:00
const core = require('@actions/core')
const {exec} = require('@actions/exec')
const {installElixir, installOTP} = require('./installer')
const path = require('path')
const semver = require('semver')
2019-11-17 19:30:42 +01:00
const https = require('https')
2020-09-16 14:56:15 -04:00
const {
fstat,
promises: {readFile},
} = require('fs')
2019-08-28 00:00:01 -04:00
main().catch(err => {
core.setFailed(err.message)
})
async function main() {
checkPlatform()
const otpSpec = core.getInput('otp-version', {required: true})
const elixirSpec = core.getInput('elixir-version', {required: true})
2019-11-17 23:40:55 +01:00
const otpVersion = await getOtpVersion(otpSpec)
2019-12-04 13:54:33 -05:00
const [elixirVersion, otpMajor] = await getElixirVersion(
elixirSpec,
otpVersion
)
const osVersion = getOSVersion()
2019-08-28 00:00:01 -04:00
let installHex = core.getInput('install-hex')
installHex = installHex == null ? 'true' : installHex
2019-08-28 00:00:01 -04:00
let installRebar = core.getInput('install-rebar')
installRebar = installRebar == null ? 'true' : installRebar
2019-08-28 00:00:01 -04:00
console.log(`##[group]Installing OTP ${otpVersion} - built on ${osVersion}`)
await installOTP(otpVersion, osVersion)
2019-08-28 00:00:01 -04:00
console.log(`##[endgroup]`)
console.log(`##[group]Installing Elixir ${elixirVersion}`)
2019-11-17 19:30:42 +01:00
await installElixir(elixirVersion, otpMajor)
2019-08-28 00:00:01 -04:00
console.log(`##[endgroup]`)
process.env.PATH = `${process.env.RUNNER_TEMP}/.setup-elixir/elixir/bin:${process.env.RUNNER_TEMP}/.setup-elixir/otp/bin:${process.env.PATH}`
2019-12-04 13:54:33 -05:00
if (installRebar === 'true') await exec('mix local.rebar --force')
if (installHex === 'true') await exec('mix local.hex --force')
2019-11-26 23:38:31 -05:00
2019-12-04 13:54:33 -05:00
const matchersPath = path.join(__dirname, '..', '.github')
console.log(`##[add-matcher]${path.join(matchersPath, 'elixir.json')}`)
2020-08-05 10:52:42 -04:00
core.setOutput('otp-version', otpVersion)
core.setOutput('elixir-version', elixirVersion)
core.setOutput('osVersion', osVersion)
2019-08-28 00:00:01 -04:00
}
function checkPlatform() {
if (process.platform !== 'linux')
throw new Error(
'@actions/setup-elixir only supports Ubuntu Linux at this time'
)
}
2019-11-17 23:40:55 +01:00
async function getOtpVersion(spec) {
return getVersionFromSpec(spec, await getOtpVersions()) || spec
}
function getOSVersion() {
const mapToUbuntuVersion = {
ubuntu16: 'ubuntu-16.04',
ubuntu18: 'ubuntu-18.04',
ubuntu20: 'ubuntu-20.04',
}
return mapToUbuntuVersion[process.env.ImageOS] || 'ubuntu-18.04'
}
2020-09-16 14:56:15 -04:00
exports.getElixirVersion = getElixirVersion
2019-11-17 23:40:55 +01:00
async function getElixirVersion(spec, otpVersion) {
const versions = await getElixirVersions()
2020-09-16 14:56:15 -04:00
const semverRegex = /^v(\d+\.\d+\.\d+(?:-.+)?)/
2019-11-17 23:40:55 +01:00
2019-12-04 13:54:33 -05:00
const semverVersions = Array.from(versions.keys())
.filter(str => str.match(semverRegex))
.map(str => str.match(semverRegex)[1])
2019-11-17 23:40:55 +01:00
const version = getVersionFromSpec(spec, semverVersions)
const gitRef = version ? `v${version}` : spec
2019-11-17 19:30:42 +01:00
const [otpMajor] = otpVersion.match(/^\d+/)
2019-11-17 23:40:55 +01:00
if (versions.get(gitRef).includes(otpMajor)) {
return [gitRef, otpMajor]
2019-11-17 19:30:42 +01:00
} else {
2019-11-17 23:40:55 +01:00
return [gitRef, null]
2019-11-17 19:30:42 +01:00
}
}
function getVersionFromSpec(spec, versions) {
2019-11-19 22:03:23 +01:00
if (versions.includes(spec)) {
2019-12-04 13:54:33 -05:00
return spec
2019-11-19 22:03:23 +01:00
} else {
const range = semver.validRange(spec)
return semver.maxSatisfying(versions, range)
}
2019-08-28 00:00:01 -04:00
}
2019-11-17 19:30:42 +01:00
async function getOtpVersions() {
2019-12-04 13:54:33 -05:00
const result = await get(
'https://raw.githubusercontent.com/erlang/otp/master/otp_versions.table'
)
return result
.trim()
.split('\n')
.map(line => {
const [_, version] = line.match(/^OTP-([\.\d]+)/)
return version
})
2019-11-17 19:30:42 +01:00
}
async function getElixirVersions() {
2019-12-04 13:54:33 -05:00
const result = await get('https://repo.hex.pm/builds/elixir/builds.txt')
2019-11-17 19:30:42 +01:00
const map = new Map()
2019-12-04 13:54:33 -05:00
result
.trim()
.split('\n')
.forEach(line => {
const match =
2020-09-16 14:56:15 -04:00
line.match(/^(v\d+\.\d+\.\d+(?:-.+)?)-otp-(\d+)/) ||
2019-12-04 13:54:33 -05:00
line.match(/^([^-]+)-otp-(\d+)/)
if (match) {
const [_, version, otp] = match
const array = map.get(version) || []
array.push(otp)
map.set(version, array)
}
})
2019-11-17 19:30:42 +01:00
return map
}
function get(url) {
2020-09-16 14:56:15 -04:00
if (process.env.NODE_ENV === 'test') {
return readFile(
path.join(__dirname, '..', '__tests__', 'builds.txt')
).then(buf => buf.toString())
}
2019-11-17 19:30:42 +01:00
return new Promise((resolve, reject) => {
const req = https.get(url)
req.on('response', res => {
let data = ''
2019-12-04 13:54:33 -05:00
res.on('data', chunk => {
data += chunk
})
res.on('end', () => {
resolve(data)
})
2019-11-17 19:30:42 +01:00
})
2019-12-04 13:54:33 -05:00
req.on('error', err => {
reject(err)
})
2019-11-17 19:30:42 +01:00
})
}