Dependency bound bumping using Renovate

I’ve added Cabal file parsing to Renovate. Renovate is a program that scans your build configuration and finds outdated dependencies. To learn more about Renovate, here is the product page, here is the Github page.

I’d like to invite users of haskell-actions to try this out on projects with simple bounds like >=X.Y && <V.W. Setup instructions: haskell-actions/setup/docs.examples.md#Dependency updates.

For maximum convenience, Cabal constraints should get automatically picked up from Renovate commits, without any additional configuration. Without any way to pick up the new version (be it through git trailers or some other mechanism), the Cabal solver (running in the CI of the Renovate PR) might not actually pick the newly released version of the dependency, which means the PR must be tested manually, which is a bummer.

Using git trailers for messaging between Renovate and the CI suite is one protocol that enables this functionality. It would be nice to agree on the protocol across projects. That way, arbitrary projects could swap either Renovate or haskell-actions out for other solutions.

In the future, I think I’d be nice to add support for this protocol to e.g. Haskell-CI.

Of course, it would also be possible to have Renovate add these trailers by default, eventually.

Example scenario

Let’s say you have the dependency bound lens >=5.2 && <5.3. Now, imagine that lens-5.3 gets released. (you can see on Hackage that this did in fact happen in May 2024)

  1. The Renovate Github app scans your repo periodically
  2. It makes a commit with the trailer New-Versions: lens==5.3.3, and a PR with that commit
  3. Your CI suite, when it runs on the Renovate PR, configured using the instructions linked above, converts the git trailer to the line constraints: lens==5.3.3 in cabal.project.
  4. The CI suite either passes or fails.
    • If it fails (as it very well might, since this is a major release of lens!), human intervention is necessary. Well, at least you know.
    • If it passes, you could merge the PR. Any subsequent Hackage revision/release could also be automated, but that’s a different topic.

Related projects

  • Joachim Breitner authored haskell-bounds-bump-action. One limitation is that it only works for Github. In contrast to Renovate, it is coded in Haskell, which means it can leverage the Cabal libraries.

  • Freckle authored stack-lint-extra-deps. It is an independent executable, so you can run it anywhere, like Renovate. And it is coded in Haskell. But it is obviously just for stack.yaml files.

20 Likes

Can you be more specific here, what exactly is in the commit? There’s no New-Versions property in .cabal file, did you mean build-depends?

You can see an example commit in the pureMD5 repo. New-Versions is a git trailer, they are documented in the official git documentation or at alchemists.io. Git trailers are part of the commit message. Github will show you the commit message in monospace type.

The point of this trailer is to communicate a temporary constraint to Cabal running in the CI system. It’s related to build-depends, since build-depends entries also typically have constraints on them. But New-Versions is used here for pinning to an exact version, which is the version that Renovate discovered. We want the CI suite to run with that exact version, because we want to find out whether the new release is compatible or not. If we didn’t have this additional constraint, the Cabal solver might not actually pick the new release. The modified build-depends entry as generated by Renovate will allow the newly released version, but it is wider than that, and in fact allows the whole major series that the new version is part of.

Does that clarify anything? I am still wondering how I can make this more appealing to e.g. new users reading the haskell-actions documentation. So if this message clarifies things for you, I’d love to hear if you have any suggestions on how I can make this as appealing as possible to readers of the haskell-actions documentation.

2 Likes