Skip to content

Commit 5911360

Browse files
committed
Modernize tooling, docs, and README
Made-with: Cursor
1 parent e8e57f8 commit 5911360

40 files changed

Lines changed: 3236 additions & 977 deletions

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: github-actions
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
8+
- package-ecosystem: pip
9+
directory: /
10+
schedule:
11+
interval: weekly

.github/workflows/ci.yml

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,53 @@ on:
77
branches: [main]
88

99
jobs:
10-
build:
10+
test:
1111
runs-on: ubuntu-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
python-version: ["3.10", "3.11", "3.12"]
1216

1317
steps:
1418
- name: Checkout code
15-
uses: actions/checkout@v3
19+
uses: actions/checkout@v4
1620

1721
- name: Set up Python
18-
uses: actions/setup-python@v4
22+
uses: actions/setup-python@v5
1923
with:
20-
python-version: "3.8"
24+
python-version: ${{ matrix.python-version }}
25+
cache: pip
26+
cache-dependency-path: pyproject.toml
2127

2228
- name: Install dependencies
2329
run: |
2430
python -m pip install --upgrade pip
25-
pip install -r requirements.txt
26-
pip install pytest flake8 black
31+
pip install -e ".[dev,ml]" --extra-index-url https://download.pytorch.org/whl/cpu
2732
28-
- name: Lint with flake8
29-
run: flake8 .
33+
- name: Ruff check
34+
run: ruff check .
3035

31-
- name: Check code format with black
32-
run: black --check .
36+
- name: Ruff format
37+
run: ruff format --check .
3338

34-
- name: Run tests with pytest
35-
run: pytest --maxfail=1 --disable-warnings -q
39+
- name: Mypy
40+
run: mypy cloudpilot
41+
42+
- name: Bandit
43+
run: bandit -q -r cloudpilot -c pyproject.toml
44+
45+
- name: Pip audit
46+
run: |
47+
pip freeze > freeze.txt
48+
pip-audit -r freeze.txt --desc on
49+
50+
- name: Run tests with coverage
51+
run: |
52+
pytest --junitxml=junit.xml -q --cov=cloudpilot --cov=cli --cov-report=xml --cov-report=term
53+
54+
- name: Upload coverage artifact
55+
if: matrix.python-version == '3.12'
56+
uses: actions/upload-artifact@v4
57+
with:
58+
name: coverage-xml
59+
path: coverage.xml

.gitignore

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Byte-compiled / optimized
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
7+
# Distribution / packaging
8+
.Python
9+
build/
10+
develop-eggs/
11+
dist/
12+
downloads/
13+
eggs/
14+
.eggs/
15+
lib/
16+
lib64/
17+
parts/
18+
sdist/
19+
var/
20+
wheels/
21+
*.egg-info/
22+
.installed.cfg
23+
*.egg
24+
25+
# Virtual environments
26+
.venv/
27+
venv/
28+
ENV/
29+
env/
30+
31+
# Testing / coverage
32+
.pytest_cache/
33+
.coverage
34+
.coverage.*
35+
htmlcov/
36+
coverage.xml
37+
*.cover
38+
.hypothesis/
39+
40+
# Type checkers / linters
41+
.mypy_cache/
42+
.ruff_cache/
43+
.dmypy.json
44+
dmypy.json
45+
46+
# Editors / OS
47+
.idea/
48+
.vscode/
49+
*.swp
50+
*.swo
51+
.DS_Store
52+
Thumbs.db
53+
54+
# uv
55+
uv.lock.bak
56+
57+
# Local env files
58+
.env
59+
.env.local
60+
61+
# JUnit / CI artifacts
62+
junit.xml
63+
freeze.txt

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.8.4
4+
hooks:
5+
- id: ruff
6+
args: [--fix]
7+
- id: ruff-format

CONTRIBUTING.md

Lines changed: 127 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,151 @@
11
# Contributing to CloudPilot
22

