feat(self-managed): record the installed stack version in-cluster, and let the 1.0 train ship it - #2012
Merged
sbaum1994 merged 3 commits intoSep 22, 2026
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: NVIDIA/nvcf/.coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
kristinapathak
force-pushed
the
kpathak/seed-stack-1.0-upgrade-policy
branch
from
September 21, 2026 22:25
77a4539 to
207955c
Compare
Contributor
sbaum1994
approved these changes
Sep 21, 2026
4 tasks
along-2017
approved these changes
Sep 21, 2026
The v1.0.0 tag this branch is rooted at predates release branching. At that commit there is no release_branch_only, no version_file, no publish_release_branch_release and no branch_cut, and test-github-release.py actively asserted that no stack may carry a VERSION file: the three stacks still released from main under semantic-release. A branch cut from that tag therefore has no code path that can publish 1.0.1 at all. This is a carve of two commits from main, reduced to what makes a release possible and nothing else: 729fcc5 ci(release): put the deploy/stacks subprojects back on release branching (#1959) a00ee1e fix(release): do not cut a stack patch for a push that changes nothing it ships (#1963) Their documentation changes are left out; a maintenance branch describing capabilities it does not carry is worse than one that says nothing. The second commit is load-bearing rather than incidental: it is what makes stack_content_changed_since discard the version file, so release bookkeeping on this branch does not cut versions. All three VERSION files are present because test_the_stacks_release_from_a_ branch_and_nothing_else_does validates one for every stack registered as release_branch_only, so the metadata and the files have to agree. They read 1.0.0 because all three stacks were tagged v1.0.0 together; the 0.21.0 seed #1959 carries is the pre-1.0 value #1964 later had to correct on main. Nothing here cuts a version. The only path under deploy/stacks that changes is the version file, which is excluded from the content comparison. Refs #1977 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kristinapathak
force-pushed
the
kpathak/seed-stack-1.0-upgrade-policy
branch
from
September 21, 2026 23:00
c223ede to
4c95235
Compare
An upgrade has to know where it is starting from, and nothing in a cluster carries that today. Helm tracks chart versions per release; helmfile has no concept of the bundle's own version. So every cluster looks identical at upgrade time, and a gate has no basis to decide whether the jump it has been asked to make is one it can make safely. This writes a nvcf-upgrade-receipt ConfigMap naming the stack version that was installed. Only the writer ships here. The validating hook belongs in the release that first has something to validate against, and a writer cannot block an upgrade whereas a checker that misjudges can break every existing customer. Shipping it on the 1.0 line is the point. A cluster that reaches 2.0.0 with no receipt is indistinguishable from a 0.x install, which leaves a gate choosing between refusing everybody and checking nothing. Once any 1.x records a version, absence becomes a refusal that names a version the customer can actually install. The hook is post-install and post-upgrade, not pre-*: a receipt must not claim a version before that version has been applied. post-upgrade alone would skip the first cluster to receive this chart, because Helm runs post-install where no prior release exists -- precisely the clusters this exists for. Ordering is a stage boundary rather than a needs: edge. Under the helmfile version this stack pins, needs: places a release in a later DAG layer where it waits on every peer in the previous one, and one slow or failed peer silently skips it; see the admin-issuer-proxy comment in 02-core.yaml.gotmpl. A new last-numbered stage gets the ordering without that failure mode. The chart is local to the bundle rather than pulled from the registry, so the receipt works the moment this merges instead of waiting on a chart publish. Closes #1977 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6 tasks
The Role granted get, create and patch on every ConfigMap in the namespace, so anything able to run a pod under this ServiceAccount could rewrite unrelated ConfigMaps for as long as the binding existed. The Job only ever touches one object. get and patch now name that object through resourceNames. create stays unscoped in a rule of its own, because RBAC matches resourceNames against an object that does not exist yet and so never satisfies a create rule that names one; keeping it separate leaves the unscoped verb visible rather than buried alongside the scoped ones. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 tasks
sbaum1994
merged commit Sep 22, 2026
67c010f
into
release-deploy/stacks/self-managed/v1.0
17 checks passed
Contributor
|
This PR is included in version 1.0.1. The release is available on GitHub release. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ships the upgrade receipt on the 1.0 line. Closes #1977.
Two commits: the first makes this branch capable of publishing at all, the second is the receipt itself.
The receipt
An upgrade has to know where it is starting from, and nothing in a cluster carries that today. Helm tracks chart versions per release; helmfile has no concept of the bundle's own version. So every cluster looks identical at upgrade time and a gate has no basis to decide anything.
This writes a
nvcf-upgrade-receiptConfigMap naming the installed stack version. Only the writer ships here. The validating hook belongs in the release that first has something to validate against, and a writer cannot block an upgrade whereas a checker that misjudges can break every existing customer.Shipping it on 1.0 is the whole point: a cluster reaching 2.0.0 with no receipt is indistinguishable from a 0.x install, which leaves a gate choosing between refusing everybody and checking nothing. Once any 1.x records a version, absence becomes a refusal that names a version the customer can actually install.
Three decisions worth review:
post-install,post-upgrade, notpre-*. A receipt must not claim a version before that version has been applied.post-upgradealone would skip the first cluster to receive this chart, since Helm runspost-installwhere no prior release exists — precisely the clusters this exists for.needs:edge. Under the helmfile version this stack pins,needs:places a release in a later DAG layer where it waits on every peer in the previous one, and one slow or failed peer silently skips it — see theadmin-issuer-proxycomment in02-core.yaml.gotmpl. A stage boundary gets the ordering without that failure mode.Why the first commit exists
The
v1.0.0tag predates release branching: norelease_branch_only, noversion_file, nopublish_release_branch_release, andtest-github-release.pyasserted no stack may carry aVERSIONfile. A branch cut from that tag cannot publish anything. It is a carve of729fcc5(#1959) anda00ee1e(#1963) reduced to what makes a release possible — documentation changes left out, since a maintenance branch describing capabilities it does not carry is worse than one that says nothing.All three
VERSIONfiles are present becausetest_the_stacks_release_from_a_branch_and_nothing_else_doesvalidates one for every stack registered asrelease_branch_only. Verified by removal: dropping the other two fails the suite.This cuts 1.0.1
Verified by running the real release logic on a correctly-named branch:
That is the intent — the receipt is the first change to what the stack actually deploys, so it is what publishes the patch.
Test plan
make testindeploy/stacks/self-managed— full suite, exit 0, including the newupgrade-receipt-wiringpython3 tools/ci/test-github-release.py— 98 tests, OKINSTALLED_STACK_VERSIONresolves to1.0.0from the bundle's ownVERSION1.0.1Note: CodeRabbit reports
Review skipped: reviews are disabled for this base branch, so this PR gets no automated review.🤖 Generated with Claude Code