Reduce Renovate noise by using Truncated Versions (<major>.<minor>) for development-only dependencies

Related to https://gitlab.com/groups/gitlab-com/gl-infra/gitlab-dedicated/-/epics/483

Related to scalability#3178

Background

One of the ways that Renovate generates noise on GitLab projects is through patch version updates.

For many projects, especially development-only dependencies, such as pmv, shfmt, shellcheck etc etc, this is noise. There is very little reason to need to control these dependencies, and the extra noise this creates is not worth the additional rigour it adds to projects.

This is not the case for runtime dependencies, where controlling the patch version may, in some cases, be very important.

Tools

As we migrate of asdf to mise (gitlab-com/runbooks#134), we have the ability to use partial matches on version numbers.

For example, we can use the <major>.<minor> version shfmt 3.8.0 and mise will match shfmt 3.8.*.

This means that the latest patch will be automatically used, without the need for Renovate updates for each patch update.

Unfortunately, this doesn't translate well to the rest of our ecosystem.

For one, the .gitlab-ci-asdf-versions.yml file, which is generated from .tool-versions would then also use GL_ASDF_SHFMT_VERSION: "3.8". This breaks, however, since many projects don't publish <major>.<minor> versions on container tags, and we use the GL_ASDF_SHFMT_VERSION variables to pull container images, for example in GitLab CI.

job:
  image: shfmt:$GL_ASDF_SHFMT_VERSION

In many cases, these container images are only presented as full semver tags.

Workaround

For many tasks in common-ci-tasks, we use our own container images. These are stored in the common-ci-tasks-images (https://gitlab.com/gitlab-com/gl-infra/common-ci-tasks-images) project.

This presents us with the option to provide our own <major>.<minor> tags for development-only container images.

For these images, in common-ci-tasks-images we publish both the full semver image, plus the <major>.<minor> version image, which always represents the latest patch.

In .tool-versions, we use the major.minor versions, as follows

shfmt 3.8

Renovate

Renovate will always attempt to use the full semver version tag.

This means that it will replace 3.8 with 3.8.x in an MR, and then create a new MR for each patch after that. We're then back to the noise.

It's possible that we'll be able to coerce Renovate into not behaving in this way, but will need try various experiments (possibly using a custom regex versioning scheme, or similar)

Edited by Andrew Newdigate