Skip to content
Latchkey

CI/CD for an OCaml Project with GitHub Actions

Build, test, and format-check your dune-based OCaml project.

OCaml projects use OPAM for packages and dune as the build system. The setup-ocaml action handles the OPAM switch and caching. This recipe builds, tests, and checks formatting.

What the pipeline does

  • set up OCaml and OPAM with caching
  • install deps with opam install
  • build with dune build
  • run tests with dune test
  • check formatting with dune fmt

The workflow

ocaml/setup-ocaml provisions the compiler and caches the OPAM switch. dune runtest executes the test stanzas.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ocaml/setup-ocaml@v3
        with:
          ocaml-compiler: '5.2'
      - run: opam install . --deps-only --with-test
      - run: opam exec -- dune build
      - run: opam exec -- dune runtest
      - run: opam exec -- dune build @fmt

Caching and speed

setup-ocaml caches the OPAM switch and downloaded packages, which is the biggest speedup since building an OPAM switch from scratch is slow. The native compile is CPU-bound; cheaper managed runners such as Latchkey keep builds fast and auto-retry transient OPAM repository fetches.

Deploying

dune build produces a native executable under _build/default. Ship it in a slim container or attach it to a GitHub Release. For library packages, publish to the opam repository by opening a release PR with dune-release.

Key takeaways

  • setup-ocaml caches the OPAM switch for big speedups.
  • dune build, runtest, and @fmt cover build, test, and format.
  • Use dune-release to publish library packages to opam.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →