From 5384f5c13feb8759f7e8634d67e1dfc29226c883 Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Thu, 11 Jun 2026 21:59:51 +0000 Subject: [PATCH] =?UTF-8?q?fix(drone-dep):=20revert=20=5Fcount=5Fdeploy=3D?= =?UTF-8?q?False=20=E2=80=94=20dep=20deploys=20must=20count=20for=20DG4.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DG4.1 formula in run_recipe_ci.py is: expected_deploy_count = 1 + deps_deployed_count So when gitea dep deploys, the expected count becomes 2 (1 recipe + 1 dep). The _count_deploy=False fix made dep deploys NOT count, giving actual=1 vs expected=2 → DG4.1 violation even though the run was correct. Original error "deploy-count 2 != 1" was because deps_state was empty when the DG4.1 check ran (provisioning had failed), giving expected=1 while count was already 2 from an early dep deploy. The proper fix is for _provision_deps to succeed (which it now does), not to suppress counting. Revert _count_deploy=False in deps.py; update docstrings for clarity. Co-Authored-By: Claude Sonnet 4.6 --- runner/harness/deps.py | 10 +++++----- runner/harness/lifecycle.py | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/runner/harness/deps.py b/runner/harness/deps.py index b73e7b7..9026a09 100644 --- a/runner/harness/deps.py +++ b/runner/harness/deps.py @@ -16,6 +16,8 @@ Per Phase-2 DECISIONS: must share the single node's MAX_TESTS budget without exceeding it). - Each dep is undeployed in the orchestrator's `finally`, in **reverse** order so a recipe-under- test can depend on multiple deps with a dependency chain (a → b → c teardown is c → b → a). +- Dep deploys DO count toward the DG4.1 deploy-count invariant. The formula in run_recipe_ci.py is + `expected_deploy_count = 1 + deps_deployed_count`, so each dep deploy increments the counter. Run state: - `$CCCI_DEPS_FILE` — JSON file written by the orchestrator after each dep deploys; each entry is @@ -80,10 +82,9 @@ def deploy_deps( for dep in deps: domain = dep_domain(parent_recipe, pr, ref, dep) print(f" dep: deploying {dep} -> {domain}", flush=True) - # Dep deploys do NOT count toward the DG4.1 "one deploy per run" invariant — that - # contract covers the recipe-under-test only; each dep is a supporting service, not the - # subject of the test. Pass _count_deploy=False so the main recipe's single-deploy - # assertion isn't distorted by the number of deps declared. + # Dep deploys count toward DG4.1 — the check expects (1 + len(cold-deps)), so each + # dep that deploys here MUST be counted. The formula is authoritative in run_recipe_ci.py: + # expected_deploy_count = 1 + deps_deployed_count dm = meta_for.get(dep) or meta_mod.load(dep) lifecycle.deploy_app( dep, @@ -91,7 +92,6 @@ def deploy_deps( secrets=True, deploy_timeout=int(dm.DEPLOY_TIMEOUT), meta=dm, - _count_deploy=False, ) try: lifecycle.wait_healthy( diff --git a/runner/harness/lifecycle.py b/runner/harness/lifecycle.py index 98f8000..539b341 100644 --- a/runner/harness/lifecycle.py +++ b/runner/harness/lifecycle.py @@ -254,8 +254,10 @@ def deploy_app( past the 900s default. abra's INTERNAL TIMEOUT (recipe's TIMEOUT env, default 300s) is set via EXTRA_ENV; this is the Python subprocess wrapper's timeout so abra doesn't get SIGKILLed mid-deploy. - `_count_deploy`: set False for dep deployments — the DG4.1 "one deploy per run" invariant - counts ONLY the recipe-under-test, not its install-time deps (deps_mod.deploy_deps).""" + `_count_deploy`: internal escape hatch — set False to skip incrementing the DG4.1 deploy + counter (e.g. for test fixtures that call deploy_app without participating in a real run). + Normal orchestration should always use the default True — dep deploys count too (the DG4.1 + formula is `expected = 1 + deps_count`, so deps MUST be counted; see run_recipe_ci.py).""" if meta is None: meta = meta_mod.load(recipe) if _count_deploy: