Releases, Tags, Release CLI, Evidence, Changelogs, and Deployment Traceability: Concepts, Architecture, and Mental Model
Model a production release as a chain from Git commit and tag through GitLab Release metadata, assets, changelog, release evidence, immutable artifact/image identities, and deployment records.
Learning objectives
- Separate a Git tag/ref from the GitLab Release object layered on that tag.
- Trace source commit → tag → Release → asset/package/image digest → deployment evidence.
- Explain automatic release evidence and its tier-specific extensions without treating evidence as a security attestation.
- Choose current glab/API automation rather than deprecated release-cli.
- Use generated changelogs as structured release input while preserving human review.
glab release delete documentation requires
Maintainer-or-higher, so the fully scripted glab cleanup path is
Maintainer-scoped; Developer-level learners can use the documented
UI/Releases API path where permitted or simulate cleanup. On-demand
evidence recollection is Premium/Ultimate and limited to
Self-Managed/Dedicated; retaining report artifacts as release evidence
is Ultimate. release-cli was deprecated in GitLab 18.0
and is scheduled for removal in 20.0; use glab or the
Releases API for new automation. The mandatory labs use only a
disposable project/tag, synthetic asset links or package/image
coordinates, and no paid feature.
1. The practical problem: a release name is not enough
Chapters 22 and 23 gave packages and OCI images durable coordinates
and digests. A production release must now connect those objects
back to the exact source and delivery event. “Version 2.4.0 shipped”
is weak evidence unless an operator can answer: which commit did
v2.4.0 name, which pipeline built the deliverables,
which immutable package or image digest was distributed, what
Release metadata described it, and which deployment consumed that
identity?
Git provides commit and tag objects. GitLab adds a hosted Release object, release notes, assets/links, evidence snapshots, API/CLI automation, and relationships to milestones and deployment activity. Do not collapse these layers into one abstraction.
2. Git tag versus GitLab Release object
| Layer | Object | Identity / mutation | Operational meaning |
|---|---|---|---|
| Git | Commit | Content-addressed commit SHA; immutable object. | Source state. |
| Git | Lightweight tag | Ref name pointing at an object; tag ref can be deleted/recreated if policy permits. | Human version selector. No tag message object. |
| Git | Annotated tag | Tag object with message/tagger that points to another object. | Version selector plus Git-native annotation. |
| GitLab | Release | Hosted metadata associated with a tag: name, notes, date, assets, links, evidence. | Product-facing release record. |
| Package/OCI | Package version / image digest | Registry identity; digest/hash is stronger than mutable names/links. | Binary/content actually consumed. |
| GitLab environment | Deployment | Record linking job/commit/environment/status. | What GitLab believes was deployed. |
A Release is not a second Git commit and it is not the binary itself. It is metadata anchored to a tag. Deleting a Release leaves the tag; deleting the tag associated with a Release removes the Release too.
3. Mental model: release as a chain of independently verifiable identities
flowchart TD C[Commit SHA] --> T[Git tag vX.Y.Z] T --> R[GitLab Release] P[Pipeline / job] --> A[Package hash or OCI digest] A --> R R --> V[Release evidence JSON] A --> D[Deployment / environment] C --> P D --> O[Operational rollback record]
The tag connects release metadata to source. The pipeline connects source to produced content. A package checksum or OCI digest names the deliverable. A deployment record should resolve to the same source/artifact identity. Release evidence snapshots surrounding metadata, but it does not replace independent artifact verification.
4. Read-only inspection before release mutation
Before creating or editing a release, prove current state from at least two surfaces:
git fetch --tags --prune
git status --short
git rev-parse HEAD
git tag --list "v*" --sort=-version:refname | head -n 10
glab release list -F json --per-page 20
# Inspect a known release without editing it:
glab release view v1.2.3 -F json
For machine-readable API evidence, use
GET /projects/:id/releases and
GET /projects/:id/releases/:tag_name. Record project,
tag, Release creation/release timestamps, returned commit SHA, asset
links, and evidence file path. Never infer a binary digest merely
because it is linked from a release.
5. Current automation interfaces: glab, release keyword, REST API
For new automation, prefer glab, the CI
release keyword, or the Releases API.
release-cli is deprecated since GitLab 18.0 and
scheduled for removal in 20.0.
release_job:
stage: release
image: registry.gitlab.com/gitlab-org/cli:latest
rules:
- if: $CI_COMMIT_TAG
variables:
GLAB_ENABLE_CI_AUTOLOGIN: "true"
script:
- echo "Release metadata will be created after this job script succeeds."
release:
tag_name: $CI_COMMIT_TAG
name: "Release $CI_COMMIT_TAG"
description: "CHANGELOG.md"
Authentication nuance: for CI job-token auto-login,
set GLAB_ENABLE_CI_AUTOLOGIN=true. Do not set
GITLAB_TOKEN=$CI_JOB_TOKEN; glab sends
GITLAB_TOKEN as a private-token header, which the
Releases API does not accept as a job token and can result in
404 Not Found.
6. Assets are references; durability depends on the target
A Release includes automatically generated source archives plus optional asset links. An asset link has a display name and URL; it can point to a Generic Package, container/package download, documentation, runbook, or other durable service. The Release does not magically copy the referenced bytes unless your chosen workflow explicitly uploads them somewhere durable.
| Asset pattern | Strength | Risk / recommendation |
|---|---|---|
| Generic Package version | Project-scoped version + file checksum metadata. | Good release-asset backend; verify exact version/hash. |
| OCI image digest | Content-addressed manifest identity. | Excellent deployment coordinate; link/report digest explicitly. |
| Job artifact URL | Easy to generate. | Usually ephemeral; expiry or manual deletion can break release links. |
| External HTTPS URL | Can point anywhere. | Treat mutable URL as indirection; preserve checksum/digest/provenance separately. |
| Source archive auto-link | Derived from repository tag. | Useful for source distribution; not a compiled binary identity. |
7. Release evidence: audit snapshot, not cryptographic trust
When a release is created, GitLab creates release-evidence JSON automatically on Free/Premium/Ultimate across all offerings. The snapshot can include release metadata and related records; matching packages may be included when package versions match the release tag convention. Current tier-specific extensions matter:
- Automatic snapshot: Free-compatible.
- Collect another evidence snapshot on demand: Premium/Ultimate, Self-Managed/Dedicated.
- Preserve report artifacts as release evidence: Ultimate.
The evidence SHA identifies the evidence snapshot. It does not assert that a package/image is vulnerability-free, signed by a trusted key, reproducibly built, or safe to deploy. Those are separate controls/evidence sources.
8. Changelog generation: structured commit data, not automatic editorial judgment
GitLab changelog generation selects commits using a configured Git
trailer, by default Changelog, and emits Markdown. The
default values such as added, fixed,
changed, deprecated, removed,
security, performance, and
other give maintainers a useful taxonomy.
git commit -m "Harden release verification
Changelog: security"
glab changelog generate --version 1.2.0 --from <old_sha> --to <new_sha> > release-notes.md
Generated notes are evidence of selected commit metadata, not a substitute for human explanation of breaking changes, migration steps, compatibility, or known limitations.
9. Tags are release governance, not decoration
Because release metadata is anchored to tags, tag creation/deletion policy is part of release governance. Protected tags are Free across all offerings and can restrict who may create matching release tags. Maintainers/Owners configure the rules; deleting a protected tag requires GitLab UI/API and appropriate permission.
A particularly dangerous failure is deleting and recreating a release tag after consumers have cached or deployed the earlier ref. The same tag text can then name a different commit. Preserve the original incident evidence, restore by a new version/tag when possible, and use protected-tag policy to reduce this class of mutation.
10. Traceability invariant
A production release record is strong when the following invariant is independently checkable:
tag_commit_sha == release.commit.id == build_source_sha
release_asset_hash_or_digest == deployed_artifact_hash_or_digest
deployment.commit_sha == intended_release_commit_sha
Not every GitLab object stores every equality directly, so operators collect the chain from Git, Release API, package/container metadata, pipeline/job evidence, and environment/deployment records.
11. DevOps connection
Release governance reduces two forms of pressure: ambiguity (“which binary is this?”) and ceremony (“we have a release page, so we must be compliant”). The goal is a small, automatable chain of durable identities and explicit permissions. That chain supports rollback, incident response, audit, customer distribution, and later security policy without making the Release page the single source of truth for everything.
Knowledge check
Does a GitLab Release create a new Git commit?
No. A Release is hosted metadata associated with a Git tag; the source identity remains the underlying Git commit/tag.
Which deletion leaves the other object intact: deleting the Release or deleting the tag?
Deleting the Release leaves its Git tag. Deleting the Git tag associated with a Release also removes the Release.
Why is an OCI digest stronger release evidence than the tag
latest?
The digest identifies exact manifest content;
latest is a mutable name that can point elsewhere
later.
Why should new CI automation avoid
release-cli?
It is deprecated since GitLab 18.0 and scheduled for removal in
20.0; use glab/the Releases API/current release
keyword path.
Does release evidence prove the linked artifact is secure?
No. It is an audit snapshot of release-related data. Security, provenance, signatures, scans, and immutable artifact identity must be verified separately.
Summary
Git commits and tags provide source identity; GitLab Releases provide hosted metadata; package hashes/OCI digests provide deliverable identity; deployment records provide operational state; release evidence and changelogs add audit/context. A trustworthy release ties these layers together without pretending any one layer proves all the others.
Official references
Primary sources used for the current GitLab 19.3 behavior taught in this lesson:
- GitLab Docs — Releases
- GitLab Docs — Project releases API
- GitLab Docs — Release links API
- GitLab Docs — Release evidence
- GitLab Docs — Release fields and assets
- GitLab Docs — release-cli (deprecated)
- GitLab CI/CD YAML — release keyword
- GitLab CLI — release
- GitLab CLI — release create
- GitLab CLI — release view
- GitLab CLI — release list
- GitLab Docs — Changelogs
- GitLab CLI — changelog generate
- GitLab Docs — Repositories API changelog endpoints
- GitLab Docs — Protected tags
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.