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: