| name | flux-controller-minor-releases |
| description | Run the upstream Flux controller minor release procedure for helm-controller, image-automation-controller, image-reflector-controller, kustomize-controller, notification-controller, source-controller, and source-watcher. Use when cutting a new controller minor release (vX.Y.0): creating the release series branch, drafting the minor changelog, tagging, merging the release branch back to main, and adding the backport label.
|
| license | Apache-2.0 |
Flux Controller Minor Releases
Use this skill for upstream Flux controller minor releases (vX.Y.0) only —
the release that opens a new release/vX.Y.x series. Do not use it for flux2,
pkg, or other non-controller repos.
Supported controllers:
helm-controller
image-automation-controller
image-reflector-controller
kustomize-controller
notification-controller
source-controller
source-watcher
Important rules
Preconditions
- Read the upstream procedure at
website/content/en/flux/releases/procedure.md,
section Controllers: minor releases
(https://fluxcd.io/flux/releases/procedure/#controllers-minor-releases).
- Identify the flux2 minor-release tracking issue so PR bodies can reference it
(
Part of: https://github.com/fluxcd/flux2/issues/NNNN).
- Use
date to get the release date for the changelog entry.
git fetch --all --tags --prune before reasoning about branches, tags, or
merged PRs. Do not trust stale local origin/* refs.
- Treat
git and gh commands as confirmation points if the user wants that.
Release Flow
For the controller being released (target version vX.Y.0):
-
Create the release series branch from main and push it.
git switch -c release/vX.Y.x main
git push origin release/vX.Y.x
-
Create the release preparation branch from the series branch.
git switch -c release-vX.Y.0 release/vX.Y.x
-
Draft the new CHANGELOG.md entry (see "How To Build The Changelog Entry").
Then commit it.
git add CHANGELOG.md
git commit -s -m "Add changelog entry for vX.Y.0"
-
Apply the release version bump exactly as documented.
- Update the controller self-API version in the root
go.mod to vX.Y.0.
Inspect the actual go.mod; do not assume the self-API path form
(source-watcher uses github.com/fluxcd/source-watcher/api/v2).
- Update
config/manager/kustomization.yaml newTag to vX.Y.0.
git add go.mod config/manager/kustomization.yaml
git commit -s -m "Release vX.Y.0"
-
Push the release preparation branch.
git push origin release-vX.Y.0
-
Open and merge the release PR into the release series branch.
- Base:
release/vX.Y.x Head: release-vX.Y.0
- Title
Release vX.Y.0, body Part of: <tracking issue URL>.
- Merge when CI is green and a maintainer has approved.
-
Refresh the release series branch after the merge.
git switch release/vX.Y.x
git pull origin release/vX.Y.x
- Confirm both version refs are
vX.Y.0 on the merged commit before tagging.
-
Create and push signed tags from the updated release series branch. Push the
api/ tag first — the release tag depends on it.
git tag -s -m "api/vX.Y.0" api/vX.Y.0
git push origin api/vX.Y.0
git tag -s -m "vX.Y.0" vX.Y.0
git push origin vX.Y.0
-
Verify the release workflow triggered by the vX.Y.0 tag. Watch it in the
background until it concludes successfully (images published + signed, SBOM,
SLSA provenance, GitHub release created).
-
Merge the release series branch into main via PR. This merges the whole
branch (changelog + version bump), not a cherry-pick.
- Base:
main Head: release/vX.Y.x
- Leave the title at the GitHub default — the humanized branch name
Release/vX.Y.x. Body Part of: <tracking issue URL>.
- Merge when CI is green and approved.
-
Last: open the backport label PR against main. Do this only after
step 10 has merged.
How To Build The Changelog Entry
A minor changelog entry summarizes what is new in vX.Y.0 relative to the whole
vX.(Y-1) line — not every commit since the previous minor. The hard part is
selecting exactly the right PRs.
Selecting the PRs (do this rigorously — do not infer from commit messages)
- Establish the candidate set: PRs merged to
main since the previous minor
(v(X).(Y-1).0).
- From merge commits:
git log --merges --grep="Merge pull request" v(X).(Y-1).0..release/vX.Y.x
and extract the #NNNN.
- Cross-check against
gh so squash/rebase merges are not missed:
gh pr list --base main --state merged --limit 200 --json number,mergedAt,title
filtered to merges after the previous minor's release timestamp.
- Verify every candidate PR via
gh pr view <n> -R fluxcd/<repo> --json number,baseRefName,state,mergedAt,title.
Keep only PRs that are MERGED and have baseRefName == main. Use the PR
title from GitHub, never the local merge-commit subject (these drift; e.g. a
commit may say one thing while the PR title says another).
- Exclude PRs already shipped in a patch release of the previous minor
(anything
> v(X).(Y-1).0 and < vX.Y.0). Read the ## (X).(Y-1).Z patch
sections already in CHANGELOG.md and drop any candidate whose change shipped
there. Note the patch changelogs cite the cherry-pick PR numbers
(against release/v(X).(Y-1).x), which differ from the original main PR
numbers — match by change, not by number.
- Exclude release mechanics PRs: changelog cherry-pick/"Add changelog entry"
PRs, the previous release's
Release/v(X).(Y-1).x merge-back, and label PRs.
- Collapse routine dependency bumps (fluxcd/pkg, CI actions, k8s/Go bumps whose
content already shipped in a patch) into a single
Various dependency updates
bullet listing each PR link. Keep genuinely user-facing items as their own
bullets. See "Dependency update PRs" below before settling for a generic line.
Writing the entry
Write the new section at the top of CHANGELOG.md, matching the existing minor
entries in that repo:
## X.Y.0
**Release date:** YYYY-MM-DD (from date)
- A one–two sentence intro naming the headline theme.
- Optional
⚠️ upgrade warnings (API removals, required flux migrate, etc.).
When warning about a deprecated/beta API removal, link the upgrade instruction
to the canonical flux2 upgrade-procedure discussion
(https://github.com/fluxcd/flux2/discussions/5572), not to a one-off
flux migrate PR — the discussion is the maintained guide covering both the
Flux CLI and Flux Operator migration paths. Older changelog entries may still
point at a migrate PR; do not copy that, use the discussion link.
- Per-API subsections (
### GitRepository, ### OCIRepository,
### HelmChart, ### Bucket, …) describing notable features in prose.
- An optional
### General updates subsection for k8s/Go/dependency posture.
Fixes: and Improvements: bullet lists, each bullet a short title plus one
or more [#NNNN](https://github.com/fluxcd/<repo>/pull/NNNN) links.
Surface borderline items (repo-internal docs, a dep bump whose content already
shipped in a patch) to the user rather than guessing whether to headline them.
Dependency update PRs
Do not reduce a dependency bump to a generic line without checking its substance.
- Read the PR description, follow referenced upstream PRs (e.g.
Includes: fluxcd/pkg#NNNN), and look at the go.mod diff.
- Call out security fixes with their CVE/GHSA and an advisory link plus a short
impact parenthetical. Use matching wording across controllers that pull the
same bump.
- Only mention a dependency change relevant to what that controller actually
does — a bumped module often ships capabilities the controller never exercises.
Critical Checks
- Always
git fetch --all --tags --prune before comparing
v(X).(Y-1).0..release/vX.Y.x or reasoning about merged PRs.
- The release series branch (step 1) is cut from
main; the prep branch (step 2)
is cut from release/vX.Y.x.
- Pull the release series branch again after merging the release PR and before
tagging. Tag from the series-branch merge commit, not from the prep branch.
- Push
api/vX.Y.0 before vX.Y.0.
- The release→main PR merges the whole branch; do not cherry-pick for a minor.
- Open the backport label PR last (after step 10 merges) to avoid a rebase.
- Inspect the actual root
go.mod for the self-API path; do not assume its form.
- Do not silently special-case a controller. If a documented step seems not to
apply, inspect the file and confirm before proceeding.
Bumping the API in dependent controllers
After a controller minor ships, its API module often needs bumping in the
controllers that depend on it (e.g. image-reflector-controller/api in
image-automation-controller, or source-controller/api in helm-controller,
kustomize-controller, image-automation-controller, and source-watcher). This is a
separate follow-up PR per dependent repo, not part of the 11 release steps above.
- Branch from the dependent repo's
main (which may already carry an earlier
bump from the same release round), then
go get github.com/fluxcd/<controller>/api@vX.Y.0 followed by go mod tidy.
- The bump is usually
go.mod + go.sum only. Mirror an existing sibling PR
from the same round for the exact title/body/commit shape.
- But check whether the dependent repo pins the dependency's published release
manifests in
config/default/kustomization.yaml (remote
…/releases/download/vX.Y.Z/<controller>.crds.yaml and .deployment.yaml
URLs). If it does, bump those URLs to the new version too. Some repos pin them
(source-controller is pinned by source-watcher, helm-controller, and
kustomize-controller) and some do not (image-automation-controller does not pin
image-reflector-controller). Do not assume — grep the repo.
- If the released minor removed APIs, confirm the dependent still builds: it must
not import a removed package version. Run
go build ./... and go vet ./....
Updating this skill
- Improvements should land as a single-commit PR on a dedicated branch. When
accumulating more changes during a release session, amend and force-push rather
than adding new commits.
- Keep the skill-update PR open during the session and merge it last, after
the release is fully done. Do not keep a CI watch open on it throughout — check
CI right before merging.
- Do not leak session-specific state, downstream/enterprise distribution details,
or AI attribution into the skill file.
Useful Local Queries
- Existing release branches:
git branch -r --list 'origin/release/v*.x' | sort -V
- Latest tags:
git tag -l 'v*' | sort -V | tail
- Candidate PR merges since the previous minor:
git log --merges --grep="Merge pull request" v(X).(Y-1).0..release/vX.Y.x
- Full merged-PR cross-check:
gh pr list --base main --state merged --limit 200 --json number,mergedAt,title
- Verify a single PR for the changelog:
gh pr view <n> -R fluxcd/<repo> --json number,title,url,baseRefName,state,mergedAt