Thanks for considering a contribution to LinuxVitals
(sameeralam3127.linux_vitals).
You do not need Docker, a lab, or any Linux hosts to make a useful first change. Most of the test suite runs locally in about a minute, and CI does the heavy part for you.
-
Pick an issue labelled
good first issue. Each one has a comment listing the files to change and the test to add. Comment on the issue to claim it, and ask anything there. -
Set up and run the quick loop:
git clone https://github.com/<you>/linux-vitals.git && cd linux-vitals python3 -m venv .venv && source .venv/bin/activate pip install -r requirements-dev.txt ansible-galaxy collection install -r requirements.yml pytest -q # ~200 tests, no hosts involved pre-commit run --all-files # lint, YAML, whitespace, shellcheck
-
Open the pull request. CI then runs what you could not run locally: Molecule against live systemd containers for Ubuntu, Rocky, Fedora, and openSUSE, and the whole suite again on the oldest ansible-core this collection supports. If one of those fails and the reason is not obvious, say so in the PR -- that is a normal part of review, not a failure on your part.
Add a line to CHANGELOG.md under [Unreleased] for anything a user would
notice. The rest of this document is reference for when you need it.
git clone https://github.com/sameeralam3127/linux-vitals.git
cd linux-vitals
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
ansible-galaxy collection install -r requirements.yml
pre-commit installpytest -q creates the .dev-collections symlink automatically if it's
missing. To run playbooks by hand, create it yourself first:
mkdir -p .dev-collections/ansible_collections/sameeralam3127
ln -s "$(pwd)" .dev-collections/ansible_collections/sameeralam3127/linux_vitalsSee docs/architecture.md before making structural
changes -- in particular, why the roles share one variable namespace
and why report/.env paths resolve from inventory_dir.
pre-commit run --all-files
ansible-lint roles/ playbooks/ molecule/ demo/
ansible-playbook playbooks/healthcheck.yml --syntax-check
pytest -qAll four run in CI (.github/workflows/ci.yml)
on every pull request; a change isn't done until all four pass locally.
CI runs them twice: on the newest ansible-core, and on 2.16, the minimum
declared in meta/runtime.yml. A change can pass locally on a new core and
still break 2.16 -- see
docs/testing.md for what that
usually looks like and how to run the 2.16 suite yourself.
On top of those, CI runs the Molecule scenarios -- one live systemd container per supported distribution (Ubuntu, Rocky, Fedora, openSUSE) -- which are what prove the roles' runtime behaviour rather than just their syntax. They need a Docker daemon, so they are not part of the quick loop above:
molecule test -s ubuntu # one distribution
molecule test --all # all fourSee docs/testing.md for what each scenario covers, how to
debug a failing one, and what containers can't prove. Any change to
vitals_scan discovery, vitals_heal, or the report pipeline should be
validated with at least one scenario locally before pushing.
A check that could not run must never read as a clean host. When a check
shells out, tell "ran and found nothing" from "could not run", and for the
second raise a finding with 'status': 'unknown' and a reason instead of
nothing. failed_when: false and 2>/dev/null are exactly how the two get
conflated. tests/test_finding_contract.py fails if a new scan probe sets
failed_when: false, and passes once you have handled the "could not run"
path and added the probe to its list. The full rule is in
docs/architecture.md.
A new finding id also needs a severity in linux_vitals_finding_severities
(roles/vitals_scan/defaults/main.yml), a row in
docs/report-guide.md, a section in the
runbook, and a golden fixture that fires it
(docs/testing.md).
- Add the default to the owning role's
defaults/main.yml(see docs/architecture.md for which role owns what). - Document it in that role's
meta/argument_specs.ymlwith atype, adefault, and adescription-- this is whatansible-doc -t rolerenders and what validates an operator's override at role entry.tests/test_argument_specs.pyfails if the spec and the defaults disagree. Do not mark itrequired: every variable must have a working default. - Document it in docs/variable-reference.md and, if it's something most users would touch, in docs/configuration-reference.md.
- Add or update a fixture in
tests/fixtures/if the change affects template rendering, and an assertion intests/test_templates.py. - Add a
CHANGELOG.mdentry under[Unreleased].
roles/vitals_report/templates/dashboard.html.j2 is self-contained by
design -- no external CSS/JS, no CDN links, since it needs to open offline
and survive being emailed or copied around. Keep it that way. After any
change:
- Run
pytest -q(renders the template with representative fixture data and asserts on the output). - Extract and syntax-check the embedded
<script>block:node --checkon its contents catches JS typos pytest won't. - Render a realistic multi-host sample (mixed pass/fail, a
baseline/postcheck comparison) and read through the output for
balanced tags and no leaked
{{ }}/Noneartifacts -- there's no automated visual regression test, so this is a manual step.
- Keep commits scoped and the message focused on why, not just what changed line-by-line.
- Run the full check suite above before opening a PR.
- Update
CHANGELOG.mdunder[Unreleased]for any user-visible change.
-
Bump
versionin galaxy.yml (semantic versioning) and move theCHANGELOG.md[Unreleased]section under the new version heading. -
Run the full check suite, plus a local build/install smoke test:
ansible-galaxy collection build ansible-galaxy collection install sameeralam3127-linux_vitals-*.tar.gz --force ansible-playbook -i examples/inventory/hosts.example.ini sameeralam3127.linux_vitals.healthcheck --syntax-check -
After the release PR is merged, tag the merge commit on
mainand push the tag:git tag -a vX.Y.Z -m "LinuxVitals X.Y.Z" git push origin vX.Y.ZThe tag starts .github/workflows/release.yml, which refuses a tag that does not match
galaxy.yml, re-runs the fast checks, builds, publishes to Galaxy, and confirms the version is live. There is no manualansible-galaxy collection publishstep and no API key on anyone's machine; the key is the repository'sAPI_KEYsecret. -
Verify on the Galaxy collection page that the README, tags, and version rendered as expected.
galaxy.yml's build_ignore already excludes dev-only files (.github/,
.dev-collections/, venv/, inventory/, ansible.cfg,
requirements-dev.txt, test caches) from the shipped tarball.