GitLab Release Manifest
Summary
The GitLab Release Manifest provides structured data about the versions of modular components of GitLab that are compatible with a given overarching GitLab version. This information is intended to be used by internal and external installation tools that aim to provide GitLab environments containing modular components, such as GitLab Orbit and Artifact Registry. The release manifest is built with a particular focus on simplifying the initial installation of GitLab (with modular components) and the experience of upgrading GitLab automatically.
Goals, Non-Goals, and Assumptions
Goals
- Communicate the versions of modular components which are compatible with a GitLab version
- Ensure that the modular component release cycle is not tied to GitLab’s current release schedule
- Allow users to upgrade a single modular component while keeping most of their GitLab installation unchanged
- Release manifest should be structured and machine readable
- Release manifest should be immutable once a GitLab version has been published
Non-Goals
- Replace Managed versioning
- Replace
*_VERSIONfiles in the GitLab Rails codebase (such as GITLAB_KAS_VERSION, GITALY_SERVER_VERSION, etc.) - Build or bundle the binaries, docker images, Helm charts for modular components into the existing GitLab Helm chart, CNG images, or Omnibus package
Assumptions
- Modular components follow semantic versioning and produce semantic releases using the Release Framework
- Modular components build their own build artifacts such as binaries, container images, Helm charts, etc.
- Modular components tag and publish releases at their own pace
Present State
Each GitLab version consists of many components apart from the Rails codebase. The commonly used method to store the versions of these components is to add a *_VERSION file in the Rails codebase. This method is currently used for Gitaly, KAS, Pages, Shell, Zoekt, OpenBao, among others.
This version file is updated using various methods: The file is updated manually for OpenBao, using Renovate Bot for Zoekt, and using release tooling for components under Managed Versioning (Gitaly and KAS).
We expect the rapid addition of 10s of new modular components, which will be built and released from their own repository using the Release Framework. In this scenario, it will no longer be practical to introduce and maintain a *_VERSION file in the Rails codebase for each new modular component. Release manifest proposes the simplification of version management by building on the standardization provided by the Release Framework.
Proposed Solution
The release manifest will take a snapshot of the compatible versions for each modular component whenever a GitLab release is published, and store this in a machine-readable format for other tools to consume. It will provide a mapping from a given GitLab version to compatible versions for all modular components that work with that version of GitLab.
flowchart LR
MCR[Modular Component - Release published] -->|Component entry updated in the Mutable catalog| RMMut[(Mutable Catalog)]
GRS[GitLab Release Schedule] -->|GitLab monthly or weekly scheduled release published| GRP[GitLab Release Published]
GRP ==> |Release manifest frozen for the current milestone| RMMut
GRP ==> |Release manifest initialized for the next milestone| RMMut
subgraph RM[Release Manifest]
direction TD
RMMut
RMMut ==>|Release manifest frozen for the current milestone| RMImmut[(Immutable Record)]
RMImmut
end
linkStyle 2 stroke:red
linkStyle 3 stroke:blue
linkStyle 4 stroke:red
It will contain two pieces:
- Mutable Catalog of compatible versions for the future GitLab releases: This catalog will be updated automatically using CI jobs inside Release Framework, requiring no intervention from the teams developing the modular component. Release framework requires components to follow semantic versioning, so all release framework components will be included in the Mutable catalog by default.
- Immutable Record of compatible versions for past GitLab releases: When a GitLab release is published to users, the catalog entry for that release will be copied to an immutable store. This will serve as a reference for all tooling that intends to install this version at any point in time.
Data Model
Mutable Catalog
The release manifest entry for artifact-registry for the upcoming GitLab release 19.5.0 will live inside the file 19/5/0/artifact-registry.json. The string artifact-registry is the module’s ID within the Release Framework; we use that as an identifier in the release manifest.
The entry’s content will be in this format:
{
"version": "1.275.1",
"sha": "6cdaf83c809b7d02c794d5db2dea9e101c662ac7",
"ref": "v1.275.1",
"source": {
"url": "https://gitlab.com/gitlab-org/ops/artifact-registry"
}
}
Similarly, the entry for knowledge-graph (GitLab Orbit) will be in the file 19/5/0/knowledge-graph.json and have this content:
{
"version": "0.95.3",
"sha": "51aab3662a8764f47616acefdff8163312bd2bc6",
"ref": "v0.95.3",
"source": {
"url": "https://gitlab.com/gitlab-org/orbit/knowledge-graph"
}
}
Such entries will exist for all components which are being managed using the Release Framework.
The mutable catalog will be updated only once a version of the modular component is published to users. This allows the modular component team to control when their component version will be included in the overarching GitLab version.
Immutable Record
Once the release 19.5.0 is published to users, we will combine the version information for multiple components into a single file 19/5/0.json. This file’s content will follow this format:
{
"version": "19.5.0",
"modules": {
"artifact-registry": {
"version": "1.275.1",
"sha": "6cdaf83c809b7d02c794d5db2dea9e101c662ac7",
"ref": "v1.275.1",
"source": {
"url": "https://gitlab.com/gitlab-org/ops/artifact-registry"
}
},
"knowledge-graph": {
"version": "0.95.3",
"sha": "51aab3662a8764f47616acefdff8163312bd2bc6",
"ref": "v0.95.3",
"source": {
"url": "https://gitlab.com/gitlab-org/orbit/knowledge-graph"
}
}
}
}
Storage
The release manifest lives in three dedicated projects under gitlab-org/release/manifests. Module authors and consumers start here.
| Project | Contents | Visibility |
|---|---|---|
manifests/unreleased |
Mutable catalog. One file per component, at {major}/{minor}/{patch}/{module-id}.json |
Private. Internal consumers ask the Delivery: Release and Deploy team for a group share with the Reporter role |
manifests/released |
Immutable record. One file per published GitLab release, at {major}/{minor}/{patch}.json |
Public |
manifests/schema |
The JSON Schema that both tiers validate against | Public |
Nobody pushes to main in either data project directly: the push allow-list on main holds only the release automation bots. A human change has to go through a merge request, where the CI checks gate it. Both projects validate every file against the schema. The record project also fails any merge request that changes a record file which already exists, enforcing the “immutable once published” goal (see Goals) by mechanism rather than by convention. A deliberate corrective change is still possible: it needs the record-change-approved label, and the job then passes and posts an audit comment naming the changed files.
How Entries Are Written
Two separate events write to the release manifest, and each one writes to a different project.
A module publishes a version. release-tools adds that module’s entry to the mutable catalog, for each GitLab version that is still upcoming. The write does not wait for a GitLab release, and it does not touch any other module. This keeps the module release cycle independent of the GitLab release schedule (see Goals).
A GitLab version publishes. release-tools freezes the catalog entries for that version into one file in the immutable record, then carries the same entries forward into the catalog for the next versions. The frozen file is the answer for that GitLab version from then on, and it never changes.
Carrying entries forward keeps the last published version of a module in the catalog until the module publishes again. A module that releases rarely still appears in later records, and a module that publishes during the cycle replaces the entry.
Related Documents
- GitLab R&D Summit 2026 - Release Manifest Demo (GitLab Delivery) - Google Slides
- Repositories and content used during the demo, replaced by the production projects in Storage
- Implementation details and component changes
06c65b44)
