Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - box-id/setup-beam: Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...) · GitHub
Skip to content
This repository was archived by the owner on Feb 19, 2026. It is now read-only.

Repository files navigation

setup-beam ActionUbuntuWindows

This action sets up an Erlang/OTP environment for use in a GitHub Actions workflow by:

  • installing Erlang/OTP
  • optionally, installing Elixir
  • optionally, installing Gleam
  • optionally, installing rebar3
  • optionally, installing hex
  • optionally, opting for strict or loose version matching
  • optionally, having problem matchers 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.

Usage

See action.yml for the action's specification.

Input versioning

Input (tools') versions are controlled via with: (check the examples below).

Strict versions

The Erlang/OTP release version specification, for example, is relatively complex, so, for best results, we recommend specifying exact versions, and setting option version-type to strict.

Version ranges

However, values like 22.x, or even >22, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means version-type is loose, which is also the default value for this option.

Specify versions as strings, not numbers

Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like 23.0 don't 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.

"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 and some repositories might propose).

If in doubt do a test run and compare the obtained release with the one you were expecting to be the latest.

Compatibility between Operating System and Erlang/OTP

This list presents the known working version combos between the target operating system and Erlang/OTP.

Operating systemErlang/OTPOTP ArchitectureStatus
ubuntu-18.0417.0 - 25.3x86_64, arm64
ubuntu-20.0421.0 - 27x86_64, arm64
ubuntu-22.0424.2 - 27x86_64, arm64
ubuntu-24.0424.3 - 27x86_64, arm64
windows-201921* - 25x86_64, x86
windows-202221* - 27x86_64, x86

Note *: prior to 23, Windows builds are only available for minor versions, e.g. 21.0, 21.3, 22.0, etc.

Self-hosted runners

Self-hosted runners need to set env. variable ImageOS to one of the following, since the action uses that to download assets:

ImageOSOperating system
ubuntu18ubuntu-18.04
ubuntu20ubuntu-20.04
ubuntu22ubuntu-22.04
ubuntu24ubuntu-24.04
win19windows-2019
win22windows-2022

as per the following example:

...
jobs:
test:
runs-on: self-hostedenv:
ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1...

Outputs

The action provides the following outputs:

OutputContent
otp-versionThe Erlang version, e.g. OTP-26.0
elixir-versionThe Elixir version, e.g. v1.14-otp-26
gleam-versionThe Gleam version, e.g. v1.5.1
rebar3-versionThe rebar3 version, e.g. 3.18.0
setup-beam-versionThe commit unique id of the executed action version, e.g. a34c98f

accessible as ${{steps.<setup-beam-step-id>.outputs.<Output>}}, e.g. ${{steps.setup-beam.outputs.erlang-version}}

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:

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-versionerlang
elixir-versionelixir
gleam-versiongleam
rebar3-versionrebar

Alternative hex.pm mirrors

It is possible to use alternative hex.pm mirror(s), in their declared order, with option hexpm-mirrors. By default, the action will use builds.hex.pm. To use other alternative mirrors, add one per line, as shown below.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'# Use `cdn.jsdelivr.net/hex` as an alternative to `builds.hex.pm`hexpm-mirrors: https://cdn.jsdelivr.net/hex

Alternatively, you may try cdn.jsdelivr.net/hex if builds.hex.pm fails:

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '26'hexpm-mirrors: | https://builds.hex.pm https://cdn.jsdelivr.net/hex

OTP Architecture

On Windows you can specify the OTP architecture to install.

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-lateststeps:
- uses: erlef/setup-beam@v1with:
otp-version: '26'otp-architecture: '32'

Environment variables

Base installation folders (useful for e.g. fetching headers for NIFs) are available in the following environment variables:

  • INSTALL_DIR_FOR_OTP: base folder for Erlang/OTP
  • INSTALL_DIR_FOR_ELIXIR: base folder for Elixir
  • INSTALL_DIR_FOR_GLEAM: base folder for Gleam
  • INSTALL_DIR_FOR_REBAR3: base folder for rebar3

In each of these you'll find folder bin where the appropriate binaries, platform-dependant, are found (i.e. erl, erl.exe, rebar3, rebar3.exe, ...).

Elixir Problem Matchers

The Elixir Problem Matchers in this repository are adapted from here. See MATCHER_NOTICE for license details.

Examples

Erlang/OTP + Elixir, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']elixir: ['1.8.2', '1.9.4']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}elixir-version: ${{matrix.elixir}}
- run: mix deps.get
- run: mix test

Erlang/OTP + rebar3, on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-20.04name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}strategy:
matrix:
otp: ['21.1', '22.2', '23.3']rebar3: ['3.14.1', '3.14.3']steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: ${{matrix.otp}}rebar3-version: ${{matrix.rebar3}}
- run: rebar3 ct

Erlang/OTP + rebar3, on Windows

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: windows-2022steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '24'rebar3-version: '3.16.1'
- run: rebar3 ct

Gleam on Ubuntu

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: '27'gleam-version: '1.5.1'
- run: gleam test

Gleam on Ubuntu without OTP

# create this in .github/workflows/ci.ymlon: pushjobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1with:
otp-version: falsegleam-version: '1.5.1'
- run: gleam check

Note: the otp-version: false input is only applicable when installing Gleam.

The project

Versioning

setup-beam has three version paths, described below, for example version 1.8.0:

  • @v1: the latest in the 1.y.z series (this tag is movable),
  • @v1.8: the latest in the 1.8.z series (this tag is movable),
  • @v1.8.0: release 1.8.0 (this tag is not movable).

We make a real effort to not introduce incompatibilities without changing the major version number. To be extra safe against changes causing issues in your CI you should specify an exact version with @vx.y.z.

License

The scripts and documentation in this project are released under the MIT license.

Contributing

Check out this doc.

Code of Conduct

This project's code of conduct is made explicit in CODE_OF_CONDUCT.md.

Security

This project's security policy is made explicit in SECURITY.md.

About

Set up your BEAM-based GitHub Actions workflow (Erlang, Elixir, Gleam, ...)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages