feat: add promote downgrade/monotonicity gate#156
Merged
Conversation
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
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.
Problem
The promote path does no version comparison. It propagates the source env's version forward verbatim, so promoting an older version onto an env would silently regress it (and every later env, including prod) to an older release.
Version.Compareexisted but was unused by promote. This closes that silent-regression hole.Fix
A hard monotonicity gate in promote preflight (
internal/promote/preflight.gocheckDowngrade), run alongside the existing divergence guard. For each planned promotion it parses the incoming version (the source version being promoted) and the target env's current version and compares them withversion.Compare:--allow-downgrade(newworkflow_dispatchboolean input, threaded input ->ALLOW_DOWNGRADEenv ->--allow-downgradeflag ->PreflighterOptions, mirroring--rollback-on-failure): permits a non-prod downgrade with a recorded warning.--allow-downgrade, with a prod-specific error, even when a lower env in the same cascade permitted the same downgrade. Prod is never silently downgraded.Additive: forward promotions are unchanged; the gate only fires on a detected downgrade, and the new input defaults to false.
Verification
internal/promote/downgrade_test.go(forward, equal, blocked-without-flag, allowed-with-flag, prod-always-requires-flag, non-semver warn+allow, empty-version skip). All pass.e2e/scenarios/20-promote-allow-downgrade.yamlasserts the generatedpromote.yamlexposes theallow_downgradeinput and threads it into the preflight step. PASS locally:--- PASS: TestMultiStepScenarios/Promote_allow_downgrade_dispatch_input (19.37s)go build ./... && go test ./...(1241 pass); e2e modulego build/go vetclean;golangci-lint run ./...clean on both modules..github/workflows/promote.yamlcommitted.--allow-downgradedocumented in the CLI reference.