Molecule checks for a requirements file at the scenario's default path
before it installs anything, and warns "Missing roles requirements file"
when it is absent - so `requirements-file` pointing elsewhere was silently
ignored and the galaxy roles were never installed. CI failed on a missing
ansible-role-docker; the local run passed only because those roles were
already in ~/.ansible/roles from earlier work, which is exactly the kind of
difference a clean CI run exists to expose.
A symlink satisfies Molecule's check while keeping one copy of the pins.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three things that would not have scaled to 70 roles:
- The Python and Ansible dependency pins were about to be copied into every
role. They now live once in molecule-shared/, which scenarios reference
relatively, so they cannot drift apart.
- The helper container images used for probing were hardcoded inline. They
are pinned once in molecule-shared/vars.yml, carry `# renovate:`
annotations, and a custom manager in .github/renovate.json keeps them
current - verified with a local Renovate dry run, which offers
curl 8.11.1 -> 8.21.0 and python 3.13 -> 3.14-alpine. Seventy invisible
hardcodes is the blindness class we have been removing elsewhere.
- Running a scenario meant knowing the venv and cd incantation. `just
molecule <role>` does it, and with no argument lists the roles that have
a scenario.
Molecule is deliberately not wired into prek: a run takes minutes, pulls
images and needs Docker, which is fine on request and not fine per commit.
docs/molecule-testing.md covers how to run and write these, including the
four things a role here needs that a standalone role does not. AGENTS.md
points at it rather than carrying the detail.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>