Contributing
This guide covers how to set up a development environment for infrahub-sync and contribute to the project. For the release runbook, see RELEASING.md at the repository root — that's maintainer-only.
Prerequisites
- Python 3.10–3.13 (3.12 recommended)
- uv for dependency management
- Git
Setting up your development environment
Clone the repository
git clone https://github.com/opsmill/infrahub-sync.git
cd infrahub-sync
Install uv
If you don't have uv installed, you can install it with:
curl -LsSf https://astral.sh/uv/install.sh | sh
Or see the uv installation guide for other options.
Install dependencies
uv sync --group dev
This installs all runtime and development dependencies defined in pyproject.toml.
Verify your setup
uv run infrahub-sync --help
uv run infrahub-sync list --directory examples/
Install the Git hooks
prek.toml defines the commit hooks: Ruff formatting and lint for Python, rumdl for Markdown
and MDX, and checks for whitespace, YAML, TOML, large files, and private keys. Install them with:
uv run --frozen --extra dev prek install --force
Run the same command in an existing checkout. This project used pre-commit before, and
uv sync removes that package, so the .git/hooks/pre-commit file it generated stops working
and blocks every commit. --force replaces that file. It also overwrites any other script at
that path, so copy your own hook elsewhere first if you keep one there.
Development workflow
Before committing any changes, run the following commands in order:
uv run invoke format # Format code with ruff
uv run invoke lint # Lint code with ruff and pylint
uv run mypy infrahub_sync/ --ignore-missing-imports
Validate the CLI
After making changes, verify the CLI still works:
uv run infrahub-sync --help
uv run infrahub-sync list --directory examples/
uv run infrahub-sync generate --name from-netbox --directory examples/
Running tests
uv run pytest -q
Code standards
Python style
- Python 3.10–3.13 compatible
- Type hints on new or changed code
- Ruff-formatted and lint-clean
- Mypy-checked (do not increase existing error count)
- Public functions and classes require documentation strings
- Raise specific exceptions; avoid broad
except Exception:
Line length
- Maximum line length: 120 characters (configured in
pyproject.toml)
Documentation
If you make user-facing changes (CLI flags, configuration options, new adapters), update the documentation.
Generate command-line documentation
uv run invoke docs.generate
Build documentation site
First-time setup (requires Node.js):
cd docs && npm install
Build the site:
uv run invoke docs.docusaurus
Lint markdown files
npx markdownlint-cli "docs/docs/**/*.{md,mdx}"
npx markdownlint-cli --fix "docs/docs/**/*.{md,mdx}"
Changelog entries
Release notes are written by contributors rather than generated from pull request titles, so every pull request into main must add a news fragment under changelog/. CI fails the pull request if it does not.
Create one with towncrier, naming it after the issue or pull request number:
uv run --extra dev towncrier create -c "Short description of what changed." 123.fixed.md
The file must be a direct child of changelog/ named <id>.<type>.md, where the type is one of security, removed, deprecated, added, changed, fixed, or housekeeping. Use + as the identifier when the change has no issue number, for example +short-slug.housekeeping.md.
Nested paths and unknown types are ignored by towncrier, so the check rejects them rather than let your entry disappear at release time.
If a change genuinely needs no entry — a dependency bump or a typo fix — a maintainer can label the pull request ci/skip-changelog.
Do not edit CHANGELOG.md or the version in pyproject.toml by hand. Both are generated when a release is prepared; see RELEASING.md.
Adding a new adapter
- Create
infrahub_sync/adapters/<name>.pyfollowing existing adapter patterns - Add connection configuration schema and an example under
examples/ - Provide
listanddiffpathways before enablingsync - Document required environment variables and expected error cases
- Create a documentation page in
docs/docs/adapters/ - Add the adapter to the sidebar in
docs/sidebars.ts
Invoke tasks
View all available tasks:
uv run invoke --list
Common tasks:
| Task | Description |
|---|---|
linter.format-ruff | Format Python code with ruff |
linter.lint-ruff | Lint Python code with ruff |
linter.lint-pylint | Lint Python code with pylint |
linter.lint-yaml | Lint YAML files with yamllint |
docs.generate | Generate CLI documentation |
docs.docusaurus | Build documentation website |
format | Alias for ruff format |
lint | Run all linters |