Skip to content

Commit

Permalink
Ease consumption by means of .tool-versions (#159)
Browse files Browse the repository at this point in the history
* Ease consumption by means of .tool-versions

* Update as per self-review

* Update as per self-review

* Act on CI results

* Act on CI results

* Act on CI results

This value is check by code, in any case

* Act on CI results

* Act on CI results

* Act on CI results

It appears we can't install Elixir twice on Windows, but can
on Ubuntu; this is outside the scope of this branch's context
so I won't fix it now

* Tweak visual consumption elements

* Ease potential future maintenance and/or update
  • Loading branch information
paulo-ferraz-oliveira authored Nov 22, 2022
1 parent 529221d commit c373088
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 31 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ jobs:
node-version: '14'
- run: npm ci
- run: npm test
- name: .tool-versions test
id: setup-beam
uses: ./
with:
version-file: __tests__/.tool-versions
version-type: strict

unit_tests_windows:
name: Unit tests (Windows)
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/**
dist/.github/workflows
__tests__/.tool-versions
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ workflow by:
- optionally, installing [Gleam](https://gleam.run/)
- optionally, installing [`rebar3`](https://www.rebar3.org/)
- optionally, installing [`hex`](https://hex.pm/)
- optionally, opting for strict or loose version matching
- optionally, having
[problem matchers](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md) show
warnings and errors on pull requests
- optionally, using a version file (as explained in "Version file", below), to identify versions

**Note**: currently, this action only supports Actions' `ubuntu-` and `windows-` runtimes.

Expand Down Expand Up @@ -86,6 +88,31 @@ jobs:
...
```
### Version file
A version file is specified via input `version-file` (e.g.`.tool-versions`). This
allows not having to use YML input for versions, though the action does check (and
will exit with error) if both inputs are set.

**Note**: if you're using a version file, option `version-type` is checked to be `strict`,
and will make the action exit with error otherwise.

The following version file formats are supported:

- `.tool-versions`, as specified by [asdf: Configuration](https://asdf-vm.com/manage/configuration.html)

Supported version elements are the same as the ones defined for the YML portion of the action,
with the following correspondence.

#### `.tool-versions` format

| YML | `.tool-versions` |
|- |-
| `otp-version` | `erlang`
| `elixir-version` | `elixir`
| `gleam-version` | `gleam`
| `rebar3-version` | `rebar`

### Example (Erlang/OTP + Elixir, on Ubuntu)

```yaml
Expand Down
36 changes: 35 additions & 1 deletion __tests__/setup-beam.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ simulateInput('install-rebar', 'true')
simulateInput('install-hex', 'true')

const assert = require('assert')
const fs = require('fs')
const setupBeam = require('../src/setup-beam')
const installer = require('../src/installer')

Expand All @@ -20,6 +21,8 @@ async function all() {
await testRebar3Versions()

await testGetVersionFromSpec()

await testParseVersionFile()
}

async function testFailInstallOTP() {
Expand Down Expand Up @@ -405,8 +408,39 @@ async function testGetVersionFromSpec() {
simulateInput('version-type', 'loose')
}

async function testParseVersionFile() {
const otpVersion = unsimulateInput('otp-version')
const elixirVersion = unsimulateInput('elixir-version')

const erlang = '25.1.1'
const elixir = '1.14.1'
const toolVersions = `# a comment
erlang ${erlang}# comment, no space
elixir ${elixir} # comment, with space
gleam 0.23 # not picked up`
const filename = '__tests__/.tool-versions'
fs.writeFileSync(filename, toolVersions)
process.env.GITHUB_WORKSPACE = ''
const appVersions = setupBeam.parseVersionFile(filename)
assert.strictEqual(appVersions.get('erlang'), erlang)
assert.strictEqual(appVersions.get('elixir'), elixir)

simulateInput('otp-version', otpVersion)
simulateInput('elixir-version', elixirVersion)
}

function unsimulateInput(key) {
const before = process.env[input(key)]
simulateInput(key, '')
return before
}

function simulateInput(key, value) {
process.env[`INPUT_${key.replace(/ /g, '_').toUpperCase()}`] = value
process.env[input(key)] = value
}

function input(key) {
return `INPUT_${key.replace(/ /g, '_').toUpperCase()}`
}

all()
Expand Down
7 changes: 5 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ inputs:
otp-version:
description: Version range or exact version of Erlang/OTP to use,
or false when installing only Gleam without OTP
required: true
elixir-version:
description: Version range or exact version of Elixir to use
gleam-version:
Expand All @@ -31,8 +30,12 @@ inputs:
to guess versions based on semver rules
default: loose
disable_problem_matchers:
description: whether to have the problem matchers present in the results (or not)
description: whether to have the problem matchers present in the results
(or not)
default: false
version-file:
description: a versions file (e.g. as used by `asdf`), which defines inputs
default: ''
outputs:
elixir-version:
description: Exact version of Elixir that was installed
Expand Down
90 changes: 76 additions & 14 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7196,6 +7196,7 @@ const { exec } = __nccwpck_require__(1514)
const path = __nccwpck_require__(1017)
const semver = __nccwpck_require__(1383)
const https = __nccwpck_require__(5687)
const fs = __nccwpck_require__(7147)
const installer = __nccwpck_require__(2127)

main().catch((err) => {
Expand All @@ -7205,24 +7206,31 @@ main().catch((err) => {
async function main() {
installer.checkPlatform()

const versionFilePath = getInput('version-file', false)
let versions
if (versionFilePath) {
if (!isStrictVersion()) {
throw new Error(
"you have to set version-type=strict if you're using version-file",
)
}
versions = parseVersionFile(versionFilePath)
}

const osVersion = getRunnerOSVersion()
const otpSpec = core.getInput('otp-version', { required: true })
const elixirSpec = core.getInput('elixir-version', { required: false })
const gleamSpec = core.getInput('gleam-version', { required: false })
const rebar3Spec = core.getInput('rebar3-version', { required: false })
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)

if (elixirInstalled === true) {
const shouldMixRebar = core.getInput('install-rebar', {
required: false,
})
const shouldMixRebar = getInput('install-rebar', false)
await mix(shouldMixRebar, 'rebar')
const shouldMixHex = core.getInput('install-hex', {
required: false,
})
const shouldMixHex = getInput('install-hex', false)
await mix(shouldMixHex, 'hex')
}
} else if (!gleamSpec) {
Expand Down Expand Up @@ -7254,9 +7262,7 @@ async function maybeInstallElixir(elixirSpec, otpVersion) {
console.log(`##[group]Installing Elixir ${elixirVersion}`)
await installer.installElixir(elixirVersion)
core.setOutput('elixir-version', elixirVersion)
const disableProblemMatchers = core.getInput('disable_problem_matchers', {
required: false,
})
const disableProblemMatchers = getInput('disable_problem_matchers', false)
if (disableProblemMatchers === 'false') {
const matchersPath = __nccwpck_require__.ab + ".github"
console.log(
Expand Down Expand Up @@ -7503,7 +7509,7 @@ async function getRebar3Versions() {
}

function isStrictVersion() {
return core.getInput('version-type', { required: false }) === 'strict'
return getInput('version-type', false) === 'strict'
}

function getVersionFromSpec(spec, versions, maybePrependWithV0) {
Expand Down Expand Up @@ -7653,12 +7659,68 @@ function isVersion(v) {
return /^v?\d+/.test(v)
}

function getInput(inputName, required, alternativeName, alternatives) {
const alternativeValue = (alternatives || new Map()).get(alternativeName)
let input = core.getInput(inputName, {
required: alternativeValue ? false : required,
})
// We can't have both input and alternativeValue set
if (input && alternativeValue) {
throw new Error(
`Found input ${inputName}=${input} (from the YML) \
alongside ${alternativeName}=${alternativeValue} \
(from the version file). You must choose one or the other.`,
)
} else if (!input) {
input = alternativeValue
}
return input
}

function parseVersionFile(versionFilePath0) {
const versionFilePath = path.join(
process.env.GITHUB_WORKSPACE,
versionFilePath0,
)
if (!fs.existsSync(versionFilePath)) {
throw new Error(
`The specified version file, ${versionFilePath0}, does not exist`,
)
}
console.log(`##[group]Parsing version file at ${versionFilePath0}`)
const appVersions = new Map()
const versions = fs.readFileSync(versionFilePath, 'utf8')
// For the time being we parse .tool-versions
// If we ever start parsing something else, this should
// become default in a new option named e.g. version-file-type
versions.split('\n').forEach((line) => {
const appVersion = line.match(/^([^ ]+)[ ]+([^ #]+)/)
if (appVersion) {
const app = appVersion[1]
if (['erlang', 'elixir', 'gleam', 'rebar'].includes(app)) {
const [, , version] = appVersion
console.log(`Consuming ${app} at version ${version}`)
appVersions.set(app, version)
}
}
})
if (!appVersions.size) {
console.log('There was apparently nothing to consume')
} else {
console.log('... done!')
}
console.log('##[endgroup]')

return appVersions
}

module.exports = {
getOTPVersion,
getElixirVersion,
getGleamVersion,
getRebar3Version,
getVersionFromSpec,
parseVersionFile,
}


Expand Down
Loading

0 comments on commit c373088

Please sign in to comment.