Thank you for contributing. This document describes how to set up a development environment, run the same checks as CI, and submit changes.
- Reporting bugs
- Feature requests
- Development setup
- Daily workflow
- Code style and static analysis
- Tests
- Environment variables for local runs
- Pull requests
- Documentation
- Communication
- Search existing issues before filing a duplicate.
- Include a clear title, minimal steps to reproduce, expected vs actual behavior, and environment details (OS, Python version, how you installed CloudPilot, relevant env vars).
Open an issue to discuss scope and design before investing in a large pull request.
git clone https://github.com/<your-org-or-username>/cloudpilot.git
cd cloudpilot
python -m venv .venv
source .venv/bin/activate # or Windows: .venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -e ".[dev,ml]" --extra-index-url https://download.pytorch.org/whl/cpuUse the default PyPI index (or a CUDA index) instead of the CPU index if you need GPU builds of PyTorch.
git clone https://github.com/<your-org-or-username>/cloudpilot.git
cd cloudpilot
uv sync --all-extrasThe first uv sync with the ml extra may download a large PyTorch wheel.
Install hooks so Ruff runs on commit:
pip install pre-commit
pre-commit install
pre-commit run --all-files # optional one-off checkConfiguration lives in .pre-commit-config.yaml. CI does not require pre-commit; it invokes Ruff directly.
- Create a branch from
main. - Make changes with tests.
- Run
ruff check .,ruff format .,mypy cloudpilot, andpytest(see below). - Open a PR with a clear description and links to issues.
| Tool | Command | Config |
|---|---|---|
| Ruff (lint) | ruff check . |
pyproject.toml [tool.ruff] |
| Ruff (format) | ruff format . |
same |
| Mypy | mypy cloudpilot |
[tool.mypy] |
| Bandit | bandit -r cloudpilot -c pyproject.toml |
[tool.bandit] |
CI (.github/workflows/ci.yml) runs Ruff (check + format check), Mypy, Bandit, pip-audit on a frozen environment, and pytest with coverage on Python 3.10, 3.11, and 3.12.
Mirror the CI step:
pip freeze > freeze.txt
pip-audit -r freeze.txt --desc on
rm freeze.txt # or delete on Windows: del freeze.txtfreeze.txt is gitignored; do not commit it.
pytestPytest defaults are set in pyproject.toml under [tool.pytest.ini_options]:
addoptsincludes-m 'not integration', so tests marked@pytest.mark.integrationare skipped in the default run.- Markers include
integrationandrequires_torch(reserved for tests that assume the optional Torch install).
Run only integration-marked tests:
pytest -m integrationRun with coverage (and optional JUnit, as in CI):
pytest --junitxml=junit.xml -q --cov=cloudpilot --cov=cli --cov-report=termCoverage reporting uses [tool.coverage.report] fail_under = 45 in pyproject.toml.
- Prefer mocking Kubernetes (
kubernetes.client), AWS (boto3), and Prometheus rather than requiring live services. - Add or extend tests under
tests/for behavioral changes. - Use
@pytest.mark.integrationonly for checks that need a real cluster, cloud accounts, or long-running services, and document any required env vars in the test docstring.
When exercising self_heal or K8s tuning against a real cluster:
| Variable | When to set |
|---|---|
CLOUDPILOT_SELF_HEAL_CONFIRM=1 |
Only if you intend to delete non-Running pods (dangerous on shared clusters). |
CLOUDPILOT_K8S_DRY_RUN=1 |
To exercise tuning logic without patch_namespaced_deployment. |
See README.md for the full list.
- Fork the repository and branch from
main. - Keep commits focused; use present-tense, imperative messages (for example:
Add dry-run guard for deployment patch). - Ensure Ruff, Mypy, and pytest pass locally.
- Describe what changed and why; reference related issues.
Update README.md for user-facing behavior, install paths, env vars, or CLI changes. Update this file when contributor workflow or CI steps change.
Use GitHub issues and pull requests. For substantial refactors or API changes, open an issue first to agree on direction.
Thank you for helping improve CloudPilot.