Allow version-type: strict + otp-version: master for Elixir -based builds (#144)

8d31e4d · Paulo F. Oliveira · 2022-10-19 20:10

4 files +117 -127
Message
{commit_body(@commit)}

Files changed

modified .github/workflows/ubuntu.yml
+9 −1
@@ -21,6 +21,13 @@ jobs:
21 21 fail-fast: false
22 22 matrix:
23 23 combo:
24 + - otp-version: 'master'
25 + elixir-version: '1.14.0'
26 + os: 'ubuntu-latest'
27 + - otp-version: 'master'
28 + elixir-version: '1.14.0'
29 + os: 'ubuntu-latest'
30 + version-type: 'strict'
24 31 - otp-version: '25'
25 32 elixir-version: '1'
26 33 rebar3-version: '3'
@@ -113,12 +120,13 @@ jobs:
113 120 - elixir-version: 'master'
114 121 otp-version: '23.1'
115 122 os: 'ubuntu-20.04'
116 - elixir-version: 'master'
123 + - elixir-version: 'main'
117 124 otp-version: '25'
118 125 os: 'ubuntu-20.04'
119 126 version-type: 'strict'
120 127 - gleam-version: 'nightly'
121 128 otp-version: '24'
129 + os: 'ubuntu-latest'
122 130 - gleam-version: '0.23'
123 131 otp-version: '24'
124 132 os: 'ubuntu-latest'
modified __tests__/setup-beam.test.js
+10 −2
@@ -188,6 +188,14 @@ async function testElixirVersions() {
188 188 got = await setupBeam.getElixirVersion(spec, otpVersion)
189 189 assert.deepStrictEqual(got, expected)
190 190
191 + simulateInput('version-type', 'strict')
192 + spec = '1.14.0'
193 + otpVersion = 'master'
194 + expected = 'v1.14.0'
195 + got = await setupBeam.getElixirVersion(spec, otpVersion)
196 + assert.deepStrictEqual(got, expected)
197 + simulateInput('version-type', 'loose')
198 +
191 199 simulateInput('version-type', 'strict')
192 200 spec = 'v1.11.0-rc.0'
193 201 otpVersion = 'OTP-23'
@@ -205,9 +213,9 @@ async function testElixirVersions() {
205 213 simulateInput('version-type', 'loose')
206 214
207 215 simulateInput('version-type', 'strict')
208 spec = 'master'
216 + spec = 'main'
209 217 otpVersion = '23.1'
210 expected = 'master-otp-23'
218 + expected = 'main-otp-23'
211 219 got = await setupBeam.getElixirVersion(spec, otpVersion)
212 220 assert.deepStrictEqual(got, expected)
213 221 simulateInput('version-type', 'loose')
modified dist/index.js
+49 −62
@@ -7189,8 +7189,8 @@ async function main() {
7189 7189 const rebar3Spec = core.getInput('rebar3-version', { required: false })
7190 7190
7191 7191 if (otpSpec !== 'false') {
7192 const otpVersion = await installOTP(otpSpec, osVersion)
7193 const elixirInstalled = await maybeInstallElixir(elixirSpec, otpVersion)
7192 + await installOTP(otpSpec, osVersion)
7193 + const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
7194 7194
7195 7195 if (elixirInstalled === true) {
7196 7196 const shouldMixRebar = core.getInput('install-rebar', {
@@ -7300,19 +7300,13 @@ async function maybeInstallRebar3(rebar3Spec) {
7300 7300
7301 7301 async function getOTPVersion(otpSpec0, osVersion) {
7302 7302 const otpVersions = await getOTPVersions(osVersion)
7303 const otpSpec = otpSpec0.match(/^(OTP-|maint-)?([^ ]+)/)
7304 let otpVersion
7305 if (otpSpec[1] && !isStrictVersion()) {
7306 throw new Error(
7307 `Requested Erlang/OTP version (${otpSpec0}) ` +
7308 "should not contain 'OTP-, or maint-'",
7309 )
7310 }
7311 if (otpSpec) {
7312 otpVersion = getVersionFromSpec(
7313 otpSpec[2],
7314 Array.from(otpVersions.keys()).sort(),
7315 )
7303 + let otpSpec = otpSpec0 // might be a branch (?)
7304 + const otpVersion = getVersionFromSpec(
7305 + otpSpec,
7306 + Array.from(otpVersions.keys()).sort(),
7307 + )
7308 + if (isVersion(otpSpec0)) {
7309 + otpSpec = `OTP-${otpSpec0}` // ... it's a version!
7316 7310 }
7317 7311 if (otpVersion === null) {
7318 7312 throw new Error(
@@ -7324,60 +7318,46 @@ async function getOTPVersion(otpSpec0, osVersion) {
7324 7318 return otpVersions.get(otpVersion) // from the reference, for download
7325 7319 }
7326 7320
7327 async function getElixirVersion(exSpec0, otpVersion) {
7321 +async function getElixirVersion(exSpec0, otpVersion0) {
7322 + const otpVersion = otpVersion0.match(/^([^-]+-)?(.+)$/)[2]
7323 + const otpVersionMajor = otpVersion.match(/^([^.]+).*$/)[1]
7328 7324 const elixirVersions = await getElixirVersions()
7329 7325 const semverVersions = Array.from(elixirVersions.keys()).sort()
7330
7331 const exSpec = exSpec0.match(/^v?(.+)(-otp-.+)/) || exSpec0.match(/^v?(.+)/)
7332 let elixirVersion
7333 if (exSpec[2] && !isStrictVersion()) {
7334 throw new Error(
7335 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) ` +
7336 "should not contain '-otp-...'",
7337 )
7326 + const exSpec = exSpec0.replace(/-otp-.*$/, '')
7327 + const elixirVersionFromSpec = getVersionFromSpec(exSpec, semverVersions, true)
7328 + let elixirVersionForDownload = elixirVersionFromSpec
7329 + if (isVersion(otpVersionMajor)) {
7330 + elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
7338 7331 }
7339 if (exSpec) {
7340 elixirVersion = getVersionFromSpec(exSpec[1], semverVersions)
7341 }
7342 if (!exSpec || elixirVersion === null) {
7332 + if (elixirVersionFromSpec === null) {
7343 7333 throw new Error(
7344 7334 `Requested Elixir version (${exSpec0}) not found in version list ` +
7345 7335 "(should you be using option 'version-type': 'strict'?)",
7346 7336 )
7347 7337 }
7348 const otpMatch = otpVersion.match(/^(?:OTP-)?([^.]+)/)
7349 let elixirVersionWithOTP
7350
7351 if (elixirVersions.get(elixirVersion)) {
7352 const otpVersionMajor = otpMatch[1]
7353 // We try for a version like `v1.4.5-otp-20`...
7354 if (elixirVersions.get(elixirVersion).includes(otpMatch[1])) {
7355 // ... and it's available: use it!
7356 elixirVersionWithOTP = `${elixirVersion}-otp-${otpVersionMajor}`
7357 core.info(
7358 `Using Elixir ${elixirVersion} (built for OTP ${otpVersionMajor})`,
7359 )
7360 } else {
7361 // ... and it's not available: exit with exception
7362 throw new Error(
7363 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
7364 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?)',
7365 )
7366 }
7338 +
7339 + const elixirVersionComp = elixirVersions.get(elixirVersionFromSpec)
7340 + if (
7341 + (elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
7342 + !isVersion(otpVersionMajor)
7343 + ) {
7344 + core.info(
7345 + `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
7346 + )
7367 7347 } else {
7368 7348 throw new Error(
7369 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
7370 "found in version list (should you be using option 'version-type': 'strict'?)",
7349 + `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
7350 + 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?)',
7371 7351 )
7372 7352 }
7373 7353
7374 return maybePrependWithV(elixirVersionWithOTP, elixirVersion)
7354 + return maybePrependWithV(elixirVersionForDownload)
7375 7355 }
7376 7356
7377 7357 async function getGleamVersion(gleamSpec0) {
7378 const gleamSpec = gleamSpec0.match(/^v?(.+)/)
7358 + const gleamSpec = gleamSpec0.match(/^v?(.+)$/)
7379 7359 const gleamVersions = await getGleamVersions()
7380 const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions)
7360 + const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions, true)
7381 7361 if (gleamVersion === null) {
7382 7362 throw new Error(
7383 7363 `Requested Gleam version (${gleamSpec0}) not found in version list ` +
@@ -7421,7 +7401,9 @@ async function getOTPVersions(osVersion) {
7421 7401 .trim()
7422 7402 .split('\n')
7423 7403 .forEach((line) => {
7424 const otpMatch = line.match(/^(OTP-|maint-)?([^ ]+)/)
7404 + const otpMatch = line
7405 + .match(/^([^ ]+)?( .+)/)[1]
7406 + .match(/^([^-]+-)?(.+)$/)
7425 7407 const otpVersion = otpMatch[2]
7426 7408 otpVersions.set(otpVersion, otpMatch[0]) // we keep the original for later reference
7427 7409 })
@@ -7438,7 +7420,6 @@ async function getOTPVersions(osVersion) {
7438 7420 })
7439 7421 })
7440 7422 }
7441
7442 7423 return otpVersions
7443 7424 }
7444 7425
@@ -7455,7 +7436,7 @@ async function getElixirVersions() {
7455 7436 .forEach((line) => {
7456 7437 const elixirMatch =
7457 7438 line.match(/^v?(.+)-otp-([^ ]+)/) || line.match(/^v?([^ ]+)/)
7458 const elixirVersion = elixirMatch[1]
7439 + const elixirVersion = maybePrependWithV(elixirMatch[1])
7459 7440 const otpVersion = elixirMatch[2]
7460 7441 const otpVersions = otpVersionsForElixirMap.get(elixirVersion) || []
7461 7442 if (otpVersion) {
@@ -7502,7 +7483,7 @@ function isStrictVersion() {
7502 7483 return core.getInput('version-type', { required: false }) === 'strict'
7503 7484 }
7504 7485
7505 function getVersionFromSpec(spec, versions) {
7486 +function getVersionFromSpec(spec, versions, maybePrependWithV0) {
7506 7487 let version = null
7507 7488
7508 7489 if (spec.match(/rc/) || isStrictVersion()) {
@@ -7527,7 +7508,11 @@ function getVersionFromSpec(spec, versions) {
7527 7508 }
7528 7509 }
7529 7510
7530 return version === null || version === undefined ? null : version
7511 + let v = version === null || version === undefined ? null : version
7512 + if (maybePrependWithV0 && v != null) {
7513 + v = maybePrependWithV(v)
7514 + }
7515 + return v
7531 7516 }
7532 7517
7533 7518 function maybeCoerced(v) {
@@ -7634,15 +7619,17 @@ async function get(url0, pageIdxs) {
7634 7619 return ret
7635 7620 }
7636 7621
7637 function maybePrependWithV(versionToPrepend, specVersion) {
7638 const digitStart = /^\d+/
7639 let v = versionToPrepend
7640 if (digitStart.test(specVersion)) {
7641 v = `v${versionToPrepend}`
7622 +function maybePrependWithV(v) {
7623 + if (isVersion(v)) {
7624 + return `v${v.replace('v', '')}`
7642 7625 }
7643 7626 return v
7644 7627 }
7645 7628
7629 +function isVersion(v) {
7630 + return /^v?\d+/.test(v)
7631 +}
7632 +
7646 7633 module.exports = {
7647 7634 getOTPVersion,
7648 7635 getElixirVersion,
modified src/setup-beam.js
+49 −62
@@ -19,8 +19,8 @@ async function main() {
19 19 const rebar3Spec = core.getInput('rebar3-version', { required: false })
20 20
21 21 if (otpSpec !== 'false') {
22 const otpVersion = await installOTP(otpSpec, osVersion)
23 const elixirInstalled = await maybeInstallElixir(elixirSpec, otpVersion)
22 + await installOTP(otpSpec, osVersion)
23 + const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
24 24
25 25 if (elixirInstalled === true) {
26 26 const shouldMixRebar = core.getInput('install-rebar', {
@@ -130,19 +130,13 @@ async function maybeInstallRebar3(rebar3Spec) {
130 130
131 131 async function getOTPVersion(otpSpec0, osVersion) {
132 132 const otpVersions = await getOTPVersions(osVersion)
133 const otpSpec = otpSpec0.match(/^(OTP-|maint-)?([^ ]+)/)
134 let otpVersion
135 if (otpSpec[1] && !isStrictVersion()) {
136 throw new Error(
137 `Requested Erlang/OTP version (${otpSpec0}) ` +
138 "should not contain 'OTP-, or maint-'",
139 )
140 }
141 if (otpSpec) {
142 otpVersion = getVersionFromSpec(
143 otpSpec[2],
144 Array.from(otpVersions.keys()).sort(),
145 )
133 + let otpSpec = otpSpec0 // might be a branch (?)
134 + const otpVersion = getVersionFromSpec(
135 + otpSpec,
136 + Array.from(otpVersions.keys()).sort(),
137 + )
138 + if (isVersion(otpSpec0)) {
139 + otpSpec = `OTP-${otpSpec0}` // ... it's a version!
146 140 }
147 141 if (otpVersion === null) {
148 142 throw new Error(
@@ -154,60 +148,46 @@ async function getOTPVersion(otpSpec0, osVersion) {
154 148 return otpVersions.get(otpVersion) // from the reference, for download
155 149 }
156 150
157 async function getElixirVersion(exSpec0, otpVersion) {
151 +async function getElixirVersion(exSpec0, otpVersion0) {
152 + const otpVersion = otpVersion0.match(/^([^-]+-)?(.+)$/)[2]
153 + const otpVersionMajor = otpVersion.match(/^([^.]+).*$/)[1]
158 154 const elixirVersions = await getElixirVersions()
159 155 const semverVersions = Array.from(elixirVersions.keys()).sort()
160
161 const exSpec = exSpec0.match(/^v?(.+)(-otp-.+)/) || exSpec0.match(/^v?(.+)/)
162 let elixirVersion
163 if (exSpec[2] && !isStrictVersion()) {
164 throw new Error(
165 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) ` +
166 "should not contain '-otp-...'",
167 )
156 + const exSpec = exSpec0.replace(/-otp-.*$/, '')
157 + const elixirVersionFromSpec = getVersionFromSpec(exSpec, semverVersions, true)
158 + let elixirVersionForDownload = elixirVersionFromSpec
159 + if (isVersion(otpVersionMajor)) {
160 + elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
168 161 }
169 if (exSpec) {
170 elixirVersion = getVersionFromSpec(exSpec[1], semverVersions)
171 }
172 if (!exSpec || elixirVersion === null) {
162 + if (elixirVersionFromSpec === null) {
173 163 throw new Error(
174 164 `Requested Elixir version (${exSpec0}) not found in version list ` +
175 165 "(should you be using option 'version-type': 'strict'?)",
176 166 )
177 167 }
178 const otpMatch = otpVersion.match(/^(?:OTP-)?([^.]+)/)
179 let elixirVersionWithOTP
180
181 if (elixirVersions.get(elixirVersion)) {
182 const otpVersionMajor = otpMatch[1]
183 // We try for a version like `v1.4.5-otp-20`...
184 if (elixirVersions.get(elixirVersion).includes(otpMatch[1])) {
185 // ... and it's available: use it!
186 elixirVersionWithOTP = `${elixirVersion}-otp-${otpVersionMajor}`
187 core.info(
188 `Using Elixir ${elixirVersion} (built for OTP ${otpVersionMajor})`,
189 )
190 } else {
191 // ... and it's not available: exit with exception
192 throw new Error(
193 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
194 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?)',
195 )
196 }
168 +
169 + const elixirVersionComp = elixirVersions.get(elixirVersionFromSpec)
170 + if (
171 + (elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
172 + !isVersion(otpVersionMajor)
173 + ) {
174 + core.info(
175 + `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
176 + )
197 177 } else {
198 178 throw new Error(
199 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion}) not ` +
200 "found in version list (should you be using option 'version-type': 'strict'?)",
179 + `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
180 + 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?)',
201 181 )
202 182 }
203 183
204 return maybePrependWithV(elixirVersionWithOTP, elixirVersion)
184 + return maybePrependWithV(elixirVersionForDownload)
205 185 }
206 186
207 187 async function getGleamVersion(gleamSpec0) {
208 const gleamSpec = gleamSpec0.match(/^v?(.+)/)
188 + const gleamSpec = gleamSpec0.match(/^v?(.+)$/)
209 189 const gleamVersions = await getGleamVersions()
210 const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions)
190 + const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions, true)
211 191 if (gleamVersion === null) {
212 192 throw new Error(
213 193 `Requested Gleam version (${gleamSpec0}) not found in version list ` +
@@ -251,7 +231,9 @@ async function getOTPVersions(osVersion) {
251 231 .trim()
252 232 .split('\n')
253 233 .forEach((line) => {
254 const otpMatch = line.match(/^(OTP-|maint-)?([^ ]+)/)
234 + const otpMatch = line
235 + .match(/^([^ ]+)?( .+)/)[1]
236 + .match(/^([^-]+-)?(.+)$/)
255 237 const otpVersion = otpMatch[2]
256 238 otpVersions.set(otpVersion, otpMatch[0]) // we keep the original for later reference
257 239 })
@@ -268,7 +250,6 @@ async function getOTPVersions(osVersion) {
268 250 })
269 251 })
270 252 }
271
272 253 return otpVersions
273 254 }
274 255
@@ -285,7 +266,7 @@ async function getElixirVersions() {
285 266 .forEach((line) => {
286 267 const elixirMatch =
287 268 line.match(/^v?(.+)-otp-([^ ]+)/) || line.match(/^v?([^ ]+)/)
288 const elixirVersion = elixirMatch[1]
269 + const elixirVersion = maybePrependWithV(elixirMatch[1])
289 270 const otpVersion = elixirMatch[2]
290 271 const otpVersions = otpVersionsForElixirMap.get(elixirVersion) || []
291 272 if (otpVersion) {
@@ -332,7 +313,7 @@ function isStrictVersion() {
332 313 return core.getInput('version-type', { required: false }) === 'strict'
333 314 }
334 315
335 function getVersionFromSpec(spec, versions) {
316 +function getVersionFromSpec(spec, versions, maybePrependWithV0) {
336 317 let version = null
337 318
338 319 if (spec.match(/rc/) || isStrictVersion()) {
@@ -357,7 +338,11 @@ function getVersionFromSpec(spec, versions) {
357 338 }
358 339 }
359 340
360 return version === null || version === undefined ? null : version
341 + let v = version === null || version === undefined ? null : version
342 + if (maybePrependWithV0 && v != null) {
343 + v = maybePrependWithV(v)
344 + }
345 + return v
361 346 }
362 347
363 348 function maybeCoerced(v) {
@@ -464,15 +449,17 @@ async function get(url0, pageIdxs) {
464 449 return ret
465 450 }
466 451
467 function maybePrependWithV(versionToPrepend, specVersion) {
468 const digitStart = /^\d+/
469 let v = versionToPrepend
470 if (digitStart.test(specVersion)) {
471 v = `v${versionToPrepend}`
452 +function maybePrependWithV(v) {
453 + if (isVersion(v)) {
454 + return `v${v.replace('v', '')}`
472 455 }
473 456 return v
474 457 }
475 458
459 +function isVersion(v) {
460 + return /^v?\d+/.test(v)
461 +}
462 +
476 463 module.exports = {
477 464 getOTPVersion,
478 465 getElixirVersion,

Parents: 4c52669