feat(ansible): prepare the launch fleet (private overlay, catalogue sizing, runbook) #141
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: Molecule | |
| # Containerised converge + idempotence + verify for the decdn_node role. | |
| # Heavy (privileged systemd Docker container) — scoped to ansible/ changes and | |
| # blocking. Mark it a required status check in branch protection once proven. | |
| # This file is in `paths` alongside ansible/ so a change to the job itself (its cache | |
| # wiring, JOBS, the timeout) is exercised by the PR that makes it. | |
| on: | |
| pull_request: | |
| paths: ['ansible/**', '.github/workflows/molecule.yml'] | |
| push: | |
| branches: [main] | |
| paths: ['ansible/**', '.github/workflows/molecule.yml'] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: molecule-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| molecule: | |
| runs-on: ubuntu-latest # Docker is preinstalled | |
| # ~4m41s at JOBS=3. A bound, not a target: without one a wedged privileged | |
| # systemd container burns the 360-minute default, and with cancel-in-progress | |
| # above, some branch-protection setups read the resulting cancelled check as | |
| # "not failed" rather than as a failure. | |
| timeout-minutes: 45 | |
| defaults: | |
| run: | |
| working-directory: ansible | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| # Keyed on this workflow file: no pip manifest exists, and the workflow is | |
| # where the package list lives. ci.yml's ansible-lint job has the full note. | |
| - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| cache: pip | |
| cache-dependency-path: .github/workflows/molecule.yml | |
| - name: Install molecule + Ansible | |
| run: | | |
| python -m pip install --upgrade \ | |
| molecule "molecule-plugins[docker]" ansible ansible-lint docker | |
| # Same key and same rationale as ci.yml's jobs (see ansible-lint there): a warm | |
| # tree makes the install a no-op that never contacts galaxy.ansible.com, and the | |
| # save is gated so a part-way Galaxy failure cannot poison the cache. The key is | |
| # derived wholly from ansible/requirements.yml, so it cannot drift from ci.yml's | |
| # copy the way a duplicated env var would. It wraps | |
| # `make molecule` because the deps install is owned by the Make target here, not | |
| # by a step of its own. | |
| - uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| id: galaxy-cache | |
| with: | |
| path: ansible/collections | |
| key: galaxy-${{ runner.os }}-${{ hashFiles('ansible/requirements.yml') }} | |
| - name: molecule test | |
| # `make molecule` runs every scenario under ansible/molecule/ and fans them out | |
| # in parallel; ansible/Makefile documents the set and the fail-loud guards. | |
| # | |
| # There is deliberately no separate `make deps` step: the molecule targets take | |
| # `deps` as a prerequisite, so a standalone one would resolve and install the | |
| # Galaxy requirements a second time every run — a second chance to trip over a | |
| # flaky galaxy.ansible.com, for no added coverage. The cache above wraps that | |
| # Make-owned invocation instead. | |
| # | |
| # JOBS is capped at 3 rather than the default (one job per scenario, currently | |
| # 7): every scenario is a privileged systemd container, and they share this | |
| # runner's cores and cgroup hierarchy. If this job turns flaky, drop to JOBS=1 | |
| # or swap in `make molecule-serial` — the latter also serialises the output. | |
| run: make molecule JOBS=3 | |
| # A step `if:` without a status-check function implies success(), so this is | |
| # skipped when anything above failed — including a genuinely failing scenario, | |
| # which leaves the cache cold for that run. Conservative on purpose: it is the | |
| # same guard that keeps a part-way Galaxy install out of the cache. | |
| - uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| if: steps.galaxy-cache.outputs.cache-hit != 'true' | |
| with: | |
| path: ansible/collections | |
| key: galaxy-${{ runner.os }}-${{ hashFiles('ansible/requirements.yml') }} |