In this article I'll show you how to setup and configure GitHub Actions to work with an OCaml Library.
Rob Anderson @jamsidedown (Site) decided he's going to be doing ⭐️ AoC this year in OCaml! They wrote a new library ocaml-cll an OCaml circular linked list library, in preperation for this as it's been needed in other languages for previous questions.
To help out we looked at how to build the package using GitHub Actions.
See the example here: ocaml-example main.yml
Or the production one: ocaml-cll main.yml
Firstly as with most builds you setup your env with the language you need:
Another useful action is actions-ocaml.
- name: 🐪 Set-up OCaml
  uses: ocaml/setup-ocaml@v2
  with:
    ocaml-compiler: "5.0"
    dune-cache: true
Once configured you need to install any dependencies from your .opam/dune-project file.
- name: ⬇️ Install opam deps
  run: opam install . --deps-only --with-test
It's worth installing any global packages you need like odoc etc.
- name: ⬇️ Install opam global deps
  run: opam install odoc ocamlformat dune-release
Next build your project:
- name: 🔨 Build
  run: opam exec -- dune build
And test:
- name: 🧪 Test
  run: opam exec -- dune runtest
Or with coverage:
- name: 🧪 Test and Coverage
  run: "opam exec -- dune runtest --instrument-with bisect_ppx --force"
- name: 📄 Coverage Report"
  run: "opam exec -- bisect-ppx-report summary"
You can then build the docs:
- name: 📄 Build Docs
  run: opam exec -- dune build @doc
Then decide if you want to upload that as an artifact and deploy it to either GitHub Pages or another service.
Once you have a package you can add it to the opam-repository, example PRs here:
- https://github.com/ocaml/opam-repository/pull/24626
- https://github.com/ocaml/opam-repository/pull/24719
- https://github.com/ocaml/opam-repository/pull/24777
Complete:
jobs:
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/helloworld
    steps:
      - name: 🛎️ Checkout
        uses: actions/checkout@v4
      - name: 🐪 Set-up OCaml
        uses: ocaml/setup-ocaml@v2
        with:
          ocaml-compiler: "5.0"
          dune-cache: true
      - name: ⬇️ Install opam deps
        run: opam install . --deps-only --with-test
      - name: ⬇️ Install opam global deps
        run: opam install odoc ocamlformat dune-release
      - name: 🔨 Build
        run: opam exec -- dune build
      - name: 🧪 Test
        run: opam exec -- dune runtest
      - name: 📄 Build Docs
        run: opam exec -- dune build @doc
      
      - name: Upload API Docs artifact
        uses: actions/upload-artifact@v3.1.3
        with:
          name: docs
          path: ./src/helloworld/_build/default/_doc/_html
      - name: Deploy API Docs
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          user_name: 'github-actions[bot]'
          user_email: 'github-actions[bot]@users.noreply.github.com'
          publish_dir: ./src/helloworld/_build/default/_doc/_html
          destination_dir: docs
          enable_jekyll: true
ocaml-cll
- Documentation https://robanderson.dev/ocaml-cll/cll/
- Package https://opam.ocaml.org/packages/cll/