Release Management SOP
Standard Operating Procedure for releasing Rossoctl, aligned with CNCF project conventions (Kubernetes, Helm, ArgoCD).
Related: docs/releasing.md contains the procedural step-by-step instructions. This document covers policy and governance.
1. Branching Strategy
| Branch | Purpose | Lifetime |
|---|---|---|
main | Active development; all features merge here | Permanent |
release-X.Y | Stabilization and patches for a minor series | Permanent once created |
Rules
mainis always releasable. CI must pass; broken builds are P0.- Release branches are cut at RC time, not before. Alpha releases tag directly from
main. - No direct commits to release branches. All fixes land on
mainfirst and are cherry-picked back (exceptions: release-only metadata changes like version bumps). - One active release branch per minor version. Example:
release-0.6coversv0.6.0-rc.1through allv0.6.Zpatches.
When to Create a Release Branch
main ─────●────●────●────●────●────●─── (development continues)
│
└─── release-0.6 ─── rc.1 ─── rc.2 ─── v0.6.0 ─── v0.6.1
Create release-X.Y when cutting the first RC:
git checkout -b release-X.Y main
git push origin release-X.Y
2. Pre-release Lifecycle
2.1 Alpha Releases
Purpose: Milestone snapshots for early testing. May break between releases.
Naming: vX.Y.0-alpha.N (e.g., v0.7.0-alpha.1, v0.7.0-alpha.2)
Criteria to tag:
- CI passes on
main - No known data-loss or security issues in the tagged commit
- All image tags in
values.yamlpinned (nolatest)
Cadence: As needed during active development (typically every 1-2 weeks during a cycle).
Process:
# Determine next alpha number
git tag --list 'vX.Y.0-alpha.*' --sort=-v:refname | head -1
# Tag (follow multi-repo dependency order - see Section 6)
git tag -s vX.Y.0-alpha.N -m "vX.Y.0-alpha.N"
git push origin vX.Y.0-alpha.N
2.2 Release Candidates
Purpose: Feature-complete builds for validation. Code freeze in effect.
Naming: vX.Y.0-rc.N (e.g., v0.7.0-rc.1, v0.7.0-rc.2)
Code freeze rules:
- Only bug fixes, test fixes, and documentation changes are allowed.
- No new features, refactors, or dependency upgrades (unless fixing a security issue).
- All changes go through the normal PR process targeting the release branch.
Entry criteria:
- All planned features for the milestone are merged to
main - No open P0/P1 bugs against the milestone
- Feature freeze declared on Slack/mailing list
- Release branch created from
main - All image tags pinned to RC version
Progression:
- If bugs are found during RC testing, fix on
main, cherry-pick to release branch, bump torc.N+1. - Maximum 3 RCs recommended. If more are needed, re-evaluate scope.
3. Stable (GA) Releases
Naming: vX.Y.0 (first GA of a minor series), vX.Y.Z (patches)
Promotion criteria:
- At least 1 RC validated with no release-blocking issues
- Minimum 1-week soak since last RC (recommended)
- At least one maintainer sign-off (not the person who tagged the RC)
- E2E tests pass on Kind and OpenShift
- Upgrade path from previous GA tested
- Release notes written and reviewed
Process:
# On the release branch
git checkout release-X.Y
# Verify the RC tag is the HEAD (or contains only release metadata commits)
git log --oneline release-X.Y...vX.Y.0-rc.N # should be empty or trivial
# Tag GA
git tag -s vX.Y.0 -m "vX.Y.0"
git push origin vX.Y.0
Post-release:
- Mark GitHub Release as "Latest"
- Announce on Slack and mailing list
- Update installation docs with new version
4. Maintenance and Patching
4.1 Cherry-Pick Workflow
All fixes land on main first. To backport to a release branch:
# 1. Identify the commit(s) to cherry-pick
git log --oneline main | grep "<fix description>"
# 2. Cherry-pick onto release branch
git checkout release-X.Y
git cherry-pick -x <commit-sha> # -x adds "cherry picked from" reference
# 3. Resolve conflicts if any, then push
git push origin release-X.Y
# 4. Tag the patch
git tag -s vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z
The -x flag is mandatory — it creates traceability between main and the backport.
4.2 Security Patches vs. Bug Fixes
| Aspect | Security Patch | Bug Fix |
|---|---|---|
| Timeline | ASAP (24-72h target) | Next patch window |
| Disclosure | Private fix, coordinated disclosure | Public PR on main |
| RC required? | No (direct to patch tag) | Recommended for non-trivial fixes |
| Backport scope | All supported release branches | Latest release branch only (unless critical) |
| Communication | Security advisory + CVE | Release notes |
Security patch process:
- Fix developed in a private fork or restricted branch
- Patch applied to all supported release branches simultaneously
- Tags pushed for all affected versions
- GitHub Security Advisory published
- Announce on mailing list with CVE reference
4.3 Support Window
| Policy | Scope |
|---|---|
| Active support | Current GA (N) — bug fixes and security patches |
| Security-only | Previous GA (N-1) — security patches only |
| End of life | N-2 and older — no further releases |
5. Multi-Repo Dependency Order
Rossoctl spans multiple repositories. Tags must be created in dependency order:
1. rossoctl/operator → tag, wait for CI
2. rossoctl/cortex → tag, wait for CI
3. rossoctl/rossoctl → update Chart.yaml + values.yaml, tag
Between each step: Verify container images and Helm charts are published before proceeding to the next repository.
6. Automation and Tooling
Release image pinning
Installers use local charts from the repo checkout — they do NOT pull from OCI.
Therefore image tags must be pinned in the committed values.yaml files before
tagging.
Pin all images in one command:
bash scripts/pin-release-tags.sh v0.6.0-rc.6
This updates tags across both charts/rossoctl/values.yaml and
charts/rossoctl-deps/values.yaml. See docs/releasing.md — Pinning Image
Tags for details.
Validate before tagging:
bash scripts/check-release-pins.sh
This validates both charts for tag: latest entries and detects tag drift
between rossoctl-deps and the main platform chart.
Currently Automated (via existing build.yaml workflows)
| Step | Trigger | Output |
|---|---|---|
| Container image build + push | Tag push (v*) | Images on ghcr.io/rossoctl/ |
| Helm chart package + push (with tag pinning) | Tag push (v*) | OCI charts on ghcr.io/rossoctl/ |
| GitHub Release creation | Tag push (v*) | Release with auto-generated changelog |
| Pre-release flag | GoReleaser prerelease: auto | -alpha/-rc tags marked as pre-release |
Pin validation (ci-release-pins.yaml) | PR touching charts/ | Summary on all PRs; hard gate on release/* branches |
Recommended Additions
| Automation | Trigger | Purpose | Priority |
|---|---|---|---|
| Release branch protection | Branch creation matching release-* | Enforce PR reviews, required CI, no force push | P0 |
| Changelog generation | Tag push | Generate structured changelog from conventional commits (e.g., git-cliff) | P1 |
| Cross-repo orchestration | Manual workflow dispatch | Trigger dependency-ordered release across repos | P2 |
| Cosign image signing | After image push | Sign images with Sigstore keyless signing | P2 |
| SBOM generation | Tag push | Produce CycloneDX SBOM per image | P3 |
7. Release Checklist (Quick Reference)
Alpha
- CI green on
main - Tag dependency repos in order (operator → extensions)
- Verify images/charts published for each
- Update
Chart.yaml+values.yamlinrossoctl/rossoctl - Pin all image tags (no
latest) - Run
helm dependency update charts/rossoctl/ - Tag
rossoctl/rossoctl - Verify GitHub Release is Pre-release
RC
- Feature freeze announced
- All alpha checklist items
- Release branch
release-X.Ycreated - E2E tests pass
- Testing checklist added to release notes
GA
- All RC checklist items
- 1-week soak since last RC
- Maintainer sign-off
- Upgrade from previous GA tested
- Full release notes with component version table
- Announcement drafted
Patch
- Fix merged to
mainwith tests - Cherry-picked to
release-X.Ywith-xflag - CI passes on release branch
- Tag
vX.Y.Z - Release notes describe the fix
8. Tooling
| Tool | Role |
|---|---|
/release skill | Interactive AI-assisted release workflow |
gh CLI | Tag management, release creation, CI status |
| GoReleaser | Builds binaries, manages GitHub Releases |
| Helm | Chart packaging and OCI registry push |
git-cliff (proposed) | Conventional-commit changelog generation |
| Cosign (proposed) | Image signature verification |