Contributing¶
Thank you for contributing to CIS Benchmark CLI!
Documentation Path
You are here: Developer Guide > Contributing
- For architecture: See Architecture Overview
- For testing: See Testing Guide
- For data flow: See Data Flow Pipeline
Git Workflow¶
IMPORTANT: This project uses semantic-release for automated versioning.
Branch-Based Development (Required)¶
DO NOT commit directly to main. Always work on feature/fix branches:
# Create a feature branch
git checkout -b feat/add-new-capability
# Or a fix branch
git checkout -b fix/resolve-bug
# Make changes and commit
git commit -m "feat: add new capability"
# Push branch to GitHub
git push origin feat/add-new-capability
# Create Pull Request to main
gh pr create --title "Add new capability" --body "Description..."
Why Branch-Based Development?¶
- Semantic-release runs on
mainand creates version commits - Working directly on
maincauses constant rebase conflicts - PRs allow code review before merging to
main - Clean git history with automated releases
Conventional Commits¶
All commits must follow Conventional Commits:
feat:- New feature (minor version bump)fix:- Bug fix (patch version bump)docs:- Documentation onlychore:- Maintenance tasksrefactor:- Code refactoringtest:- Test changes
Development Setup¶
Prerequisites¶
- Python 3.12+ (modern Python)
- uv (fast Python package manager)
- Git
Setup with uv (Recommended)¶
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone repository
git clone https://github.com/mitre/cis-bench.git
cd cis-bench
# Install dependencies (creates .venv automatically)
uv sync --all-extras
# Install pre-commit hooks
uv run pre-commit install
# Verify setup
uv run pytest tests/
Alternative: Setup with pip¶
# Clone repository
git clone https://github.com/mitre/cis-bench.git
cd cis-bench
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install with dev dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install
# Verify setup
pytest tests/
Code Quality Standards¶
WE DO NOT COMMIT BROKEN CODE¶
Before ANY commit:
- All tests must pass
- All linting must pass
- No ruff errors
- No bandit security issues
Pre-commit hooks enforce this automatically.
Testing Requirements¶
Write Tests for ALL Code¶
Coverage required:
- Unit tests for functions/classes
- Integration tests for components
- E2E tests for CLI commands
Test file naming:
Test Isolation¶
All tests must use isolated databases:
- Unit tests:
tmp_pathfixtures - E2E tests:
CIS_BENCH_ENV=test(automatic) - NO touching production data
See: Testing Guide
Architecture Principles¶
1. Config-Driven, Not Hardcoded¶
DO:
DON'T:
2. Loop Through Config¶
DO:
DON'T:
3. No Direct XCCDF Imports¶
DO:
DON'T:
Why: Version-agnostic (supports XCCDF 1.1.4 and 1.2).
Adding Features¶
Adding New Export Format¶
Example: Add PDF export
-
Create exporter:
-
Add to
__init__.py: -
Write tests:
-
Use:
Adding New XCCDF Style¶
Summary:
1. Create {style}_style.yaml in configs/
2. Define field mappings
3. No code changes needed!
Coding Standards¶
Python Style¶
- PEP 8 compliance (enforced by ruff)
- Type hints where helpful
- Docstrings for all public functions/classes
- Descriptive names (no abbreviations)
Documentation¶
- Docstrings: Google style
- Comments: Explain WHY, not WHAT
- TODOs: Include issue number
Commit Messages¶
Format:
type: Short description
Longer explanation if needed.
- Bullet points for changes
- Reference issues: #123
Authored by: Your Name <email@example.com>
Types:
feat:New featurefix:Bug fixdocs:Documentationtest:Testsrefactor:Code restructuringchore:Maintenance
Git Workflow¶
Branch Strategy¶
main- Production-ready code- Feature branches for new work
Commit Rules¶
ONE CHANGE PER COMMIT:
- Do not mix features
- Separate logical changes
- Each commit should build
NEVER:
git add .orgit add -A- Commit without testing
- Commit broken code
ALWAYS:
# Add files specifically
git add file1.py file2.py
# Run tests first
pytest tests/
# Then commit
git commit -m "feat: Add specific feature"
Code Review¶
Before Submitting PR¶
- [ ] All tests pass (405+)
- [ ] Ruff linting passes
- [ ] Bandit security scan passes
- [ ] Documentation updated
- [ ] Commit messages clear
- [ ] No debug code left
- [ ] Reviewed own changes
PR Description¶
Include:
- What changed
- Why it changed
- How to test
- Related issues
Architecture Compliance¶
Tests Enforce Architecture¶
Architecture compliance tests will FAIL if you:
- Hardcode field lists instead of looping config
- Import XCCDF models directly
- Add hardcoded field checks (
if field_name == "title")
See: tests/unit/test_architecture_compliance.py
Design Documents¶
Follow the design:
- Read design docs before implementing
- Do not improvise or "improve"
- If design is wrong, update design FIRST, then code
Development Environment¶
Recommended Setup¶
# Use dev environment
export CIS_BENCH_ENV=dev
# Your work goes to ~/.cis-bench-dev/
# Production stays clean
Running Tests¶
# All tests
pytest tests/
# Specific module
pytest tests/unit/test_catalog_database.py
# With coverage
pytest tests/ --cov=src/cis_bench
# Verbose
pytest tests/ -v
Release Process¶
(When maintainer releases):
- Update version in
pyproject.toml - Update CHANGELOG.md
- Run full test suite
- Tag release:
git tag v1.0.0 - Build:
python -m build - Publish:
twine upload dist/*
Getting Help¶
Documentation¶
- Read existing docs in
docs/ - Check architecture diagrams
- Review YAML config reference
Ask Questions¶
- GitHub Discussions
- Issues (for bugs)
Code of Conduct¶
Be professional, respectful, and collaborative.
See Also¶
- Architecture - System design
- Testing Guide - Test practices
- How to Add XCCDF Style - Extension guide