fix(drone-dep): correct gitea admin create flag + dep deploy counter
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Two issues found during first manual harness run: 1. gitea `--must-change-password false` (space form) leaves a pending password-change for the ci_admin user, blocking the OAuth2 API call. Fix: use `--must-change-password=false` (equals form, required by gitea's BoolFlag with default=true). 2. dep deploy_app() calls incremented the DG4.1 "one deploy per run" counter, causing a false violation when gitea dep + drone both deploy. Fix: lifecycle.deploy_app gains _count_deploy=True param (default backward-compat); deps_mod.deploy_deps passes _count_deploy=False so only the recipe-under-test counts toward DG4.1. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -80,9 +80,10 @@ def deploy_deps(
|
|||||||
for dep in deps:
|
for dep in deps:
|
||||||
domain = dep_domain(parent_recipe, pr, ref, dep)
|
domain = dep_domain(parent_recipe, pr, ref, dep)
|
||||||
print(f" dep: deploying {dep} -> {domain}", flush=True)
|
print(f" dep: deploying {dep} -> {domain}", flush=True)
|
||||||
# NB: each dep_app gets a fresh deploy_count entry only on `_record_deploy` which fires
|
# Dep deploys do NOT count toward the DG4.1 "one deploy per run" invariant — that
|
||||||
# inside `lifecycle.deploy_app`. For Phase 2 the deploy-count guard (DG4.1) counts the
|
# contract covers the recipe-under-test only; each dep is a supporting service, not the
|
||||||
# parent + its deps as distinct install events — by design, since each is a separate app.
|
# 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.
|
||||||
dm = meta_for.get(dep) or meta_mod.load(dep)
|
dm = meta_for.get(dep) or meta_mod.load(dep)
|
||||||
lifecycle.deploy_app(
|
lifecycle.deploy_app(
|
||||||
dep,
|
dep,
|
||||||
@ -90,6 +91,7 @@ def deploy_deps(
|
|||||||
secrets=True,
|
secrets=True,
|
||||||
deploy_timeout=int(dm.DEPLOY_TIMEOUT),
|
deploy_timeout=int(dm.DEPLOY_TIMEOUT),
|
||||||
meta=dm,
|
meta=dm,
|
||||||
|
_count_deploy=False,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
lifecycle.wait_healthy(
|
lifecycle.wait_healthy(
|
||||||
|
|||||||
@ -238,6 +238,7 @@ def deploy_app(
|
|||||||
install_steps_hook: tuple[str, str] | None = None,
|
install_steps_hook: tuple[str, str] | None = None,
|
||||||
deploy_timeout: int = 900,
|
deploy_timeout: int = 900,
|
||||||
meta=None,
|
meta=None,
|
||||||
|
_count_deploy: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create + configure + deploy an app. Forces LETS_ENCRYPT_ENV='' so traefik serves the
|
"""Create + configure + deploy an app. Forces LETS_ENCRYPT_ENV='' so traefik serves the
|
||||||
wildcard cert via the file provider and NEVER attempts ACME (adversary finding A1). Applies any
|
wildcard cert via the file provider and NEVER attempts ACME (adversary finding A1). Applies any
|
||||||
@ -251,10 +252,14 @@ def deploy_app(
|
|||||||
`deploy_timeout` is the subprocess timeout for `abra app deploy`. Caller (orchestrator) passes
|
`deploy_timeout` is the subprocess timeout for `abra app deploy`. Caller (orchestrator) passes
|
||||||
`recipe_meta.DEPLOY_TIMEOUT` so heavy recipes (ghost, matrix-synapse, lasuite-meet) can extend
|
`recipe_meta.DEPLOY_TIMEOUT` so heavy recipes (ghost, matrix-synapse, lasuite-meet) can extend
|
||||||
past the 900s default. abra's INTERNAL TIMEOUT (recipe's TIMEOUT env, default 300s) is set via
|
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."""
|
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)."""
|
||||||
if meta is None:
|
if meta is None:
|
||||||
meta = meta_mod.load(recipe)
|
meta = meta_mod.load(recipe)
|
||||||
_record_deploy()
|
if _count_deploy:
|
||||||
|
_record_deploy()
|
||||||
# Lock BEFORE the app exists: a concurrent run's janitor must never see this app without a
|
# Lock BEFORE the app exists: a concurrent run's janitor must never see this app without a
|
||||||
# held app lock (it would probe it as an orphan and reap an in-flight deploy). Also the
|
# held app lock (it would probe it as an orphan and reap an in-flight deploy). Also the
|
||||||
# double-!testme serialisation point: a second run of the same domain blocks here.
|
# double-!testme serialisation point: a second run of the same domain blocks here.
|
||||||
|
|||||||
@ -444,8 +444,7 @@ def setup_gitea_oauth(provider_domain: str, parent_domain: str) -> dict:
|
|||||||
admin_password,
|
admin_password,
|
||||||
"--email",
|
"--email",
|
||||||
admin_email,
|
admin_email,
|
||||||
"--must-change-password",
|
"--must-change-password=false", # equals-form required; gitea BoolFlag default=true
|
||||||
"false",
|
|
||||||
],
|
],
|
||||||
timeout=120,
|
timeout=120,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user