STATUS: STABLE
Set up an OCaml and opam environment in GitHub Actions and add to PATH.
Consult the Hello World OCaml Action that uses Dune and opam to build a simple library.
It's possible to feed different values to the input depending on the platform of the runner. The syntax of GitHub's workflows is flexible enough to offer several methods to do this.
name: Builds, tests & co
on:
- push
- pull_request
permissions: read-all
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
fail-fast: false
steps:
- name: Checkout tree
uses: actions/checkout@v6
- name: Set-up OCaml
uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: 5
- run: opam install . --deps-only --with-test
- run: opam exec -- dune build
- run: opam exec -- dune runtest
lint-doc:
runs-on: ubuntu-latest
steps:
- name: Checkout tree
uses: actions/checkout@v6
- name: Set-up OCaml
uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: 5
- uses: ocaml/setup-ocaml/lint-doc@v3
lint-fmt:
runs-on: ubuntu-latest
steps:
- name: Checkout tree
uses: actions/checkout@v6
- name: Set-up OCaml
uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: 5
- uses: ocaml/setup-ocaml/lint-fmt@v3
lint-opam:
runs-on: ubuntu-latest
steps:
- name: Checkout tree
uses: actions/checkout@v6
- name: Set-up OCaml
uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: 5
- uses: ocaml/setup-ocaml/lint-opam@v3When using GitHub-hosted runners, specifying compiler version 4 or 5 should work across all platforms and architectures. However, there are exceptions, as shown below. If you need to test with specific versions, please choose the appropriate version for your runtime environment.
| Version | Ubuntu | macOS | Windows (MinGW-w64) | Windows (MSVC) |
|---|---|---|---|---|
| >= 5.3 | ✅ | ✅ | ✅ | ✅ |
| >= 5.0 & <= 5.2 | ✅ | ✅ | ✅ | ❌ |
| >= 4.13 & <= 4.14 | ✅ | ✅ | ✅ | ✅ |
| >= 4.02 & <= 4.12 | ✅ | ✅ | ❌ | ❌ |
| <= 4.01 | ✅ | ✅ | ❌ | ❌ |
| Version | Ubuntu | macOS | Windows |
|---|---|---|---|
| >= 4.12 | ✅ | ✅ | ❌ |
| = 4.11 | ✅ | ❌ | ❌ |
| = 4.10 | ✅ | ✅ | ❌ |
| >= 4.02 & <= 4.09 | ✅ | ❌ | ❌ |
| <= 4.01 | ❌ | ❌ | ❌ |
The actions are downloaded and run from the GitHub graph of repositories. The workflow references an action using a ref.
Note
Binding to a major version is the latest of that major version (e.g. v3 = 3.*) Major versions should guarantee compatibility. A major version can add net new capabilities but should not break existing input compatibility or break existing workflows.
- name: Set-up OCaml ${{ matrix.ocaml-compiler }}
uses: ocaml/setup-ocaml@v3
# ^^^
with:
ocaml-compiler: ${{ matrix.ocaml-compiler }}Warning
Do not reference master since that is the latest code and can be carrying breaking changes of the next major version.
Major version binding allows you to take advantage of bug fixes, critical functionality and security fixes. The master branch has the latest code and is unstable to bind to since changes get committed to the master and released by creating a tag.
steps:
# Reference the major version of a release (most recommended)
- uses: ocaml/setup-ocaml@v3
# Reference a specific commit (most strict)
- uses: ocaml/setup-ocaml@<SHA>
# Reference a semver version of a release (not recommended)
- uses: ocaml/setup-ocaml@v3.0.0
# Reference a branch (most dangerous - do not do this)
- uses: ocaml/setup-ocaml@master| Name | Required | Description | Type | Default |
|---|---|---|---|---|
ocaml-compiler |
Yes | The OCaml compiler packages to initialise. Consult the supported version syntax section. | string | |
opam-repositories |
No | A YAML mapping of opam repository name/URL pairs to use. Repositories listed first take priority over later ones. | string | default: git+https://github.com/ocaml/opam-repository.git |
opam-pin |
No | Automatically pin local opam packages (matched by opam-local-packages) in the opam switch. Set to false to skip pinning. |
bool | true |
opam-local-packages |
No | A glob pattern matching the local .opam files to be pinned when opam-pin is enabled. Consult the @actions/glob documentation for supported patterns. |
string | *.opam |
opam-disable-sandboxing |
No | Disable the opam sandboxing feature. opam uses Bubblewrap on Linux and sandbox-exec on macOS. Useful for self-hosted runners where the sandbox tool is not available. On Windows, sandboxing is always disabled. | bool | false |
cache |
No | Cache the opam root and local switch using GitHub Actions cache. Set to false to disable all GitHub Actions cache operations. This does not affect the hosted tool cache. |
bool | true |
windows-compiler |
No | The C compiler toolchain used for building on Windows. Use mingw (default) for mingw-w64 (GCC), or msvc for the Microsoft Visual C compiler. MSVC requires Visual Studio (pre-installed on GitHub-hosted runners). |
string | mingw |
windows-environment |
No | The Unix environment used for building on Windows. Use cygwin (default) for opam's internal Cygwin, or msys2 to use the pre-installed MSYS2 on GitHub-hosted runners. |
string | cygwin |
allow-prerelease-opam |
No | Allow the use of a pre-release version of opam. Has no effect when no pre-release version is available. | bool | false |
The ocaml-compiler input supports the Semantic Versioning Specification, for more detailed examples please refer to the documentation.
When a version range is used (e.g., 5, 5.5.x), the highest matching version from the opam-repository is always selected.
Warning
Version numbers containing a dot must be quoted in YAML to avoid being parsed as floats. For example, an unquoted 5.10 is parsed as the float 5.1, which would silently resolve to the latest 5.1.x compiler instead of 5.10.x. To be safe, always quote version values:
ocaml-compiler: "5.5"Note
With the naughty exception of 4.02.2, point releases are meant to be strictly compatible, so once we (OCaml dev team) release a new point release, upgrading should be a no-brainer.
Examples:
- Exact package name:
ocaml-base-compiler.5.5.0 - Combine multiple packages:
ocaml-variants.5.5.0+options,ocaml-option-flambda,ocaml-option-musl,ocaml-option-static - Major versions:
"4","5" - Minor versions:
"4.08","4.14","5.5","5.5.x" - More specific versions:
"~4.02.2","5.5.0"
This action automatically caches the opam root and the local switch (_opam) using the GitHub Actions cache. When the cache is hit, the compiler installation is skipped and only opam update is run to ensure the repository metadata stays current. This significantly reduces setup time whilst keeping dependency resolution up to date.
Set cache: false to disable all GitHub Actions cache operations performed by this action. The hosted tool cache used for the opam executable remains enabled. This can be useful when restoring _opam before this action with a custom cache key. If a local switch already exists, the action reuses it instead of creating a new one.
Warning
Caching a switch after installing project dependencies can consume substantial cache space and may reuse stale or broken packages. If you manage this cache yourself, use an exact compiler version, include the platform, compiler and lock file in the cache key, then run opam install . --deps-only --locked after setup. Custom opam caches are used at your own risk; see #1098 for the trade-offs and examples.
The cache key is computed from the following components:
- Platform (Linux, macOS, or Windows)
- OS version
- Architecture (
x86_64,arm64, etc.) - opam version
- OCaml compiler version
- opam repository URLs
- Sandbox setting (enabled or disabled)
On Windows, the following additional components are included:
- Windows environment (
cygwinormsys2) - Windows compiler (
mingwormsvc) - MSVC version (when using the MSVC compiler)
This action intentionally does not cache the results of opam install . --deps-only. Unlike package managers such as npm or Cargo, opam does not use a lock file by default — dependency versions are resolved against the current state of opam-repository at install time.
If these resolved dependencies were cached, opam-repository updates (bug fixes, security patches, new package versions) would not be picked up for as long as the cache remains valid. On active repositories where CI runs frequently, the cache would be hit continuously and never expire, effectively freezing dependencies indefinitely. This would make CI unreliable, as it could pass with stale dependencies whilst failing on a fresh install.
If the cache becomes corrupted or stale, you can delete it using the GitHub CLI:
gh cache delete --allConsult the examples page for more complex patterns.
STATUS: STABLE
Note
All extensions are recommended to be used in separate jobs run on ubuntu-latest.
Consult the Configuring Dependabot version updates page and set .github/dependabot.yml as described below to allow Dependabot to update the actions automatically.
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
ocaml:
patterns:
- "ocaml/*"The ocaml group combines updates to GitHub Actions maintained by the OCaml organization into a single pull request.
Note
Renovate is also available for free as a third-party tool, which is much more flexible than Dependabot - depending on the project and your preferences. If you just want to automate GitHub Actions updates, Dependabot is good enough.
This action aims to provide an OS-neutral interface to opam, and so will not add features that only work on one operating system. It will also track the latest stable release of opam.
Please feel free to post to the discuss.ocaml.org forum with any questions you have about this action.
Previous discussions include: