How to add or update opam dependencies#
When a merge request (MR) introduces a new dependency to an opam package, or updates an existing dependency to a different version of an opam package, additional steps must be taken in the development and merge process. This document explains those steps.
If you have already read this guide and only need a refresher, skip to the TL;DR.
Background#
The Octez project is built under a system that is somewhat stricter than the default for OCaml projects. The goal is to make sure that users, developers and the CI use the exact same dependencies, with the exact same versions. To this end:
the set of opam dependencies and their exact version number is stored in an opam lock file ;
the hash of the commit to use from the public opam repository is stored in scripts/version.sh in the variable
opam_repository_tag
;make build-deps
andmake build-dev-deps
use the lock file and the hash to select dependencies;the CI builds and uses Docker images using this information.
Note
The CI Docker images contain additional dependencies
such as odoc
which are needed by the CI but not to build Octez.
The rest of this document explains the process of adding, removing or
updating dependencies from the point-of-view of a developer (you). The
instructions below assume you have already set up your work
environment but that you installed development
dependencies (make build-dev-deps
instead of make build-deps
).
Local work#
The simplest way of using a new dependency on the Octez codebase when working
locally (i.e., on your own machine) is to install it using opam
.
Because you have used make build-dev-deps
in order to install the
Octez dependencies, you have access to the default opam repository.
Install your dependency: opam install foo
Add dependencies to build files: both opam files and dune files must
be updated.
Add the dependency to the relevant declarations in manifest/
. And
then use make -C manifest
to update the opam and dune files accordingly.
For example, if you are modifying the Shell using the new
dependency, you must add an entry in the ~deps
list of the
let octez_shell =
entry of the manifest/product_octez.ml and then run
make -C manifest
. You should see the changes propagated onto
opam/octez-libs.opam and src/lib_shell/dune,
as well as opam/virtual/octez-deps.opam.
You can work on your feature, using the types and values provided by your new dependency.
Making an MR#
Even though you can compile and run code locally, the CI will likely fail. This is because its set of available dependencies is now different from yours. You must follow the steps below in order to produce the necessary Docker images, allowing your work to eventually be merged.
First, in your local copy of Octez, update the
opam_repository_tag
variable in the scripts/version.sh
file. You should set this variable to the commit hash of a recent version of
the master
branch of
the default opam repository.
(Note: this is not always necessary, but it is simpler for you to do so
than to check whether it is necessary to do so.)
Second, update the opam lock file. The safest way to do that is to execute the scripts/update_opam_lock.sh script. It will ask opam to upgrade all Octez dependencies, making sure that unwanted package versions are not selected for dependencies, and will update the lock file accordingly. Note that the diff may include a few more changes than what you strictly need. Specifically, it might include some updates of some other dependencies. This is not an issue in general but it might explain some changes unrelated to your work.
Note
If you do not wish to upgrade all dependencies,
you can also just run opam lock opam/virtual/octez-deps.opam
followed by mv octez-deps.opam.locked opam/virtual
,
or even edit the lock file manually.
Neither of these guarantees that packages are available in the commit
identified by opam_repository_tag
of the public opam repository,
and even so, you may end up with unwanted versions of dependencies;
so you should review the resulting lock file even more carefully.
Editing the lock file manually is even less safe than running opam lock
as it does not guarantee that the set of dependencies is actually
a valid solution that the opam solver could have chosen.
Third, commit the change of scripts/version.sh
and the updated lockfiles
with a title along the lines of “CI: use dependency foo
”.
Finally, push these changes and open an MR.
TL;DR#
As a developer:
You have an Octez MR from
<your-organisation>/tezos:<your-branch>
ontotezos/tezos:master
introducing a dependency tofoo
.You amend the
manifest/
files to declare the dependency.You propagate the changes to
opam
anddune
files by runningmake -C manifest
.You update the
opam_repository_tag
to the commit hash of a recent version of the public default opam repository.You update opam/virtual/octez-deps.opam.locked, for instance by executing scripts/update_opam_lock.sh.
You push the changes to your Octez MR.
As a merger there are no special steps to take:
You test, review, etc. the code.
You assign the Octez MR to Marge Bot.