Contributing¶
Thank you for your interest in contributing to gpuctl! This document explains how to set up a development environment, run tests, and submit a PR.
Development Environment Setup¶
Prerequisites¶
- Python 3.8+
- Git
- Access to a Kubernetes cluster (for integration tests, optional)
Clone and Install¶
# 1. Fork the repo and clone
git clone https://github.com/<your-username>/gpuctl.git
cd gpuctl
# 2. Install dev dependencies
pip install -e ".[dev]"
# Or with Poetry
poetry install
Directory Structure¶
gpuctl/
├── gpuctl/
│ ├── api/ # Pydantic data models
│ ├── parser/ # YAML parsing
│ ├── builder/ # K8s resource building
│ ├── client/ # K8s API calls
│ ├── kind/ # Scenario-specific business logic
│ ├── cli/ # CLI command implementations
│ └── constants.py # Global constants
├── server/ # FastAPI service
├── tests/ # Test cases
└── doc/ # Design documents
Running Tests¶
# Run all unit tests
pytest
# Run a specific test file
pytest tests/test_gpuctl.py
# Verbose output
pytest -v
# Generate coverage report
pytest --cov=gpuctl --cov-report=html
Code Conventions¶
Naming¶
- Functions/variables:
snake_case - Class names:
PascalCase - Constants: defined in
gpuctl/constants.py— hardcoding magic strings in other modules is not allowed
Using Constants¶
# Correct ✅
from gpuctl.constants import Kind, Labels
label_value = Kind.TRAINING
# Incorrect ❌
label_value = "training"
Adding a New Job Type¶
To add a new job type (e.g. batch), modify files in this order:
gpuctl/constants.py— add the new Kind to theKindenumgpuctl/api/— add the corresponding Pydantic model filegpuctl/parser/— add or update the parser to support the new Kindgpuctl/builder/— add a Builder implementing thebuild()methodgpuctl/client/job_client.py— add support for the new K8s resource typegpuctl/cli/job.py— handle the new Kind in CLI commandsserver/routes/jobs.py— handle the new Kind in API routestests/— add corresponding test cases
Submitting a PR¶
Branch Naming¶
Commit Message Format¶
feat: add batch job type support
fix: fix service not deleted on job cleanup
docs: update CLI command reference
refactor: move shared label constants to constants.py
test: add inference end-to-end tests
PR Steps¶
# 1. Create a feature branch
git checkout -b feature/my-feature
# 2. Develop and commit
git add .
git commit -m "feat: describe your change"
# 3. Push to your fork
git push origin feature/my-feature
# 4. Open a Pull Request on GitHub
PR Checklist¶
Before submitting, confirm:
- [ ] All
pytesttests pass - [ ] New functionality has corresponding test cases
- [ ] New magic strings are added to
constants.py - [ ] Relevant documentation is updated (CLI reference, user guide, etc.)
- [ ] PR title follows the commit message format
Building Binaries¶
# Install PyInstaller
pip install pyinstaller
# Build Linux binary
pyinstaller --onefile --name="gpuctl-linux-amd64" \
--hidden-import=yaml --hidden-import=PyYAML main.py
# Build Windows binary
pyinstaller --onefile --name="gpuctl-windows-amd64.exe" \
--hidden-import=yaml --hidden-import=PyYAML main.py
# Output is in the dist/ directory
ls dist/
Contributing to Documentation¶
This documentation site is built with MkDocs + Material theme:
# Install doc dependencies
pip install mkdocs mkdocs-material mkdocs-static-i18n
# From the project root
mkdocs serve # Local preview
mkdocs build # Build static files (output to site/)
Documentation source files are in docs/, with mkdocs.yml at the project root. Submit a PR with your changes to update the live site.
Getting Help¶
If you have questions, feel free to reach out:
- GitHub Issues: Submit a bug or feature request
- GitHub Discussions: Join the community discussion