3-
Thank you for your interest in contributing to CloudPilot! Your contributions help make this project better for everyone. Please follow these guidelines when contributing.
3+
Thank you for contributing. This document describes how to set up a development environment, run the same checks as CI, and submit changes.
44

5-
## How to Report Bugs
5+
## Contents
66

7-
- **Search for existing issues:** Before reporting a new bug, please check the [issues](https://github.com/yourusername/CloudPilot/issues) section.
8-
- **Create a new issue:** If the bug hasn’t been reported, create a new issue. Include:
9-
- A clear and descriptive title.
10-
- Steps to reproduce the bug.
11-
- Expected vs. actual behavior.
12-
- Environment details (OS, Python version, etc.).
7+
- [Reporting bugs](#reporting-bugs)
8+
- [Feature requests](#feature-requests)
9+
- [Development setup](#development-setup)
10+
- [Daily workflow](#daily-workflow)
11+
- [Code style and static analysis](#code-style-and-static-analysis)
12+
- [Tests](#tests)
13+
- [Environment variables for local runs](#environment-variables-for-local-runs)
14+
- [Pull requests](#pull-requests)
15+
- [Documentation](#documentation)
16+
- [Communication](#communication)
1317

14-
## Feature Requests
18+
## Reporting bugs
1519

16-
- **Discuss first:** Open an issue to discuss the feature request before submitting code.
17-
- **Provide details:** Describe the feature, its benefits, and any relevant use cases.
20+
- Search existing issues before filing a duplicate.
21+
- 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).
1822

19-
## Pull Request Guidelines
23+
## Feature requests
2024

21-
1. **Fork the Repository:**
22-
Fork the repo and create your branch from the `main` branch.
25+
Open an issue to discuss scope and design before investing in a large pull request.
2326

24-
2. **Code Style:**
25-
- Follow [PEP8](https://www.python.org/dev/peps/pep-0008/) guidelines.
26-
- Run linters such as `flake8` and formatters like `black` before committing.
27-
3. **Write Tests:**
27+
## Development setup
2828

29-
- Add or update tests in the `tests/` directory for your changes.
30-
- Ensure all tests pass with `py -m pytest`.
29+
### Clone and install
3130

32-
4. **Commit Messages:**
31+
```bash
32+
git clone https://github.com/<your-org-or-username>/cloudpilot.git
33+
cd cloudpilot
34+
python -m venv .venv
35+
source .venv/bin/activate # or Windows: .venv\Scripts\Activate.ps1
36+
python -m pip install --upgrade pip
37+
pip install -e ".[dev,ml]" --extra-index-url https://download.pytorch.org/whl/cpu
38+
```
3339

34-
- Write clear, descriptive commit messages.
35-
- Use the present tense (e.g., "Fix bug" not "Fixed bug").
40+
Use the default PyPI index (or a CUDA index) instead of the CPU index if you need GPU builds of PyTorch.
3641

37-
5. **Submit a Pull Request:**
38-
- Provide a clear description of your changes and reference any related issues.
39-
- Follow the repository’s PR template (if available).
42+
### Alternative: uv
4043

41-
## Running Tests Locally
44+
```bash
45+
git clone https://github.com/<your-org-or-username>/cloudpilot.git
46+
cd cloudpilot
47+
uv sync --all-extras
48+
```
4249

43-
- To run all tests:
50+
The first `uv sync` with the `ml` extra may download a large PyTorch wheel.
4451

45-
```bash
46-
py -m pytest
47-
```
52+
### Optional: pre-commit
4853

49-
- Ensure that all tests pass before opening a pull request.
54+
Install hooks so Ruff runs on commit:
55+
56+
```bash
57+
pip install pre-commit
58+
pre-commit install
59+
pre-commit run --all-files # optional one-off check
60+
```
61+
62+
Configuration lives in [`.pre-commit-config.yaml`](.pre-commit-config.yaml). CI does not require pre-commit; it invokes Ruff directly.
63+
64+
## Daily workflow
65+
66+
1. Create a branch from `main`.
67+
2. Make changes with tests.
68+
3. Run `ruff check .`, `ruff format .`, `mypy cloudpilot`, and `pytest` (see below).
69+
4. Open a PR with a clear description and links to issues.
70+
71+
## Code style and static analysis
72+
73+
| Tool | Command | Config |
74+
|------|---------|--------|
75+
| Ruff (lint) | `ruff check .` | [`pyproject.toml`](pyproject.toml) `[tool.ruff]` |
76+
| Ruff (format) | `ruff format .` | same |
77+
| Mypy | `mypy cloudpilot` | `[tool.mypy]` |
78+
| Bandit | `bandit -r cloudpilot -c pyproject.toml` | `[tool.bandit]` |
79+
80+
CI ([`.github/workflows/ci.yml`](.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**.
81+
82+
### Supply chain audit (local)
83+
84+
Mirror the CI step:
85+
86+
```bash
87+
pip freeze > freeze.txt
88+
pip-audit -r freeze.txt --desc on
89+
rm freeze.txt # or delete on Windows: del freeze.txt
90+
```
91+
92+
`freeze.txt` is gitignored; do not commit it.
93+
94+
## Tests
95+
96+
```bash
97+
pytest
98+
```
99+
100+
Pytest defaults are set in [`pyproject.toml`](pyproject.toml) under `[tool.pytest.ini_options]`:
101+
102+
- `addopts` includes `-m 'not integration'`, so tests marked `@pytest.mark.integration` are skipped in the default run.
103+
- Markers include `integration` and `requires_torch` (reserved for tests that assume the optional Torch install).
104+
105+
Run only integration-marked tests:
106+
107+
```bash
108+
pytest -m integration
109+
```
110+
111+
Run with coverage (and optional JUnit, as in CI):
112+
113+
```bash
114+
pytest --junitxml=junit.xml -q --cov=cloudpilot --cov=cli --cov-report=term
115+
```
116+
117+
Coverage reporting uses `[tool.coverage.report] fail_under = 45` in `pyproject.toml`.
118+
119+
### Writing tests
120+
121+
- Prefer **mocking** Kubernetes (`kubernetes.client`), AWS (`boto3`), and Prometheus rather than requiring live services.
122+
- Add or extend tests under [`tests/`](tests/) for behavioral changes.
123+
- Use `@pytest.mark.integration` only for checks that need a real cluster, cloud accounts, or long-running services, and document any required env vars in the test docstring.
124+
125+
## Environment variables for local runs
126+
127+
When exercising `self_heal` or K8s tuning against a real cluster:
128+
129+
| Variable | When to set |
130+
|----------|-------------|
131+
| `CLOUDPILOT_SELF_HEAL_CONFIRM=1` | Only if you intend to delete non-Running pods (dangerous on shared clusters). |
132+
| `CLOUDPILOT_K8S_DRY_RUN=1` | To exercise tuning logic without `patch_namespaced_deployment`. |
133+
134+
See [README.md](README.md) for the full list.
135+
136+
## Pull requests
137+
138+
1. Fork the repository and branch from `main`.
139+
2. Keep commits focused; use present-tense, imperative messages (for example: `Add dry-run guard for deployment patch`).
140+
3. Ensure Ruff, Mypy, and pytest pass locally.
141+
4. Describe what changed and why; reference related issues.
50142

51143
## Documentation
52144

53-
- **Update Documentation:**
54-
If you add new features or change functionality, please update the README and other documentation accordingly.
145+
Update [README.md](README.md) for user-facing behavior, install paths, env vars, or CLI changes. Update this file when contributor workflow or CI steps change.
55146

56147
## Communication
57148

58-
- Use GitHub issues and pull requests to communicate your ideas and progress.
59-
- For major changes, open an issue to discuss your approach before starting to code.
149+
Use GitHub issues and pull requests. For substantial refactors or API changes, open an issue first to agree on direction.
60150

61-
Thank you for contributing to CloudPilot! Your efforts help make this project better for the entire community.
151+
Thank you for helping improve CloudPilot.

0 commit comments

Comments
 (0)