This repository has been archived by the owner on Jan 20, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathsetup-elixir.js
169 lines (138 loc) · 4.42 KB
/
setup-elixir.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
const core = require('@actions/core')
const {exec} = require('@actions/exec')
const {installElixir, installOTP} = require('./installer')
const path = require('path')
const semver = require('semver')
const https = require('https')
const {
fstat,
promises: {readFile},
} = require('fs')
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})
const otpVersion = await getOtpVersion(otpSpec)
const [elixirVersion, otpMajor] = await getElixirVersion(
elixirSpec,
otpVersion
)
let installHex = core.getInput('install-hex')
installHex = installHex == null ? 'true' : installHex
let installRebar = core.getInput('install-rebar')
installRebar = installRebar == null ? 'true' : installRebar
const experimentalOTP = core.getInput('experimental-otp')
const osVersion =
experimentalOTP === 'true' ? getRunnerOSVersion() : 'ubuntu-14.04'
console.log(`##[group]Installing OTP ${otpVersion} - built on ${osVersion}`)
await installOTP(otpVersion, osVersion)
console.log(`##[endgroup]`)
console.log(`##[group]Installing Elixir ${elixirVersion}`)
await installElixir(elixirVersion, otpMajor)
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}`
if (installRebar === 'true') await exec('mix local.rebar --force')
if (installHex === 'true') await exec('mix local.hex --force')
const matchersPath = path.join(__dirname, '..', '.github')
console.log(`##[add-matcher]${path.join(matchersPath, 'elixir.json')}`)
core.setOutput('otp-version', otpVersion)
core.setOutput('elixir-version', elixirVersion)
core.setOutput('osVersion', osVersion)
}
function checkPlatform() {
if (process.platform !== 'linux')
throw new Error(
'@actions/setup-elixir only supports Ubuntu Linux at this time'
)
}
async function getOtpVersion(spec) {
return getVersionFromSpec(spec, await getOtpVersions()) || spec
}
function getRunnerOSVersion(experimentalOTP) {
const mapToUbuntuVersion = {
ubuntu16: 'ubuntu-16.04',
ubuntu18: 'ubuntu-18.04',
ubuntu20: 'ubuntu-20.04',
}
return mapToUbuntuVersion[process.env.ImageOS] || 'ubuntu-18.04'
}
exports.getElixirVersion = getElixirVersion
async function getElixirVersion(spec, otpVersion) {
const versions = await getElixirVersions()
const semverRegex = /^v(\d+\.\d+\.\d+(?:-.+)?)/
const semverVersions = Array.from(versions.keys())
.filter(str => str.match(semverRegex))
.map(str => str.match(semverRegex)[1])
const version = getVersionFromSpec(spec, semverVersions)
const gitRef = version ? `v${version}` : spec
const [otpMajor] = otpVersion.match(/^\d+/)
if (versions.get(gitRef).includes(otpMajor)) {
return [gitRef, otpMajor]
} else {
return [gitRef, null]
}
}
function getVersionFromSpec(spec, versions) {
if (versions.includes(spec)) {
return spec
} else {
const range = semver.validRange(spec)
return semver.maxSatisfying(versions, range)
}
}
async function getOtpVersions() {
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
})
}
async function getElixirVersions() {
const result = await get('https://repo.hex.pm/builds/elixir/builds.txt')
const map = new Map()
result
.trim()
.split('\n')
.forEach(line => {
const match =
line.match(/^(v\d+\.\d+\.\d+(?:-.+)?)-otp-(\d+)/) ||
line.match(/^([^-]+)-otp-(\d+)/)
if (match) {
const [_, version, otp] = match
const array = map.get(version) || []
array.push(otp)
map.set(version, array)
}
})
return map
}
function get(url) {
if (process.env.NODE_ENV === 'test') {
return readFile(
path.join(__dirname, '..', '__tests__', 'builds.txt')
).then(buf => buf.toString())
}
return new Promise((resolve, reject) => {
const req = https.get(url)
req.on('response', res => {
let data = ''
res.on('data', chunk => {
data += chunk
})
res.on('end', () => {
resolve(data)
})
})
req.on('error', err => {
reject(err)
})
})
}