Files
computer-playbook/cli/deploy/test/runner.py
T
kevinveenbirkenbach dac111ccb7 ci(deploy): simplify per-app deploy workflow and Makefile act targets
- Rename _deploy-matrix.yml -> _deploy-per-app.yml and drop unused inputs
  (tested_lifecycles, only_distro, final_exclude_re).
- Keep one runner per app (matrix.app) and run all distros inside that job.
- Makefile: run deploy tests through act workflow_dispatch (no serial script).
- Add scripts/ci/discover.sh and scripts/ci/deploy-one-app.sh as small SRP helpers.
- Update reusable workflow callers to use the renamed file.

https://chatgpt.com/share/69659ff3-1414-800f-8652-5298fcf55398
2026-01-13 03:41:25 +01:00

157 lines
4.2 KiB
Python

from __future__ import annotations
import subprocess
from pathlib import Path
from .compose import Compose
from .deps import apps_with_deps, resolve_run_after
from .logs import append_text, log_path, write_text
def _repo_root_from_here() -> Path:
return Path(__file__).resolve().parents[3]
def _ensure_vault_password_file(compose: Compose) -> None:
compose.exec(
[
"sh",
"-lc",
"mkdir -p /etc/inventories/github-ci && "
"[ -f /etc/inventories/github-ci/.password ] || "
"printf '%s\n' 'ci-vault-password' > /etc/inventories/github-ci/.password",
],
check=True,
)
def _create_inventory(compose: Compose, *, include: list[str]) -> None:
if not include:
raise ValueError("include must not be empty")
cmd = [
"python3",
"-m",
"cli.create.inventory",
"/etc/inventories/github-ci",
"--host",
"localhost",
"--ssl-disabled",
"--primary-domain",
"infinito.localhost",
"--vars-file",
"inventory.sample.yml",
"--include",
",".join(include),
]
compose.exec(cmd, check=True, workdir="/opt/src/infinito")
_ensure_vault_password_file(compose)
def _run_deploy(compose: Compose, *, deploy_type: str, deploy_ids: list[str]) -> int:
"""
deploy_type: "server" or "workstation"
"""
cmd = [
"python3",
"-m",
"cli.deploy.dedicated",
"/etc/inventories/github-ci/servers.yml",
"-p",
"/etc/inventories/github-ci/.password",
"-vv",
"--assert",
"true",
"--debug",
"--diff",
"-T",
deploy_type,
"-i",
*deploy_ids,
]
r = compose.exec(cmd, check=False)
return r.returncode
def run_test_plan(
*,
deploy_type: str,
distro: str,
no_cache: bool,
missing_only: bool,
only_app: str | None,
logs_dir: Path,
keep_stack_on_failure: bool,
) -> int:
if not only_app:
raise ValueError(
"Runner no longer performs discovery. You must pass --app from the workflow matrix."
)
if deploy_type not in {"server", "workstation"}:
raise ValueError(f"Invalid deploy_type: {deploy_type}")
repo_root = _repo_root_from_here()
compose = Compose(repo_root=repo_root, distro=distro)
exit_code = 0
main_log = log_path(logs_dir, deploy_type, distro, "orchestrator")
write_text(
main_log, f"deploy_type={deploy_type}\ndistro={distro}\nonly_app={only_app}\n"
)
try:
compose.build_infinito(no_cache=no_cache, missing_only=missing_only)
compose.up()
deps = resolve_run_after(compose, only_app)
deploy_ids = apps_with_deps(only_app, deps_role_names=deps)
per_app_log = log_path(logs_dir, deploy_type, distro, f"app-{only_app}")
write_text(
per_app_log,
" ".join(
[
f"app={only_app}",
f"deps={','.join(deps) if deps else '<none>'}",
f"deploy_ids={','.join(deploy_ids) if deploy_ids else '<none>'}",
]
)
+ "\n",
)
append_text(
main_log, f"\nmode=single-with-deps\nresolved_ids={','.join(deploy_ids)}\n"
)
_create_inventory(compose, include=deploy_ids)
rc = _run_deploy(compose, deploy_type=deploy_type, deploy_ids=deploy_ids)
exit_code = rc
if rc != 0:
append_text(
per_app_log,
"\n--- hint ---\n"
"Search workflow logs for the failing task output.\n"
f"Also run: INFINITO_DISTRO={distro} docker compose --profile ci logs --tail=200\n",
)
return rc
except subprocess.CalledProcessError as exc:
exit_code = exc.returncode
append_text(main_log, f"\nERROR: {exc}\n")
return exc.returncode
except Exception as exc:
exit_code = 1
append_text(main_log, f"\nERROR: {exc}\n")
return 1
finally:
should_keep = keep_stack_on_failure and exit_code != 0
if not should_keep:
try:
compose.down()
except Exception:
pass