Release Lifecycle
Complete guide to release creation, change tracking, approval workflow, deployment execution, and diff-driven confidence.
What Is a Release
A release is a versioned, auditable set of configuration changes that moves through a governed workflow: creation → approval → deployment. Releases are the central change management primitive in GitOpsHQ — every modification to your delivery state (workloads, bindings, variables, policies) flows through a release before it reaches a cluster.
Releases serve three purposes:
- Review gate — Approvers see exactly what will change before it deploys.
- Audit record — Every release captures who changed what, who approved it, and when it deployed.
- Rollback anchor — Each deployed release creates a point-in-time snapshot you can roll back to.
GitOps Principle
Releases bridge the gap between "desired state changed in the UI" and "manifests committed to Git." Nothing reaches your cluster without going through a release. The client supplies a policySnapshotJson at creation time; OPA policies are not re-evaluated server-side during release creation.
Release State Machine
Every release follows a well-defined state machine. The primary path is linear, but alternative paths handle cancellation, rejection, rollback, and failure. Rejection is not a separate state — rejecting a release transitions it to cancelled with a rejection reason.
State Descriptions
| State | Description | Allowed Actions |
|---|---|---|
draft | Release created in a non-gated environment, changes captured. Not yet submitted for review. | Edit, submit for approval, cancel |
pending_approval | Waiting for required approvals per environment policy. In approval-gated environments, releases are created directly in this state. | Approve, reject, cancel |
approved | All approval requirements met. Ready to deploy. | Deploy, cancel |
deploying | Delivery generator is rendering manifests and committing to Git. | Monitor (no user action) |
deployed | Manifests committed to the hosted Git repository. ArgoCD/Flux syncs to cluster. | View, promote to next environment, rollback |
failed | Deployment failed (generation error, Git conflict, etc.). | View error, recreate from draft |
rolled_back | A previously deployed release was rolled back. The cluster reverts to the prior release state. | View only |
cancelled | Release cancelled by the author or rejected by an approver. Rejection is a specific reason for cancellation. Preserved for audit. | View only |
Change Types
A release tracks every type of configuration change that affects delivery output:
| Change Type | Description | Example |
|---|---|---|
| Workload changes | New workloads added, existing workloads updated, image tags changed | api-gateway image tag v1.2.3 → v1.3.0 |
| Kustomize binding changes | Kustomize overlays added, removed, or modified | New patch overlay for production namespace labels |
| Manifest binding changes | Raw manifest bindings added or modified | Updated ConfigMap for feature flags |
| HQ Variable changes | Variables created, updated, or deleted at any scope | REPLICA_COUNT changed from 3 to 5 at environment scope |
| Environment policy changes | Approval requirements, freeze state, or deploy mode changed | Production environment now requires 2 approvals |
Each change type is tagged in the release summary, so reviewers can quickly understand the scope and nature of the release.
Creating a Release
Releases are created from the Release panel within a project's tenant-environment context.
Navigate to the tenant-environment. Open your project, select the target tenant and environment. The pending changes indicator shows how many uncommitted changes exist.
Review pending changes. Click "Create Release" to open the release creation dialog. All pending changes since the last release are listed, grouped by change type.
Select changes (optional). By default, all pending changes are included. For partial releases, deselect changes you want to defer to a later release.
Add release notes. Provide a description explaining the purpose of this release. Good release notes help approvers make faster decisions.
Submit. If the target environment has an approval policy, the release is created directly in pending_approval state and approvers are notified. If the environment is non-gated (no approval required), the release is created in draft state.
Partial Releases
Partial release support lets you ship urgent changes (e.g., a hotfix image tag) without waiting for unrelated changes (e.g., a new workload configuration) to be reviewed.
Diff Views
Releases provide three levels of diff to give reviewers full confidence in what will change:
Plain diff shows the raw line-by-line text comparison of values files before and after the release changes. This is the closest view to "what the author changed." It supports side-by-side or unified view, syntax-highlighted YAML, with added, removed, and modified lines clearly marked.
Resolved diff shows the values files after HQ Variable resolution. This answers the question "what will the delivery generator actually use?" All {{hq.var.VARIABLE_NAME}} placeholders are replaced with their effective values. This is useful for catching cases where a variable change at a broad scope unintentionally affects this release. It compares the previous resolved state vs. the new resolved state.
Manifest diff shows the rendered Kubernetes manifests that will be committed to Git. This is the final output after Helm template rendering or Kustomize build. It shows full Kubernetes resource YAML with differences in labels, annotations, resource specs, and container configurations. Most useful for catching template-level bugs (e.g., a Helm conditional that doesn't fire as expected).
Diff Viewer Features
The diff viewer supports:
| Feature | Description |
|---|---|
| Side-by-side | Two-column layout for easy comparison |
| Unified | Single-column layout for compact viewing |
| Syntax highlighting | YAML/JSON aware highlighting |
| Collapse unchanged | Hide unchanged sections to focus on changes |
| Line linking | Share a link to a specific line in the diff |
Approval Workflow
Releases follow the approval policies configured on the target environment. The approval system is designed for both routine reviews and high-stakes production deployments.
Approval Flow
Approval Policies
| Policy Setting | Description |
|---|---|
| Required approvals | Number of approvals needed (quorum). Example: 2 means at least 2 different approvers must approve. |
| Self-approval blocking | When enabled, the release author cannot be an approver (configurable per environment). |
| Approval expiry | Approvals can be configured to expire after N hours, requiring re-approval for stale releases. |
| Auto-approve | Environments can be configured to auto-approve releases, useful for development environments. |
What Approvers See
Approvers receive the full context needed for informed decisions:
- Change summary — Count and types of changes
- All three diff views — Plain, resolved, and manifest
- Release notes — Author's description of the change purpose
- Author identity — Who created the release
- Environment context — Which tenant-environment this targets
- Policy status — Current approval count vs. required quorum
Stale Source Protection
Stale source protection prevents deploying outdated changes when the underlying source has moved forward.
How it works:
- When a release is created, it captures the current source commit SHA as its baseline.
- If new changes are introduced to the delivery source (e.g., a new workload update, a variable change) after the release is created, the release is marked as stale.
- A stale release cannot be deployed. The UI displays a clear warning with the
stale_release_sourceindicator. - The author must either refresh the release (re-snapshot from current source) or recreate it.
Why Stale Protection Matters
Without stale protection, deploying an older release could silently revert newer changes that were made after the release was created. Stale detection prevents accidental rollbacks disguised as forward deployments.
Deployment Execution
Once a release is approved (or auto-approved), deployment can be triggered.
Trigger deploy. Click the "Deploy" button on the approved release. The release transitions to deploying.
Delivery generation. The delivery generator renders final manifests by combining Helm charts / Kustomize overlays with resolved HQ Variables.
Git commit. Rendered manifests are committed to the hosted Git repository with full metadata (release ID, author, approvers, timestamp).
Sync. ArgoCD or Flux detects the new commit and syncs the manifests to the target cluster.
Status update. The release transitions to deployed once the Git commit succeeds. Cluster sync status is tracked separately via the agent.
Deployment Failure
If deployment fails (e.g., template rendering error, Git conflict), the release transitions to failed. The error details are captured and displayed:
| Failure Type | Description | Resolution |
|---|---|---|
| Template error | Helm template or Kustomize build fails | Fix the template, recreate the release |
| Variable unresolved | A {{hq.var.X}} placeholder has no matching variable | Define the missing variable, recreate the release |
| Git conflict | Concurrent commit conflict in the hosted repository | Retry deployment (auto-resolved on retry) |
| Agent unreachable | Git commit succeeds but agent cannot confirm sync | Wait for agent reconnection; commit is safe in Git |
Release in the Approvals Inbox
Releases requiring approval appear in the unified Approvals page (/approvals) alongside other approval requests (cluster commands, promotion requests). The approvals inbox provides:
- Filterable list of all pending approvals across projects
- Release summary with change count and target environment
- Quick-action approve/reject buttons (reject transitions the release to
cancelled) - Link to full release detail with diff views
Cancel and Cleanup
Releases can be cancelled at any stage before deployment:
| Current State | Cancel Behavior |
|---|---|
draft | Immediately cancelled. Pending changes return to the uncommitted pool. |
pending_approval | Cancelled. Any existing approvals are voided. Approvers are notified. |
approved | Cancelled. The release is preserved in history but will not deploy. |
Cancelled releases are never deleted. They remain in the release history for audit purposes, marked with the cancelled state and a timestamp.
RBAC and Permissions
Release operations are governed by distinct permissions to enforce separation of duties:
| Permission | Allows |
|---|---|
releases.create | Create new releases and submit for approval |
releases.approve | Approve or reject releases (subject to self-approval policy) |
releases.deploy | Trigger deployment of approved releases |
releases.cancel | Cancel releases at any stage |
releases.view | View release history, diffs, and status |
Separation of Duties
In regulated environments, configure self-approval blocking and separate create / approve / deploy permissions across different team members. This ensures no single person can push a change to production without oversight.
Error Reference
| Error Code | Message | Meaning |
|---|---|---|
400 | release cannot be deployed in its current status | Only approved releases can be deployed |
403 | release requester cannot deploy approved release | Self-deploy restriction is active on this environment |
409 | release does not meet approval threshold: {current}/{required} | Not enough approvals to transition to approved |
409 | code: stale_release_source | Source has changed since release creation — refresh or recreate |
423 | environment is frozen | The target environment is frozen — no deploys allowed |
Best Practices
- Write meaningful release notes. They help approvers understand intent, not just mechanics.
- Use partial releases for urgency. Ship the hotfix now, review the rest in a subsequent release.
- Check all three diff views. Plain diff shows intent, resolved diff shows variable effects, manifest diff shows final output.
- Monitor stale warnings. If releases frequently go stale, your team may benefit from smaller, more frequent releases.
- Use auto-approve for dev environments. Speed up the inner dev loop by removing manual approval gates for non-production environments.
- Keep approver pools fresh. Ensure enough team members have
releases.approvepermission to avoid bottlenecks.