fix(canon): promote clears stale warm-stack on a fresh seed (failed-promote secret residue)
All checks were successful
continuous-integration/drone/push Build is passing

A once-failed promote left swarm secrets (e.g. drone's gitea client_secret_v1) behind; the retry's
install_steps 'abra app secret insert' then FATAd 'already exists', so a recipe could never recover
its canonical. promote_canonical now teardown_app()s the warm domain when there is NO existing
canonical (fresh seed) — clearing leftover secrets/.env/partial volumes — while a re-promote
(canonical exists) still reattaches its retained known-good volume untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
autonomic-bot
2026-06-17 10:51:01 +00:00
parent d32940d3e1
commit ca89d44c05

View File

@ -951,6 +951,13 @@ def promote_canonical(
meta = meta_mod.load(recipe) meta = meta_mod.load(recipe)
# The cold run's deploy-count was already asserted + the countfile removed; don't perturb it. # The cold run's deploy-count was already asserted + the countfile removed; don't perturb it.
os.environ.pop("CCCI_DEPLOY_COUNT_FILE", None) os.environ.pop("CCCI_DEPLOY_COUNT_FILE", None)
# FRESH SEED only (no existing canonical): clear any leftover warm-<recipe> stack state from a
# PRIOR FAILED promote attempt (secrets/.env/partial volumes). Without this, a recipe whose
# install_steps inserts a non-generatable secret (e.g. drone's gitea client_secret) FATAs
# "secret … already exists" on the retry, so a once-failed promote can never recover. A
# re-promote (canonical EXISTS) must NOT teardown — it reattaches its retained known-good volume.
if not canonical.read_registry(recipe):
lifecycle.teardown_app(canonical.canonical_domain(recipe), verify=False)
# Pristine tree at the tag: discard the cold run's tier mutations + untracked overlay so the # Pristine tree at the tag: discard the cold run's tier mutations + untracked overlay so the
# pinned `abra app new` clean-tree gate passes (deploy_app re-applies the overlay + auto-chaos). # pinned `abra app new` clean-tree gate passes (deploy_app re-applies the overlay + auto-chaos).
abra.recipe_checkout(recipe, version) abra.recipe_checkout(recipe, version)