diff --git a/runner/harness/canonical.py b/runner/harness/canonical.py index 308cb0b..d8a5df1 100644 --- a/runner/harness/canonical.py +++ b/runner/harness/canonical.py @@ -100,7 +100,11 @@ def deploy_canonical(recipe: str, timeout: int = 900) -> None: if not rec: raise RuntimeError(f"no canonical registry for {recipe} — seed one first (cold run)") domain, version = rec["domain"], rec["version"] - # The .env + retained volume already exist; redeploy the recorded version (idempotent with -f). + # The .env + retained volume already exist; redeploy the recorded known-good version. Reset the + # recorded TYPE=: FIRST so abra can resolve the "current deployment" even if a + # prior --quick upgrade left TYPE pointing at a since-removed/broken PR commit (otherwise abra + # FATALs "unable to resolve "). Then checkout the tag + idempotent (-f) redeploy. + abra.env_set(domain, "TYPE", f"{recipe}:{version}") abra.recipe_checkout(recipe, version) r = subprocess.run( ["abra", "app", "deploy", domain, version, "-o", "-n", "-f"], diff --git a/runner/run_recipe_ci.py b/runner/run_recipe_ci.py index c8b24b8..2768f17 100644 --- a/runner/run_recipe_ci.py +++ b/runner/run_recipe_ci.py @@ -37,6 +37,7 @@ import shutil import subprocess import sys import tempfile +import time ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(ROOT, "runner")) @@ -132,6 +133,12 @@ def fetch_recipe(recipe: str, ref: str | None, src: str | None) -> None: recipes_dir = os.path.expanduser("~/.abra/recipes") os.makedirs(recipes_dir, exist_ok=True) dest = os.path.join(recipes_dir, recipe) + # CCCI_SKIP_FETCH=1: use the local recipe clone as-is (lets a test/Adversary stage a fake/broken + # ref — e.g. a simulated broken PR head for the --quick rollback proof — without it being clobbered + # by a re-fetch). Never set in production CI. + if os.environ.get("CCCI_SKIP_FETCH") == "1": + print(f"[fetch] CCCI_SKIP_FETCH=1 — using local {recipe} recipe clone as-is", flush=True) + return if src and ref: url = f"https://git.autonomic.zone/{src}.git" git = ["git"] @@ -549,6 +556,10 @@ def run_quick(recipe: str, ref: str | None, head_ref: str | None, repo_local: st abra.undeploy(domain) _wait_undeployed(domain) warmsnap.restore(recipe, domain) + # reset recorded version to the known-good (the failed upgrade set TYPE to the broken + # PR commit) so the idle canonical's .env agrees with the registry + re-warms cleanly. + if reg.get("version"): + abra.env_set(domain, "TYPE", f"{recipe}:{reg['version']}") canonical._set_status(recipe, "idle") # noqa: SLF001 rolled_back = True print(" quick FAIL → restored known-good data; canonical idle (NOT promoted)",