OCaml Changelog


Read the latest releases and updates from the OCaml ecosystem.

After two alpha releases, the release of OCaml 5.1.0 is drawing near. We have thus released a first beta version of OCaml 5.1.0 to help you update your softwares and libraries ahead of the release (see below for the installation instructions). Compared to the last alpha release, this beta contains two subtle internal runtime fixes and one Windows fix. Overall, the opam ecosystem looks in a good shape for the first beta release.

If you find any bugs, please report them on OCaml's issue tracker.

Nearly all core development tools support OCaml 5.1.0, and you can follow the last remaining wrinkles on the opam readiness for 5.1.0 meta-issue.

Currently, the release is planned for the end of July or the beginning of August.

If you are interested in full list of features and bug fixes of the new OCaml version, the updated change log for OCaml 5.1.0 is available on GitHub.

Installation Instructions

The base compiler can be installed as an opam switch with the following commands on opam 2.1:

opam update
opam switch create 5.1.0~beta1

The source code for the alpha is also available at these addresses:

Fine-Tuned Compiler Configuration

If you want to tweak the configuration of the compiler, you can switch to the option variant with:

opam update
opam switch create <switch_name> ocaml-variants.5.1.0~beta1+options <option_list>

where option_list is a space-separated list of ocaml-option-* packages. For instance, for a flambda and no-flat-float-array switch:

opam switch create 5.1.0~beta1+flambda+nffa ocaml-variants.5.1.0~beta1+options ocaml-option-flambda ocaml-option-no-flat-float-array

All available options can be listed with opam search ocaml-option.

See full changelog

Runtime System Bugfix

  • #12037: Fix some data races by using volatile when necessary (Fabrice Buoro and Olivier Nicole, review by Guillaume Munch-Maccagnoni, Gabriel Scherer and Luc Maranget)

  • #12253, #12342: Fix infinite loop in signal handling. (Guillaume Munch-Maccagnoni, report by Thomas Leonard, review by KC Sivaramakrishnan and Sadiq Jaffer)

Windows Bugfix

  • #12184, #12320: Sys.rename Windows fixes on directory corner cases. (Jan Midtgaard, review by Anil Madhavapeddy)

Dune 3.9.0

The Dune team is thrilled to announce the release of Dune 3.9.0. This version ships with a host of new features and improvements, including:

  • New dune show Command: This command enables you to display various pieces of information. For instance, you can use dune show pp to display the preprocessed output of a file or dune show aliases [DIR] to list the aliases available in DIR. Read more about the command on its manpage using dune show --help.
  • Improved Dialect Support: We have rolled out several fixes related to dialect support. These changes make it easier to work with Dream's .eml files.
  • Introduction of (build_if) Toggle in (test) Stanza: This new field facilitates the packaging of non-portable tests and benchmarks. If you have tests that don't build on a specific platform, you can now tell Dune not to build them on other Platforms with the build_if field.

Enjoy the new features and improvements incorporated into this version!

