DEVX-133: fix: auto-discover molecule root instead of hardcoding gitea-runner

This commit is contained in:
emil User
2026-07-13 02:25:59 +00:00
parent 7b624b0525
commit 50dcb67083
6 changed files with 93 additions and 22 deletions
+17 -3
View File
@@ -30,10 +30,24 @@ from devx.i18n import _
from devx.molecule.platforms import PLATFORMS, load_platforms
DEFAULT_MAX_RUNNERS = 3
MOLECULE_ROOT = Path("ansible/roles/gitea-runner/molecule")
DEFAULT_ROLES_ROOT = Path("ansible/roles")
def _default_molecule_root() -> Path:
"""Auto-discover the single molecule directory under ansible/roles/.
If exactly one role has a molecule/ subdirectory, return it.
Otherwise, fall back to the first role with a molecule/ directory.
"""
roles_root = DEFAULT_ROLES_ROOT
if not roles_root.is_dir():
return roles_root / "gitea_runner" / "molecule" # sensible default for error message
mol_dirs = sorted(d / "molecule" for d in roles_root.iterdir() if (d / "molecule").is_dir())
if mol_dirs:
return mol_dirs[0]
return roles_root / "molecule" # will produce a clear "not found" error
@dataclass(frozen=True)
class TestPair:
"""A (scenario, platform) combination to test."""
@@ -83,7 +97,7 @@ class MultiRoleTestPair:
def discover_scenarios(root: Path | None = None) -> list[str]:
"""Return sorted list of molecule scenario directory names."""
if root is None:
root = MOLECULE_ROOT
root = _default_molecule_root()
if not root.is_dir():
raise click.ClickException(_("Molecule directory not found: {path}", path=str(root)))
scenarios = [d.name for d in root.iterdir() if d.is_dir() and not d.name.startswith("_") and d.name != "common"]
@@ -318,7 +332,7 @@ def _write_github_env(key: str, value: str) -> None:
"--molecule-root",
type=click.Path(exists=True, file_okay=False, path_type=Path),
default=None,
help="Custom molecule directory (single-role mode). Default: ansible/roles/gitea-runner/molecule.",
help="Custom molecule directory (single-role mode). Default: auto-discovered under ansible/roles/*/molecule.",
)
@click.option(
"--roles-root",
+18 -4
View File
@@ -21,7 +21,20 @@ import click
from devx.molecule.platforms import PLATFORMS
ROLE_DIR = Path("ansible/roles/gitea-runner")
DEFAULT_ROLES_ROOT = Path("ansible/roles")
def _default_role_dir() -> Path:
"""Auto-discover the single role directory with molecule scenarios."""
roles_root = DEFAULT_ROLES_ROOT
if not roles_root.is_dir():
return roles_root / "gitea_runner" # sensible default for error message
role_dirs = sorted(d for d in roles_root.iterdir() if (d / "molecule").is_dir())
if role_dirs:
return role_dirs[0]
return roles_root / "role" # will produce a clear error
SCENARIOS = ["default", "multi-instance", "lifecycle", "template-content", "deregister", "update"]
@@ -72,15 +85,16 @@ def main(bin_dir: str) -> None:
if not Path(molecule_bin).exists():
raise click.ClickException(f"molecule not found at {molecule_bin}. Run 'make setup' first.")
if not ROLE_DIR.exists():
raise click.ClickException(f"Role directory not found: {ROLE_DIR}")
role_dir = _default_role_dir()
if not role_dir.exists():
raise click.ClickException(f"Role directory not found: {role_dir}")
base_env = dict(os.environ)
base_env["ANSIBLE_ALLOW_BROKEN_CONDITIONALS"] = "true"
base_env["ANSIBLE_INJECT_INVOCATION"] = "1"
for platform in PLATFORMS:
rc = _run_platform(molecule_bin, platform, ROLE_DIR, SCENARIOS, base_env)
rc = _run_platform(molecule_bin, platform, role_dir, SCENARIOS, base_env)
if rc != 0:
click.echo(f"FAILED on platform {platform['name']}", err=True)
sys.exit(rc)
+8 -2
View File
@@ -145,13 +145,19 @@ def resolve_role_dir(role: str, roles_root: Path | None, repo_root: Path) -> Pat
"""Resolve the working directory for a molecule pair.
For multi-role pairs (role non-empty), uses ``roles_root/role``.
For single-role pairs, uses ``repo_root/ansible/roles/gitea-runner``.
For single-role pairs, auto-discovers the first role with a molecule/
subdirectory under ``repo_root/ansible/roles/``.
"""
if role:
if roles_root is None:
roles_root = repo_root / "ansible" / "roles"
return roles_root / role
return repo_root / "ansible" / "roles" / "gitea-runner"
roles_dir = repo_root / "ansible" / "roles"
if roles_dir.is_dir():
role_dirs = sorted(d for d in roles_dir.iterdir() if (d / "molecule").is_dir())
if role_dirs:
return role_dirs[0]
return roles_dir / "role" # will produce a clear "not found" error
@click.command()