Contributing to NetBox SSL¶
Thank you for considering a contribution! This guide covers everything you need to know to propose changes, whether a bug fix, a new feature, or documentation.
Before you start¶
- Read the Code of Conduct
- Check the issue tracker to see if someone else is already working on the same thing
- For non-trivial changes, open an issue first to discuss the approach — saves time for everyone
Development environment¶
The recommended setup uses Nix + direnv + uv for reproducible local development, with Docker Compose for the NetBox runtime.
Nix + direnv (recommended)¶
The repo includes a flake.nix that pins Python 3.12, uv, PostgreSQL client, Redis, Docker Compose, and pre-commit. With Nix and direnv installed:
direnv loads the Nix environment automatically each time you cd into the directory.
Alternative: pip + venv¶
git clone https://github.com/ctrl-alt-automate/netbox-ssl.git
cd netbox-ssl
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,docs]"
Docker NetBox¶
The plugin needs a running NetBox to test UI + API changes:
docker-compose up -d
# NetBox is now available at http://localhost:8000 (admin/admin)
# The plugin is mounted into the container for hot-reload
Running tests¶
The project has four test flavours, distinguished by pytest markers:
# Unit tests — fast, no NetBox required
pytest tests/ -m unit -v
# API integration tests — require running NetBox + token
NETBOX_TOKEN="nbt_xxx.yyy" pytest tests/ -m api -v
# Browser tests — require running NetBox + Playwright
pytest tests/ -m browser -v
# Load tests — require running NetBox, not run in CI
cd tests/load && NETBOX_TOKEN="nbt_..." locust -f locustfile.py --host=http://localhost:8000
The unified runner wraps all of these:
python scripts/run_tests.py --quick # unit + parser only
python scripts/run_tests.py --coverage # with coverage report
Unit-test coverage on netbox_ssl/utils/ must stay at or above 70% — CI enforces this via .coveragerc's fail_under = 70. Higher layers (models, views, scripts) are covered by Docker-based integration tests that also run in CI.
Code style¶
We use Ruff for linting and formatting:
CI runs both. If ruff format --check fails, run ruff format locally and commit the result.
Additional style conventions:
- Python: PEP 8, 120-character line length, type annotations on public functions
- Tests: pytest-style, markers for categorisation (
@pytest.mark.unitetc.) - Docstrings: Google style when helpful; keep them short
- Comments: only when the why is non-obvious; prefer good names over comments
Commit conventions¶
We follow Conventional Commits:
<type>: <short description>
<optional body with more detail, why the change matters,
relevant issue numbers, etc.>
Types: feat, fix, docs, test, refactor, chore, ci, perf.
Commits are written in English. Signed commits are appreciated but not required.
Pull request process¶
- Branch from
dev, notmain.maintracks the latest release;devis where unreleased work accumulates. - Make focused commits. Each commit should be one logical change that could be reverted independently.
- Keep the diff focused. Don't reformat unrelated code in the same PR.
- Update tests. New features need new tests. Bug fixes need regression tests.
- Update docs. User-facing changes need
docs/updates. Behaviour changes need aCHANGELOG.mdentry. - Open the PR against
dev. Fill in the PR template. - Address review feedback. Use
fixup!commits during review; the maintainer will squash-merge when ready.
The automated checks on PR are:
- Ruff (lint + format)
- Unit tests on Python 3.10, 3.11, 3.12
- Package check (wheel inclusion)
- Integration tests on NetBox 4.4 and 4.5
- MkDocs strict build (on docs-touching PRs)
- Gemini code review (automatic, informational)
All must pass before merge.
Review SLA¶
Maintainers review PRs on a best-effort basis — typically within 5 business days. For urgent security issues, see SECURITY.md.
Issue labels¶
good-first-issue— approachable for new contributorshelp-wanted— maintainers welcome external contributionsbug/enhancement/documentation— issue typeneeds-triage— not yet categorised by a maintainer
Release process (for maintainers)¶
- Create
release/vX.Y.Zbranch fromdev - Bump version in
pyproject.tomlandnetbox_ssl/__init__.py - Add CHANGELOG
[X.Y.Z]section with Added/Changed/Deprecated/Security - Update COMPATIBILITY.md if NetBox support matrix changes
- Open PR
release/vX.Y.Z → dev, admin-merge after CI + Gemini review - Open PR
dev → main, admin-merge after CI - Tag
vX.Y.Zonmain(signed annotated:git tag -s vX.Y.Z) - Push tag → triggers
publish.yml(PyPI) anddocs.yml(GH Pages) - Close the milestone's issues with link to the release
See versioning.md for the semver policy.
Questions?¶
Open a GitHub Discussion or ping the maintainers on an existing issue. We're happy to help.