See full changelog


  • Include the time it takes to read/write state files when --trace-file is enabled (#7960, @rgrinberg)

  • Include source tree scans in the traces produced by --trace-file (#7937, @rgrinberg)

  • Add --all option to dune rpc status to show all Dune RPC servers running. (#8011, fix #7902, @Alizter)

  • Add additional metadata to the traces provided by --trace-file whenever --trace-extended is passed (#7778, @rleshchinskiy)

  • $ dune describe is now a command group, so arguments to subcommands must be passed after subcommand itself. (#7919, @Alizter)

  • Add dune show command group which is an alias of dune describe. (#7946, @Alizter)

  • Add dune show env command and make dune printenv an alias of it. (#7985, @Alizter)

  • Add commands dune show targets and dune show aliases that display all the available targets and aliases in a given directory respectively. (#7770, grants #265, @Alizter)

  • Extensions used in (dialect) can contain periods (e.g., cppo.ml). (#7782, fixes #7777, @nojb)

  • The interface and implementation fields of a (dialect) are now optional (#7757, @gpetiot)

  • Add (build_if) to the (test) stanza. When it evaluates to false, the executable is not built. (#7899, fixes #6938, @emillon)

  • Allow (include_subdirs qualified) to be used when libraries define a (modules ...) field (#7797, fixes #7597, @anmonteiro)

  • Allow multiple globs in library's (stdlib (internal_modules ..)) (@anmonteiro, #7878)


  • Do not rerun OCaml syntax files on every iteration of the watch mode. This is too memory consuming. (#7894, fix #6900, @rgrinberg)

  • Attach melange rules to the default alias (#7926, @haochenx)

  • Compute digests and manage sandboxes in background threads (#7947, @rgrinberg)


  • Validate file extension for $ dune ocaml top-module. (#8005, fixes #8004, @3Rafal)

  • Cinaps: The promotion rules for cinaps would only offer one file at a time no matter how many promotions were available. Now we offer all the promotions at once (#7901, @rgrinberg)

  • Add necessary parentheses in generated opam constraints (#7682, fixes #3431, @Lucccyo)


  • Remove some compatibility code for old version of dune that generated .merlin files. Now dune will never remove .merlin files automatically (#7562)

  • In opam constraints, reject (and) and (or) with no arguments at parse time (#7730, @emillon)

The OCaml infrastructure team is going to move to Debian 12 as the main distribution from Debian 11. We will continue to provide Debian 11 and 10 images while they are supported, dropping Debian 10 when it reaches end of life in 2024-06-30. In addition to these changes we are deprecating Ubuntu 18.04, Alpine 3.16/17, OL7, OpenSuse 15.2 distributions as the have reached end of life. We strongly recommend updating to a newer version if you are still using them.

Please get in touch on https://github.com/ocaml/infrastructure/issues if you have questions or requests for additional support.

See full changelog
  • OCaml Debian images upgraded to Debian 12 (ocaml-dockerfile#172, @MisterDA)
  • Deprecation of Ubuntu 18.04, Alpine 3.16 and 3.17, OracleLinux 7, OpenSUSE 15.2 images (ocaml-dockerfile#176, @avsm)
  • Deprecate Ubuntu 18.04, Alpine 3.16/17, OL7, OpenSuse 15.2 for OCaml-CI (ocaml-ci#832, @tmcgilchrist)
  • Deprecate Ubuntu 18.04, Alpine 3.16/17, OL7, OpenSuse 15.2 for opam-repo-ci (opam-repo-ci#226, @tmcgilchrist)
  • Deprecate Ubuntu 18.04, Alpine 3.16/17, OL7, OpenSuse 15.2 for docker-base-images (docker-base-images#237, @tmcgilchrist)

Dune 3.8.3

This point release fixes two important issues on Windows and Linux.

See full changelog
  • Fix deadlock on Windows (dune#8044, @nojb)
  • When using sendfile to copy files on Linux, fall back to the portable version if it fails at runtime for some reason (NFS, etc). (dune#8049, fixes dune#8041, @emillon)

We're excited to announce the release of Dune-release 2.0.0!

This release brings support for putting your .opam files in a opam/ directory. If your project contains dozens of packages, you'll be able to generate them into the opam/ folder starting with Dune 3.8 using (opam_file_location inside_opam_directory) in your dune-project.

Another notable change is the removal of delegates. Users of dune-release who want to publish their packages to another platform than GitHub can now use the dune-release delegate-info and use the output to build their own publication workflows.

See full changelog


  • Adopt the OCaml Code of Conduct (#473, @rikusilvola)
  • Added support for projects that have their OPAM files in the opam/ subdirectory. (#466, @Leonidas-from-XIV)


  • Running dune-release check now attempts to discover and parse the change log, and a new flag --skip-change-log disables this behaviour. (#458, @gridbugs)
  • List the main package and amount of subpackages when creating the PR to avoid very long package lists in PRs (#465, @emillon)


  • Avoid collision between branch and tag name. Tag detection got confused when branch was named the same as tag. Now it searches only for tag refs, instead of all refs. (#452, @3Rafal)
  • Fix project name detection from dune-project. The parser could get confused when opam file generation is used. Now it only considers the first (name X) in the file. (#445, @emillon)


  • Remove support for delegates. Previous users of this feature should now use dune-release delegate-info and wrap dune-release calls in a script. See #188 for details. (#428, @NathanReb)
  • Removed support for the OPAM 1.2.2 client. This means dune-release expects the opam binary to be version 2.0 at least. (#406, #411, @Leonidas-from-XIV)

We've released OCaml LSP 1.16.2 with a fix that was introduced in 1.16.1 that prevented users from using preprocessor such as CPPO.

See full changelog


  • Fix file permissions used when specifying output files of pp and ppx. (ocaml-lsp#1153)

We're thrilled to announce the release of OCaml LSP 1.16.1! 🎉

This release comes with new "Extract local" and "Extract function" code actions to easily refactor your code.

We've also disabled code lenses by default following user feedback. You can follow the discussion on GitHub.

This release is also the first OCaml LSP release to use upstream Merlin. Among other things, this means that it is compatible with all the OCaml versions supported by Merlin: currently OCaml 4.14 and 5.0.0.

We're also releasing numerous bug fixes, including:

  • A fix to the integration with Dune RPC on Windows, which, alongside Dune 3.9.0, makes OCaml LSP report Dune errors to the editors with Dune watch mode enabled.
  • Minor improvements to the Odoc <-> Markdown conversion to return better function documentation on the editor.

And much more! Read the full changelog for a complete list of improvements and bug fixes.

See full changelog


  • Add "Remove type annotation" code action. (#1039)
  • Support settings through didChangeConfiguration notification (#1103)
  • Add "Extract local" and "Extract function" code actions. (#870)
  • Depend directly on merlin-lib 4.9 (#1070)


  • Support building with OCaml 5.0 and 5.1 (#1150)

  • Disable code lens by default. The support can be re-enabled by explicitly setting it in the configuration. (#1134)

  • Fix initilization of ocamlformat-rpc in some edge cases when ocamlformat is initialized concurrently (#1132)

  • Kill unnecessary $ dune ocaml-merlin with SIGTERM rather than SIGKILL (#1124)

  • Refactor comment parsing to use odoc-parser and cmarkit instead of octavius and omd (#1088)

    This allows users who migrated to omd 2.X to install ocaml-lsp-server in the same opam switch.

    We also slightly improved markdown generation support and fixed a couple in the generation of inline heading and module types.

  • Allow opening documents that were already open. This is a workaround for neovim's lsp client (#1067)

  • Disable type annotation for functions (#1054)

  • Respect codeActionLiteralSupport capability (#1046)

  • Fix a document syncing issue when utf-16 is the position encoding (#1004)

  • Disable "Type-annotate" action for code that is already annotated. (#1037, fixes #1036)

  • Fix semantic highlighting of long identifiers when using preprocessors (#1049, fixes #1034)

  • Fix the type of DocumentSelector in cram document registration (#1068)

  • Accept the --clientProcessId command line argument. (#1074)

  • Accept --port as a synonym for --socket. (#1075)

  • Fix connecting to dune rpc on Windows. (#1080)

Ppxlib 0.30.0

We're excited to announce the release of Ppxlib 0.30.0! It comes with support for OCaml 5.1, various enhancements, and bug fixes.

For PPX writing, Ast_pattern now offers additional utility functions, while metaquot benefits from improved error reporting.

PPX usage sees better compatibility with OCaml trunk, thanks to the Driver's improved Parsetree version recognition. This allows for compatibility with both trunk and stable OCaml versions concurrently.

Finally, this release enhances Ppxlib's compatibility with ReScript, introducing "ns" and "res" as reserved namespaces.

See full changelog

Dune 3.8.2

We've released Dune 3.8.2 with a few bug fixes.

See full changelog
  • Switch back to threaded console for all systems; fix unresponsive console on Windows (dune#7906, @nojb)
  • Respect -p / --only-packages for melange.emit artifacts (dune#7849, @anmonteiro)
  • Fix scanning of Coq installed files (@ejgallego, reported by @palmskog, dune#7895 , fixes dune#7893)
  • Fix RPC buffer corruption issues due to multi threading. This issue was only reproducible with large RPC payloads (dune#7418)
  • Fix printing errors from excerpts whenever character offsets span multiple lines (dune#7950, fixes dune#7905, @rgrinberg)

The server toxis where Opam-Repo-CI and OCaml-CI were deployed suffered hardware difficulties yesterday, resulting in BTRFS filesystem corruption and memory issues. These issues are tracked on ocaml/infrastructure#51. Services were restored temporarily using a spare spinning disk, but we continued to see ECC memory issues.

All services have now been redeployed on new ARM64 hardware. We retained the databases for Prometheus, OCaml-CI and Opam-Repo-CI, but unfortunately, older job logs have been lost.

The external URLs for these services are unchanged.

Dune 3.8.1

We've just released a patch version of Dune to fix regressions introduced in Dune 3.8.0.

In particular, we've reverted some cross-compilation improvements that caused build failures when using ppx_runtime_libraries and we'll revisit them in a future version of Dune.

See full changelog
  • Fix a crash when using a version of Coq < 8.13 due to the native compiler config variable being missing. We now explicitly default to (mode vo) for these older versions of Coq. (dune#7847, fixes dune#7846, @Alizter)
  • Duplicate installed Coq theories are now allowed with the first appearing in COQPATH being preferred. This is inline with Coq's loadpath semantics. This fixes an issue with install layouts based on COQPATH such as those found in nixpkgs. (dune#7790, @Alizter)
  • Revert dune#7415 and dune#7450 (Resolve ppx_runtime_libraries in the target context when cross compiling) (dune#7887, fixes dune#7875, @emillon)

With the progress of the ongoing stabilisation effort for OCaml 5.1.0, I am happy to announce a second alpha release for OCaml 5.1.0.

This second alpha release contains many noteworthy fixes:

  • a long-awaited GC fix
  • a Windows ABI fix

as announced in the first alpha but also

  • a compiler-libs (parsetree) fix
  • a type system compatibility enhancement change
  • a restored backed for s390x/IBM Z

The full list of changes since the first alpha is available below.

Once most major OCaml tools are updated to the last compiler-libs changes, we will switch to beta releases. Hopefully, this will happen in the upcoming weeks. The progress on stabilising the ecosystem is tracked on the opam readiness for 5.1.0 meta-issue.

Currently, the release is still planned for around July.

If you find any bugs, please report them on OCaml's issue tracker.

If you are interested in the ongoing list of new features and bug fixes, the updated change log for OCaml 5.1.0 is available on GitHub.

Installation Instructions

The base compiler can be installed as an opam switch with the following commands on opam 2.1:

opam update
opam switch create 5.1.0~alpha2

The source code for the alpha is also available at these addresses:

Fine-Tuned Compiler Configuration

If you want to tweak the configuration of the compiler, you can switch to the option variant with:

opam update
opam switch create <switch_name> ocaml-variants.5.1.0~alpha2+options <option_list>

where option_list is a space-separated list of ocaml-option-* packages. For instance, for a flambda and no-flat-float-array switch:

opam switch create 5.1.0~alpha2+flambda+nffa ocaml-variants.5.1.0~alpha2+options ocaml-option-flambda ocaml-option-no-flat-float-array

All available options can be listed with opam search ocaml-option.

See full changelog

Runtime System

  • #11589, #11903: Modify the GC pacing code to make sure the GC keeps up with allocations in the presence of idle domains. (Damien Doligez and Stephen Dolan, report by Florian Angeletti, review by KC Sivaramakrishnan and Sadiq Jaffer)
  • (breaking change) #11865, #11868, #11876: Clarify that the operations of a custom block must never access the OCaml runtime. The previous documentation only mentioned the main illicit usages. In particular, since OCaml 5.0, it is no longer safe to call caml_remove_global_root or caml_remove_generational_global_root from within the C finalizer of a custom block, or within the finalization function passed to caml_alloc_final. As a workaround, such a finalization operation can be registered with Gc.finalize instead, which guarantees to run the finalizer at a safe point. (Report by Timothy Bourke, discussion by Yotam Barnoy, Timothy Bourke, Sadiq Jaffer, Xavier Leroy, Guillaume Munch-Maccagnoni, and Gabriel Scherer)
  • #11827, +#12249: Restore prefetching for GC marking (Fabrice Buoro and Stephen Dolan, review by Gabriel Scherer and Sadiq Jaffer)
  • #12131: Simplify implementation of weak hash sets, fixing a performance regression. (Nick Barnes, review by François Bobot, Alain Frisch and Damien Doligez).

  • #12231: Support MinGW-w64 11.0 winpthreads library, where the macro to set up to get flexdll working changed (David Allsopp and Samuel Hym, light review by Xavier Leroy)

Type System

  • (breaking change) #12189, #12211: anonymous row variables in explicitly polymorphic type annotation, e.g. 'a. [< X of 'a ] -> 'a, are now implicitly universally quantified (in other words, the example above is now read as 'a 'r. ([< X of 'a ] as 'r) -> 'a). (Florian Angeletti and Gabriel Scherer, review by Jacques Garrigue)

Code Generation And Optimizations

  • #11712, #12258, #12261: s390x / IBM Z multicore support: OCaml & C stack separation; dynamic stack size checks; fiber and effects support. (Aleksei Nikiforov, with help from Vincent Laviron and Xavier Leroy, additional suggestions by Luc Maranget, review by the same and KC Sivaramakrishnan)

Internal/compiler-libs Changes

  • #12119, +#12188, +#12191: mirror type constraints on value binding in the parsetree: the constraint typ in let pat : typ = exp is now directly stored in the value binding node in the parsetree. (Florian Angeletti, review by Richard Eisenberg)

Bug Fixes

  • #11846: Mark rbx as destroyed at C call for Win64 (mingw-w64 and Cygwin64). Reserve the shadow store for the ABI in the c_stack_link struct instead of explictly when calling C functions. This simultaneously reduces the number of stack pointer manipulations and also fixes a bug when calling noalloc functions where the shadow store was not being reserved. (David Allsopp, report by Vesa Karvonen, review by Xavier Leroy and KC Sivaramakrishnan)

  • #12170: fix pthread_geaffinity_np configure check for android (David Allsopp, review by SĂ©bastien Hinderer)

  • #12252: Fix shared library build error on RISC-V. (Edwin Török, review by NicolĂĄs Ojeda BĂ€r and Xavier Leroy)

  • #12255, #12256: Handle large signal numbers correctly (Nick Barnes, review by David Allsopp).

  • #12277: ARM64, fix a potential assembler error for very large functions by emitting stack reallocation code before the body of the function. (Xavier Leroy, review by KC Sivaramakrishnan)

opam 2.1.5

Feedback on this post is welcomed on Discuss!

We are pleased to announce the patch release of opam 2.1.5.

This opam release consists of backported bug & security fixes:

  • Security issue: fix opam installing packages without checking their checksum when the local cache is corrupted in some case (#5538), you can find more information there.
  • Variables are now expanded in build-env (as for setenv) (#5352)
  • Correctly handle empty environment variable additions (#5350)
  • Skip empty environment variable additions (#5350)
  • Fix passing archive-mirrors field from init config file to config (#5315)
  • git, hg: Use the full SHA1 revision instead of just the 8 first characters (#5342)

Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --version 2.1.5"

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

Merlin 4.9

We are pleased to announce the release of Merlin 4.9 for OCaml 4.14.1 and 5.0.

This maintenance release brings multiple bug fixes and improvements. In particular we identified and patched an important memory consumption issue that could greatly affect Merlin’s performance in heavily functorized projects.

See full changelog
  • merlin binary
    • Allow monadic IO in dot protocol (#1581)
    • Add a scope option to the occurrences command in preparation for the upcoming project-wide-occurrences feature (#1596)
    • Construct bool-typed holes as false instead of true in the construct command, for consistency (#1599).
    • Add a hook to configure system command for spawning ppxes when Merlin is used as a library. (#1585)
    • Implement an all-or-nothing cache for the PPX phase (#1584)
    • Cleanup functors caches when backtracking, to avoid memory leaks (#1609, fixes #1529 and ocaml-lsp#1032)
    • Fix construct results ordering for sum types sand poly variants (#1603)
    • Fix object method completion not working (#1606, fixes #1575)
    • Improve context detection for package types (#1608, fixes #1607)
    • Fix incorrect locations for string literals (#1574)
    • Fixed an issue that caused errors to erroneously alert about missing cmi files (#1577)
    • Prevent destruct from crashing on closed variant types (#1602, fixes #1601)
    • Improve longident parsing (#1612, fixes #945)
  • editor modes
    • emacs: call the user's configured completion UI in merlin-construct (#1598)
  • test suite
    • Add missing dependency to a test using ppxlib (#1583)
    • Add tests for the new PPX phase cache (#1584)
    • Add and update tests for construct ordering (#1603)

Dune 3.8.0

The dune team is pleased to announce the release of Dune 3.8.0.

It is now available in opam-repository. As usual, it should always be safe to upgrade your dune package: new features and deprecations are only available if you upgrade the language version in your dune-project files.

🌟 Spotlight Features

  1. Dune concurrent action

Dune 3.8.0 introduced the new concurrent action. You can now use it instead of the progn action to execute actions concurrently.

For instance:

  (write-file A "I am file A.\n")
  (write-file B "I am certainly file B.\n")
  (write-file C "I am most certainly file C.\n"))))

will write to files A, B and C concurrently.

  1. Support for .mld files

In Dune 3.7.0, we introduced version 0.3 of the mdx stanza, which came with support for .mld files.

In Dune 3.8.0, .mld files are now supported by default with version 0.4 of the mdx stanza!

Have a look at this diff to see how to migrate your code to the new stanza version.

See full changelog


  • Introduce mdx stanza 0.4 requiring mdx >= 2.3.0 which updates the default list of files to include *.mld files (#7582, @Leonidas-from-XIV)

  • Allow (stdlib ...) to be used with (wrapped false) in library stanzas (#7139, @anmonteiro).

  • Allow the main module of a library with (stdlib ...) to depend on other libraries (#7154, @anmonteiro).

  • Support (link_flags ...) in (cinaps ...) stanza. (#7423, fixes #7416, @nojb)

  • Allow (package ...) in any position within (rule ...) stanza (#7445, @Leonidas-from-XIV)

  • Added a new user action (concurrent ) which is like (progn ) but runs the actions concurrently. (#6933, @Alizter)

  • Accept the Ordered Set Language for the modes field in library stanzas (#6611, @anmonteiro).

  • Allow parallel execution of inline tests partitions (#7012, @hhugo)

  • Add the --display-separate-messages flag to separate the error messages produced by commands with a blank line. (#6823, fixes #6158, @esope)

  • Add --watch-exclusions to Dune build options (#7216, @jonahbeckford)

  • Adds support for loading plugins in toplevels (#6082, fixes #6081, @ivg, @richardlford)

  • Introduce a public_headers field on libraries. This field is like install_c_headers, but it allows to choose the extension and choose the paths for the installed headers. (#7512, @rgrinberg)

  • Dune can now detect Coq theories from outside the workspace. This allows for composition with installed theories (not necessarily installed with Dune). (#7047, @Alizter, @ejgallego)

  • Added a --no-build option to dune coq top for avoiding rebuilds (#7380, fixes #7355, @Alizter)

  • Add a coqdoc_flags field to the coq.theory stanza allowing the user to pass extra arguments to coqdoc. (#7676, fixes #7954 @Alizter)

  • Preliminary support for Coq compiled intefaces (.vos files) enabled via (mode vos) in coq.theory stanzas. This can be used in combination with dune coq top to obtain fast re-building of dependencies (with no checking of proofs) prior to stepping into a file. (#7406, @rlepigre)

  • Read pkg-config arguments from the PKG_CONFIG_ARGN environment variable (#1492, #7734, @anmonteiro)

  • Use $PKG_CONFIG, when set, to find the pkg-config binary (#7469, fixes #2572, @anmonteiro)


  • Bootstrap: remove reliance on shell. Previously, we'd use the shell to get the number of processors. (#7274, @rgrinberg)

  • Non-user proccesses such as version control or config checking are now run silently. (#6994, fixes #4066, @Alizter)

  • Bytecode executables built for JSOO are linked with -noautolink and no longer depend on the shared stubs of their dependent libraries (#7156, @nojb)

  • Always include opam files in the generated .install file. Previously, it would not be included whenever (generate_opam_files true) was set and the .install file wasn't yet generated. (#7547, @rgrinberg)


  • Modules that were declared in (modules_without_implementation), (private_modules) or (virtual_modules) but not declared in (modules) will cause Dune to emit a warning which will become an error in 3.9. (#7608, fixes #7026, @Alizter)

  • Coq language versions less 0.8 are deprecated, and will be removed in an upcoming Dune version. All users are required to migrate to (coq lang 0.8) which provides the right semantics for theories that have been globally installed, such as those coming from opam (@ejgallego, @Alizter)


  • Find pps dependencies in the host context when cross-compiling, (#7415, fixes #4156, @anmonteiro)

  • Fix plugin loading with findlib. The functionality was broken in 3.7.0. (#7556, @anmonteiro)

  • Load the host context findlib.conf when cross-compiling (#7428, fixes #1701, @rgrinberg, @anmonteiro)

  • Allow overriding the ocaml binary with findlib configuration (#7648, @rgrinberg)

  • Resolve ppx_runtime_libraries in the target context when cross compiling (#7450, fixes #2794, @anmonteiro)

  • Fix dune install when cross compiling (#7410, fixes #6191, @anmonteiro, @rizo)

  • Fix string quoting in the json file written by --trace-file (#7773, @rleshchinskiy)

  • Correctly set MANPATH in dune exec. Previously, we would use the bin/ directory of the context. (#7655, @rgrinberg)

  • merlin: ignore instrumentation settings for preprocessing. (#7606, fixes #7465, @Alizter)

  • When a rule's action is interrupted, delete any leftover directory targets. This is consistent with how we treat file targets. (#7564, @rgrinberg)

  • Fix dune crashing on MacOS in watch mode whenever $PATH contains $PWD (#7441, fixes #6907, @rgrinberg)

  • Dune in watch mode no longer builds concurrent rules in serial (#7395 @rgrinberg, @jchavarri)

  • dune coq top now correctly respects the project root when called from a subdirectory. However, absolute filenames passed to dune coq top are no longer supported (due to being buggy) (#7357, fixes #7344, @rlepigre and @Alizter)

  • RPC: Ignore SIGPIPE when clients suddenly disconnect (#7299, #7319, fixes #6879, @rgrinberg)

  • Always clean up the UI on exit. (#7271, fixes #7142 @rgrinberg)

  • Bootstrap: correctly detect the number of processors by allowing nproc to be looked up in $PATH (#7272, @Alizter)

  • Speed up file copying on macos by using clonefile when available (@rgrinberg, #7210)

  • Support commands that output 8-bit and 24-bit colors in the terminal (#7188, @Alizter)

  • Speed up rule generation for libraries and executables with many modules (#7187, @jchavarri)

  • Do not re-render UI on every frame if the UI doesn't change (#7186, fix #7184, @rgrinberg)

  • Make coq_db creation in scope lazy (@ejgallego, #7133)

  • dune install now respects --display quiet mode (#7116, fixes #4573, fixes #7106, @Alizter)

  • Stub shared libraries (dllXXX_stubs.so) in Dune-installed libraries could not be used as dependencies of libraries in the workspace (eg when compiling to bytecode and/or Javascript). This is now fixed. (#7151, @nojb)

  • Fix regression where Merlin was unable to handle filenames with uppercase letters under Windows. (#7577, @nojb)

  • On nix+macos, pass -f to the codesign hook to avoid errors when the binary is already signed (#7183, fixes #6265, @greedy)

  • Fix bug where RPC clients built with dune-rpc-lwt would crash when closing their connection to the server (#7581, @gridbugs)

  • Fix RPC server on Windows (used for OCaml-LSP). (#7666, @nojb)

New Ubuntu 23.04 and Fedora 38 distributions have been added to docker base image builder. Following their respective releases:

  • Ubuntu 23.04 was released 20 April 2023
  • Fedora 38 was released 18 April 2023 These images started building from Apr 25th 2023 and have been pushed to https://hub.docker.com/r/ocaml/opam with a full range of OCaml versions and variants. As always the status of the images can be viewed on images.ci.ocaml.org.

Alongside the Linux updates base images containing OCaml 5.1 have also been published for supported Linux platforms. Following the OCaml 5.1 Alpha release announcement on discuss.ocaml.org. Enjoy and please report any issues on ocurrent/docker-base-images/issues.

Utop 2.12.1

Following the release of UTop 2.12.0 a few days ago, we released UTop 2.12.1, a patch release that fixes a regression with unit qualification.

This release also includes an implementation of completion-at-point for Emacs.

See full changelog

Utop 2.12.0

UTop 2.12.0 is out with support for the upcoming release of OCaml 5.1!

This release also fixes an issue that prevented users to redefine the () constructor. You can now safely run type t = () of unit and continue using your top-level session.

See full changelog
  • Add support for OCaml 5.1 (#421, @emillon)

  • Mark prompt_continue, prompt_comment, smart_accept, new_prompt_hooks, at_new_prompt as deprecated (they have been documented as such since 2012 and most of them are ignored) (#415, @emillon)

  • Qualify () constructor in generated expressions. (#418, fixes #417, @emillon)

Mdx 2.3.0

We're pleased to announce the release of Mdx 2.3.0!

This release comes with support for mld files and changes the parser used by the toplevel, which allows Camlp5's parser to be used with MDX.

🌟 Spotlight Feature

Starting in MDX 2.3.0, you can now execute code blocks in your .mld files! 🎉

As a reminder, .mld files are text files similar to Markdown, but instead of using the Markdown markup language, they use the Ocamldoc markdown language - as is used in .mli files. .mld are typically used to write manuals with odoc.

To run mdx on .mld files, start by enabling mdx in your dune-project:

(using mdx 0.3)

Then list your .mld files in the mdx stanza in your dune:

 (files index.mld))

Now if you put a code block in index.mld, it will be executed when running dune test and if dune will suggest to promote the output. For instance, if you run dune test with this index.mld:

Here's an example code block in a [.mld] file:

  # List.map (fun x -> x * x) [(1 + 9); 2; 3; 4];;

dune test will return:

diff --git a/_build/default/index.mld b/_build/default/.mdx/index.mld.corrected
index 337b042..c29bb63 100644
--- a/_build/default/index.mld
+++ b/_build/default/.mdx/index.mld.corrected
@@ -2,5 +2,6 @@ Here's an example code block in a [.mld] file:
   # List.map (fun x -> x * x) [(1 + 9); 2; 3; 4];;
+  - : int list = [100; 4; 9; 16]

You can run dune promote to accept the change.

You can see a complete demo of this here.

Now you can keep the code blocks in your manual up-to-date even when your API changes!

See full changelog


  • Added support for mld files (#423, @jonludlam)


  • Switch to using the parser that toplevel uses (found in a mutable ref, instead of always the official OCaml parser). This allows Camlp5's parser to be used with MDX. (#417, @chetmurthy)

Four months after the release of OCaml 5.0.0, the set of new features for the future version 5.1.0 of OCaml has been frozen. We are thus happy to announce the first alpha release for OCaml 5.1.0.

This alpha version is here to help fellow hackers join us early in our bug hunting and opam ecosystem fixing fun (see below for the installation instructions). The progresses on stabilising the ecosystem are tracked on the opam readiness for 5.1.0 meta-issue.

If you find any bugs, please report them on OCaml's issue tracker.

Note that this early alpha version is missing two important fixes for the garbage collector and Windows support. Those fixes will be available before the beta. The full release is expected in July.

If you are interested in the ongoing list of new features and bug fixes, the updated change log for OCaml 5.1.0 is available on GitHub.

Installation Instructions

The base compiler can be installed as an opam switch with the following commands on opam 2.1:

opam update
opam switch create 5.1.0~alpha1

For previous version of opam, the switch creation command line is slightly more verbose:

opam update
opam switch create 5.1.0~alpha1 --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git

The source code for the alpha is also available at these addresses:

Fine-Tuned Compiler Configuration

If you want to tweak the configuration of the compiler, you can switch to the option variant with:

opam update
opam switch create <switch_name> ocaml-variants.5.1.0~alpha1+options <option_list>

where option_list is a space separated list of ocaml-option-* packages. For instance, for a flambda and no-flat-float-array switch:

opam switch create 5.1.0~alpha1+flambda+nffa ocaml-variants.5.1.0~alpha1+options ocaml-option-flambda ocaml-option-no-flat-float-array

The command line above is slightly more complicated for opam version anterior to 2.1:

opam update
opam switch create <switch_name> --packages=ocaml-variants.5.1.0~alpha1+options,<option_list> --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git

In both cases, all available options can be listed with opam search ocaml-option.

Due to maintenance operations on Tuesday 11th April between 7:30am and 11:00am (UTC+1), the build system will be running at approximately 50% capacity. You may experience some build delays in Opam Repo CI and OCaml CI.

Thank you for your patience and understanding during this time.

Update: This work was completed on schedule and the cluster is back to full capacity.

Dune 3.7.1

We are excited to announce the release of Dune 3.7.1, which brings a few bug fixes from the recent 3.7.0 release:

  • Resolved watch mode issue for executables on macOS: We have addressed a problem with the recently introduced watch mode for executables that was causing segmentation faults on macOS. Users can now enjoy a stable watch mode without unexpected crashes on macOS.
  • Fixed "Too many links" error on Windows: We have fixed an issue that caused Dune build failures with a "Too many links" error on Windows when using Dune cache.

... and a few more, you can consult the changelog for a full list of bug fixes.

See full changelog
  • Fix segfault on MacOS when dune was being shutdown while in watch mode. (#7312, fixes #6151, @gridbugs, @emillon)

  • Fix preludes not being recorded as dependencies in the (mdx) stanza (#7109, fixes #7077, @emillon).

  • Pass correct flags when compiling stdlib.ml. (#7241, @emillon)

  • Handle "Too many links" errors when using Dune cache on Windows. The fix in 3.7.0 for this same issue was not effective due to a typo. (#7472, @nojb)

The intention is to retire the ocamllabs.io domain. Therefore any services using the domain will be redirected. From today, the Web UI for Opam Repo CI is available on both opam-ci.ci3.ocamllabs.io and opam.ci.ocaml.org with the service available at both opam-repo-ci.ci3.ocamllabs.io and opam-repo.ci.ocaml.org. In time, the ocamllabs.io sites will issue HTTP 301 permanent redirect messages.

Previously, opam.ci.ocaml.org targetted a web server which issued an HTTP 302 redirect to opam.ci3.ocamllabs.io. This redirection has been removed. opam.ci.ocaml.org points to the actual site.

As previously announced, "opam-repository-mingw" is no longer receiving updates.

We're actively working on getting the Windows compiler packages into ocaml/opam-repository. There are two issues which are taking (me) a little while to finish solving, but more on that further below.

In the gap - of hopefully only a month or so - for this being ready, there's is an issue that new releases are of course not available when opam-repository-mingw is being used with ocaml/setup-ocaml@v2 GitHub actions workflows. I'm hoping here to set out what's happening, and what steps you may need to take to keep your GitHub Actions Windows workflows running smoothly over the next few months.

What's happening right now?

We've updated setup-ocaml to use ocaml-opam/opam-repository-mingw instead of fdopen/opam-repository-mingw (see ocaml/setup-ocaml#651). This clone has been augmented with:

  • OCaml 4.14.1 packages, in the same style as the 4.14.0 forked packages (the "pre-compiled" package variants exist, but they're not pre-compiled)
  • Changes to the constraints for existing packages only

If you're using setup-ocaml in its default configuration, you should notice no change except that 4.14.x builds should now use 4.14.1 and the initial build will be a little slower as it builds from sources (GitHub Actions caching will then take over for subsequent runs).

For new releases of packages, it's necessary to add opam-repository to the repositories selections for the switches. It's important that opam-repository is at a lower priority than opam-repository-mingw for existing packages, so it's better to use these lines in your ocaml/setup-ocaml@v2 step than to issue opam repo add --rank=1000 later:

uses: ocaml/setup-ocaml@v2
  opam-repositories: |
    opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset
    default: https://github.com/ocaml/opam-repository.git

What do I do when things are broken?

There's an issue tracker on ocaml-opam/opam-repository-mingw, and this is a very good place to start.

If a version of a package isn't building, there are three possible remedies:

  • Previous versions of the package may have carried non-upstreamed patches in opam-repository-mingw. opam-repository's policy is not to carry such patches. In this case, the package actually doesn't work on Windows.
    • opam-repository should be updated to have os != "win32" added to the available field for the package
    • An issue on the package's upstream repo should be opened highlighting the need to upstream patches (or even a pull request with them!)
    • The patches in opam-repository-mingw make changes which may not necessarily be accepted/acceptable upstream in their current form, so the issue may be a better starting point than simply taking a patch and opening a pull request for it (for example, the utop package contains patches which may require further work and review)
  • The package relies on environment changes in "OCaml for Windows". For example, the Zarith package works in "OCaml for Windows" because the compiler packages unconditionally set the CC environment variable. This change is both not particularly desirable change to upstream (it is very confusing, for example, when working on the compiler itself) and also extremely difficult to upstream, so the fix here is instead to change the package's availability with (os != "win32" | os-distribution = "cygwinports") and constrain away OCaml 5 on Windows ("ocaml" {< "5.0" | os != "win32"})
  • Package constraints on existing packages need updating in ocaml-opam/opam-repository-mingw. For example, the release of ppxlib 0.29 required some existing packages to have upperbounds added.

What about OCaml 5.0.0?

OCaml 5.0.0 was released with support for the mingw-w64 port only, however, there's a quite major bug which wasn't caught by OCaml's testsuite, but is relatively easily triggered by opam packages. I've previously announced how to add OCaml 5 to a workflow. For the time being, the packages for OCaml 5 aren't automatically made available.

What's next?

The ultimate goal is to be using an upstream build of opam.exe with ocaml/opam-repository, just as on Unix. Once opam 2.2 is generally available (we're aiming for an alpha release at the end of March) and the compiler packages in opam-repository support the Windows builds, we will recommend stopping use of opam-repository-mingw completely. The default in setup-ocaml won't change straight away, since that risks breaking existing workflows.

With upstream compiler support, we'll be able to extend some of the existing bulk build support already being done for Linux to Windows and start to close the gap of patches in opam-repository-mingw.

Windows compiler packages

I mentioned earlier the problems with moving the compiler packages into opam-repository, and just for general interest this elaborates on them.

The first issue affects the use of the Visual Studio port ("MSVC") and is a consequence of the somewhat strange way that the C compiler is added to the environment when using the Visual Studio C compiler. "OCaml for Windows" (as well as Diskuv) use a wrapper command (it's ocaml-env in "OCaml for Windows" and with-dkml in Diskuv). Those commands are Windows-specific, which is an issue for upstream opam. There's an alternate way which sets the environment variables in a more opam-like way. Doing it that way, though, requires an improvement to opam's environment handling which is in opam 2.2, otherwise there's an easy risk of "blowing" the environment.

The second issue is selecting the C compiler. On Unix, this is easy with ocaml-base-compiler because there is only one "system" C compiler. Windows has two ports of OCaml, and the configuration requires it to be explicitly selected. That requires input from the user on switch creation for a Windows switch.

"OCaml for Windows" solves this by packaging the Windows compilers with the variant name appended, just as opam-repository used to, so ocaml-variants.4.14.1+mingw64 selects the the mingw-w64 port and ocaml-variants.4.14.1+msvc64 selects the MSVC64 port. The problem, as we already had in opam-repository, is that this adds 4 packages for each release of OCaml in ocaml-variants, and leads to a combinatorial explosion when we start considering flambda and other relevant compiler options.

opam-repository switched to using the ocaml-option- packages to solve the combinatorial explosion which was already present in opam-repository. The demonstration repo for OCaml 5 on Windows is already using an adapted version of this so that ocaml-option-mingw selects the mingw-w64 port (by default 64-bit, with ocaml-option-32bit then selecting the 32-bit port).

This work is all in progress and being tested alongside changes in opam 2.2 to support the depext experience on Windows. The only reason that's not being upstreamed piecemeal is that changes to the compiler packages in opam-repository trigger switch rebuilds all over the world, so we don't want to that until we're sure that the packages are correct. The intention is to do this around the time of the alpha release of opam 2.2, once the work in opam itself has settled down.

Thanks for getting to the end, and happy Windows CI testing!

Discuss this post further on the forums.

Following @avsm post on discuss.ocaml.org, we are pleased to announce that DNS names have now been switched over.

We are moving the opam.ocaml.org 2 servers between hosting providers, and wanted to give everyone clear notice that this happening. Over the next 24-48 hours, if you notice any unexpected changes in the way your opam archives work (for example, in your CI or packaging systems), then please do let us know immediately, either here or in ocaml/infrastructure#19 2.

The reason for the move is to take advantage of Scaleway’s generous sponsorship of ocaml.org, and to use their energy efficient renewable infrastructure 4 for our machines.

This also marks a move to building the opam website via the ocurrent 1 infrastructure, which leads to faster and more reliable updates to the hosted package archives (see here for the service graph and build logs 4). There are also now multiple machines behind the opam.ocaml.org 2 DNS (via round-robin DNS), and this makes it easier for us to publish the archives to a global CDN in the future.

But in the very short term, if something explodes unexpectedly, please do let us know.

We are pleased to announce the release of OCamlFormat 0.25.1! This release contains several bug fixes, changes, and new features.

The library is also available through the ocamlformat-lib package on opam. The ocamlformat package only contains the binary.

We would like to thank all contributors for their valuable contributions to this release. Please see the complete changelog for more details.

We hope you enjoy this release and continue to find OCamlFormat a valuable tool for your OCaml projects. You can download ocamlformat.0.25.1 from the opam repository or GitHub.

Thank you for your support and feedback, and please don't hesitate to reach out if you have any questions or issues.

The OCamlFormat team

🌟 Spotlight Feature

  1. New if-then-else and break-cases options

Starting in OCamlFormat 0.25.1, we've also added new values to the if-then-else and break-cases options. Now you can use the vertical value to format these expressions in a more readable and consistent way.

These options are not set by default but you can try them out by customizing your .ocamlformat file as usual.

Here are a few examples:

  • if-then-else = vertical
-  let epi = if Option.is_some next then fmt "@\n" else fmt_opt epi in
+  let epi =
+    if Option.is_some next then
+      fmt "@\n"
+    else
+      fmt_opt epi
+  in
-    if tree_depth tree > depth then node_depth_truncate_ depth node
-    else (* already short enough; don't bother truncating *)
+    if tree_depth tree > depth then
+      node_depth_truncate_ depth node
+    else
+      (* already short enough; don't bother truncating *)
  • break-cases = vertical
-| Ok (`Version | `Help) -> Stdlib.exit 0
-| Error _ -> Stdlib.exit 1
+| Ok (`Version | `Help) ->
+    Stdlib.exit 0
+| Error _ ->
+    Stdlib.exit 1
-    ~f:(function `Int _ | `Float _ -> true | _ -> false)
+    ~f:(function
+      | `Int _
+      | `Float _ ->
+          true
+      | _ ->
+          false)
  1. Formatting .mld files

Formatting .mld files as odoc documentation files is now possible! This will make it much easier to maintain high-quality documentation alongside your OCaml code.

This feature is only available in ocamlformat for now, but keep an eye on the future dune releases to know when dune fmt will be able to format your .mld files!

  1. Various improvements and bugfixes

We fixed various issues related to indentation, alignment, and comments positioning.

Here are a few examples:

  • More consistent indentation inside a parenthesized expression:
        | [ node ] ->
            ( (if List.mem node ~set:integer_graph.(node)
-              then Has_loop [ numbering.forth.(node) ]
-              else No_loop numbering.forth.(node))
+               then Has_loop [ numbering.forth.(node) ]
+               else No_loop numbering.forth.(node))
            , component_edges.(component) )
    (let open Memo.O in
-    let+ w = Dune_rules.Workspace.workspace () in
-    Dune_engine.Execution_parameters.builtin_default
-    |> Dune_rules.Workspace.update_execution_parameters w);
+     let+ w = Dune_rules.Workspace.workspace () in
+     Dune_engine.Execution_parameters.builtin_default
+     |> Dune_rules.Workspace.update_execution_parameters w);
  • More consistent formatting of module expressions:
-  module Sel = (val if is_osx () then (module Mac)
-                    else if Sys.unix then (module Unix)
-                    else (module Fail) : Unix_socket)
+  module Sel =
+    (val if is_osx () then (module Mac)
+         else if Sys.unix then (module Unix)
+         else (module Fail)
+        : Unix_socket)
See full changelog


  • The declaration of options is a regular module instead of a functor. (#2193, @EmileTrotignon)

Bug fixes

  • Fix indentation when ocamlformat is disabled on an expression (#2129, @gpetiot)
  • Reset max-indent when the max-indent option is not set (#2131, @hhugo, @gpetiot)
  • Add missing parentheses around immediate objects having attributes attached in 4.14 (#2144, @gpetiot)
  • Fix dropped comment attached to the identifier of an open-expression (#2155, @gpetiot)
  • Correctly format chunks of file in presence of enable/disable floating attributes (#2156, @gpetiot)
  • Remove abusive normalization in docstrings references (#2159, #2162, @EmileTrotignon)
  • Fix parentheses around symbols in if-then-else branches (#2169, @gpetiot)
  • Preserve position of comments around variant identifiers (#2179, @gpetiot)
  • Fix parentheses around symbol identifiers (#2185, @gpetiot)
  • Fix alignment inconsistency between let-binding and let-open (#2187, @gpetiot)
  • Fix reporting of operational settings origin in presence of profiles (#2188, @EmileTrotignon)
  • Fix alignment inconsistency of if-then-else in apply (#2203, @gpetiot)
  • Fix automated Windows build (#2205, @nojb)
  • Fix spacing between recursive module bindings and recursive module declarations (#2217, @gpetiot)
  • ocamlformat-rpc: use binary mode for stdin/stdout (#2218, @rgrinberg)
  • Fix interpretation of glob pattern in .ocamlformat-ignore under Windows (#2206, @nojb)
  • Remove conf mutability, and correctly display the conventional profile when using print-config (#2233, @EmileTrotignon)
  • Preserve position of comments around type alias (#2239, @EmileTrotignon)
  • Preserve position of comments around constructor record (#2237, @EmileTrotignon)
  • Preserve position of comments around external declaration strings (#2238, @EmileTrotignon, @gpetiot)
  • Preserve position of comments around module pack expressions (#2234, @EmileTrotignon, @gpetiot)
  • Correctly parenthesize array literals with attributes in argument positions (#2250, @ccasin)
  • Janestreet: Fix indentation of functions passed as labelled argument (#2259, @Julow)


  • Indent 2 columns after initializer keyword (#2145, @gpetiot)
  • Preserve syntax of generative modules ((struct end) vs ()) (#2135, #2146, @trefis, @gpetiot)
  • Preserve syntax of module unpack with type constraint (((module X) : (module Y)) vs (module X : Y)) (#2136, @trefis, @gpetiot)
  • Normalize location format for warning and error messages (#2139, @gpetiot)
  • Preserve syntax and improve readability of indexop-access expressions (#2150, @trefis, @gpetiot)
    • Break sequences containing indexop-access assignments
    • Remove unnecessary parentheses around indices
  • Mute warnings for odoc code blocks whose syntax is not specified (#2151, @gpetiot)
  • Improve formatting of odoc links (#2152, @gpetiot)
  • Preserve sugared extension node attached to an if carrying attributes (#2167, @trefis, @gpetiot)
  • Remove unnecessary parentheses around partially applied infix operators with attributes (#2198, @gpetiot)
  • JaneStreet profile: doesn't align infix ops with open paren (#2204, @gpetiot)
  • Re-use the type let_binding from the parser instead of value_binding, improve the spacing of let-bindings regarding of having extension or comments (#2219, @gpetiot)
  • The ocamlformat package now only contains the binary, the library is available through the ocamlformat-lib package (#2230, @gpetiot)

New features

  • Add a break-colon option to decide whether to break before or after the : symbol in value binding declarations and type constraints. This behavior is no longer ensured by ocp-indent-compat. (#2149, @gpetiot)
  • Format .mld files as odoc documentation files (#2008, @gpetiot)
  • New value vertical for option if-then-else (#2174, @gpetiot)
  • New value vertical for option break-cases (#2176, @gpetiot)
  • New value wrap-or-vertical for option break-infix that only wraps high precedence infix ops (#1865, @gpetiot)

watch.ocaml.org has been updated to run as a Docker service stack rather than via docker-compose. This change allowed an OCurrent pipeline to monitor the Docker repository and update the image via docker service update when a new version is available.

We have several other services updated via OCurrent: deploy.ci.ocaml.org

In OCurrent, we can create a schedule node that triggers every seven days and invokes a docker pull, yielding the current image SHA. If this has changed, run docker service update with the new image.

  let peertube =
     let weekly = Current_cache.Schedule.v ~valid_for:(Duration.of_day 7) () in
     let image = Cluster.Watch_docker.pull ~schedule:weekly "chocobozzz/peertube:production-bullseye" in
     Cluster.Watch_docker.service ~name:"infra_peertube" ~image ()

The deployment is achieved through an Ansible Playbook. Further details are available here.

The second part of the update was to improve the visibility of the backups for watch.ocaml.org. As noted previously, these use Tarsnap running monthly via CRON.

For this, a new plugin was added to OCurrent called ocurrent_ssh. This plugin allows arbitrary SSH commands to be executed as part of an OCurrent pipeline.

Again using a schedule node, the Current_ssh.run node will be triggered on a 30-day schedule, and the logs for each run will be available on deploy.ci.ocaml.org.

  let monthly = Current_cache.Schedule.v ~valid_for:(Duration.of_day 30) () in
   let tarsnap = Current_ssh.run ~schedule:monthly "watch.ocaml.org" ~key:"tarsnap" (Current.return ["./tarsnap-backup.sh"])
If you want to contribute to a new release announcement, check out the Contributing Guide on GitHub.