Skip to content
The release manifest

The release manifest

The release manifest records which modular component versions each GitLab version was published with. It is machine-readable data. release-tools writes both tiers: a module’s own release pipeline writes its catalog entry, and the GitLab release pipeline writes the record. Installation and provisioning tools such as Instrumentor read them.

This page explains how to read the answer the release manifest gives, and the limits of that answer. It does not cover the mechanics of fetching the files. For the file structure, see the Release Manifest design document.

Why there are two tiers

The release manifest is split into a mutable catalog (internal) and an immutable record, and the split exists because the two answer different questions.

The catalog is working state for a GitLab release that has not shipped yet. Entries land in it as modules publish through Release Framework, one at a time, in whatever order the module teams release. It describes an intent, not an outcome: a version you read from it today can be replaced before that GitLab release publishes.

The record states an outcome. When a GitLab version publishes, the catalog for that version is copied into a single record, and that record says GitLab 19.5.0 was published with these module versions. Consumers read the record rather than the catalog because it describes something that actually happened, and because it never changes afterwards.

Compatibility holds for the exact version pair, and nothing wider

A record does make a compatibility statement, but a narrow one. It is about a compatible version pair: one GitLab version together with one version of one module.

When the record for GitLab 19.5.0 names Artifact Registry 1.275.1, that version pair is compatible. GitLab 19.5.0 and Artifact Registry 1.275.1 shipped together and work together. A record names several modules, and each one forms its own version pair with that GitLab version.

The record says nothing about any other version pair. It does not say 1.275.1 is the only Artifact Registry version that works with 19.5.0, and it does not say that a different Artifact Registry version is broken on 19.5.0. A record is not a compatibility matrix, and neither tier can tell you which module versions work with a GitLab version in general.

The catalog makes no compatibility statement at all. Its GitLab release has not published, so no version pair in it has shipped.

Use a record to install or reproduce a version pair that shipped. Do not use it to derive a supported range.

One exact version, never a range

For each module, a record names exactly one version. That is the version to install. The release manifest has no way to express a range, a floor, or a ceiling, and it makes no claim about any version it does not name.

Comparing two records does not produce a supported range. For example, if the record for 19.2.0 names Artifact Registry 1.270.0 and the record for 19.3.0 names 1.272.5, that does not mean 19.2.0 supports anything up to 1.272.5. It means 19.2.0 was published with 1.270.0, and says nothing about 1.272.5.

This is deliberate. Installation tooling needs exactly one version per module to act on, and one named version is reproducible: two installs of the same GitLab version get the same module versions.

A module absent from a record has no recommended version for that GitLab release. Absence carries no other meaning. It does not say the module is incompatible with that release, and it does not say the module published late. An entry can also be missing because it was never written. Treat absence as no information about the module.

Some GitLab versions have no record at all, because they published before the release manifest existed. A request for one of those finds nothing, and that absence says nothing about which module versions those releases shipped with.

A published record never changes

Once a GitLab version is published, its record is frozen. Tooling can treat it as a stable answer and cache it.

Freezing has one accepted cost: a record can name a module version that is later found to contain a security vulnerability, and the record still does not change. For example, with Artifact Registry, over an illustrative three weeks:

DayEventArtifact Registry version for GitLab 19.5.0Artifact Registry version for GitLab 19.5.1
0GitLab 19.5.0 publishes1.275.1no record yet
14A security vulnerability is found in 1.275.1. Artifact Registry publishes 1.275.2 with the fix1.275.1, unchangedno record yet
21GitLab 19.5.1 publishes1.275.1, unchanged1.275.2

From day 14 to day 21, the only record for 19.5 names the affected version. Nothing rewrites it, and nothing back-ports the fix into it.

The record is not wrong. GitLab 19.5.0 really was published with Artifact Registry 1.275.1, and that stays true forever. It is simply no longer the version you want to install. A new record, for a new GitLab patch release, is the only thing that names a newer module version.

So: upgrade to the most recent GitLab patch version promptly. That is the only route by which a module fix reaches you.

Common situations

These came up while designing the release manifest, and the answers are not obvious from the data alone.

A module fix exists, but only in a later GitLab release. For example, you are on GitLab 19.2.9 with Knowledge Graph 0.95.3. The fix is in Knowledge Graph 0.95.4, which first appears in the record for 19.3.0. Upgrading GitLab to 19.3.0 is the recommended path. Upgrading Knowledge Graph to 0.95.4 while staying on 19.2.9 is possible and may work, but no GitLab release was published with that combination, so no record names it. Your installation then matches no published GitLab release, which makes any later problem harder to diagnose.

A module publishes after the GitLab release does. A module that is tagged but not yet published when a GitLab version publishes is absent from that record. It appears in a later record. A GitLab release is never blocked waiting for a module to publish, because module and GitLab release cadences are decoupled by design. This is one reason a module is absent from a record, and you cannot tell from the record which reason applies.

Module versions can move in either direction on upgrade. A module’s version in a record is set by what GitLab shipped with, not by what you had installed before, so an upgrade can name an older module version than the one you are running.

What the release manifest does not do

  • It does not extend a named version pair’s compatibility to any other version pair.
  • It does not express version ranges or compatibility windows.
  • It says nothing about combinations it does not name.
  • It does not replace managed versioning or the *_VERSION files in the Rails codebase. Both remain in place today.
  • It does not bundle or build artifacts. It only records versions.
Last updated on