Contributing to Borgitory
Thank you for your interest in contributing to Borgitory! This guide will help you get started with contributing to the project.
Getting Started
Code of Conduct
By participating in this project, you agree to abide by our Code of Conduct. Please be respectful and constructive in all interactions.
Ways to Contribute
Bug Reports - Help us identify and fix issues
Feature Requests - Suggest new functionality
Documentation - Improve guides, API docs, and examples
Code Contributions - Fix bugs, implement features, improve performance
Testing - Write tests, test new features, report compatibility issues
Community Support - Help other users in discussions and issues
Development Setup
Prerequisites
Python 3.11 or higher
Git
BorgBackup installed and in PATH
Rclone (optional, for cloud sync features)
Docker (optional, for containerized development)
Setting Up the Development Environment
Fork and Clone the Repository
# Fork the repository on GitHub, then clone your fork git clone https://github.com/YOUR_USERNAME/Borgitory.git cd Borgitory
Create a Virtual Environment
# Create virtual environment python -m venv .env_borg # Activate virtual environment # On Windows: .env_borg\Scripts\activate # On macOS/Linux: source .env_borg/bin/activate
Install Dependencies
# Install in development mode with all dependencies pip install -e .[dev]
Set Up Pre-commit Hooks (Optional but Recommended)
# Install pre-commit pip install pre-commit # Install hooks pre-commit install
Run the Development Server
# Start development server with auto-reload python run.py # Or using the CLI borgitory serve --reload --log-level debug
Verify Installation
Open http://localhost:8000 in your browser
Create a test account and repository
Run the test suite:
pytest
Development Workflow
Branch Strategy
main - Stable release branch
develop - Integration branch for new features
feature/* - Feature development branches
bugfix/* - Bug fix branches
hotfix/* - Critical fixes for production
Workflow:
Create a feature branch from
developMake your changes
Write or update tests
Ensure all tests pass
Submit a pull request to
develop
Making Changes
Before You Start:
Check existing issues and pull requests
Create an issue for discussion (for significant changes)
Ensure you understand the project architecture
Development Guidelines:
Follow Code Style
# Run linting ruff check . # Auto-fix issues ruff check . --fix # Type checking mypy src/
Write Tests
# Run all tests pytest # Run with coverage pytest --cov=borgitory # Run specific test file pytest tests/test_repositories.py
Update Documentation
Update docstrings for new functions/classes
Update README if needed
Add entries to CHANGELOG.md
Update API documentation if applicable
Code Style Guidelines
Python Code Style
We follow PEP 8 with some modifications:
Line length: 88 characters (Black default)
Imports: Use isort for import sorting
Type hints: Required for all public functions
Docstrings: Google-style docstrings
Example:
from typing import Optional, List
from pydantic import BaseModel
class Repository(BaseModel):
"""Repository configuration model.
Args:
name: Human-readable repository name
path: Filesystem path to repository
passphrase: Encryption passphrase
Attributes:
id: Unique repository identifier
created_at: Creation timestamp
"""
name: str
path: str
passphrase: str
id: Optional[int] = None
def validate_path(self) -> bool:
"""Validate repository path exists and is accessible.
Returns:
True if path is valid and accessible
Raises:
ValueError: If path is invalid
"""
# Implementation here
pass
Frontend Guidelines
HTML Templates:
Use semantic HTML elements
Include ARIA attributes for accessibility
Follow BEM naming convention for CSS classes
Use Tailwind utility classes consistently
JavaScript/Alpine.js:
Keep JavaScript minimal and focused
Use Alpine.js directives for reactivity
Prefer HTMX for server interactions
Comment complex logic
CSS/Tailwind:
Use Tailwind utility classes
Create custom components for repeated patterns
Ensure responsive design
Test in multiple browsers
Testing Guidelines
Test Structure
tests/
├── conftest.py # Pytest configuration and fixtures
├── unit/ # Unit tests
│ ├── test_models.py
│ ├── test_services.py
│ └── test_utils.py
├── integration/ # Integration tests
│ ├── test_api_endpoints.py
│ ├── test_backup_workflow.py
│ └── test_cloud_sync.py
└── fixtures/ # Test data and fixtures
├── repositories.json
└── sample_configs.py
Writing Tests
Unit Tests:
import pytest
from unittest.mock import Mock, patch
from borgitory.services.borg_service import BorgService
class TestBorgService:
"""Test BorgService functionality."""
@pytest.fixture
def borg_service(self):
"""Create BorgService instance for testing."""
return BorgService()
def test_create_repository_success(self, borg_service):
"""Test successful repository creation."""
with patch('subprocess.run') as mock_run:
mock_run.return_value.returncode = 0
result = borg_service.create_repository(
path="/tmp/test-repo",
passphrase="test-passphrase"
)
assert result.success is True
mock_run.assert_called_once()
Integration Tests:
import pytest
from httpx import AsyncClient
from borgitory.main import app
@pytest.mark.asyncio
class TestRepositoryAPI:
"""Test repository API endpoints."""
async def test_create_repository(self):
"""Test repository creation via API."""
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post(
"/api/repositories",
json={
"name": "Test Repo",
"path": "/tmp/test-repo",
"passphrase": "secure-passphrase"
}
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Repo"
Test Best Practices:
Write tests for both success and failure cases
Use descriptive test names
Keep tests isolated and independent
Mock external dependencies
Use fixtures for common test data
Aim for good test coverage (80%+)
Documentation Guidelines
Documentation Types
Code Documentation - Docstrings and inline comments
API Documentation - OpenAPI/Swagger specs
User Documentation - Installation, usage, and how-to guides
Developer Documentation - Architecture and contributing guides
Writing Documentation
Docstrings:
def create_backup(
self,
repository: Repository,
source_path: str,
archive_name: str,
compression: str = "lz4"
) -> Job:
"""Create a new backup job.
Creates a backup job that will archive the specified source path
to the given repository using BorgBackup.
Args:
repository: Target repository for the backup
source_path: Path to directory or file to backup
archive_name: Name for the created archive
compression: Compression algorithm (lz4, zlib, lzma, zstd)
Returns:
Job instance representing the backup operation
Raises:
ValueError: If source_path doesn't exist
RepositoryError: If repository is inaccessible
Example:
>>> service = BackupService()
>>> repo = Repository(name="docs", path="/repos/docs")
>>> job = service.create_backup(repo, "/home/user/docs", "docs-20231201")
>>> print(f"Backup job created: {job.id}")
"""
README Updates:
Keep installation instructions current
Update feature lists when adding functionality
Include relevant badges and links
Provide clear usage examples
Changelog:
Follow Keep a Changelog format:
## [Unreleased]
### Added
- New cloud provider support for DigitalOcean Spaces
- Archive browser file search functionality
### Changed
- Improved backup progress reporting
- Updated Docker base image to Python 3.11
### Fixed
- Fixed repository connection timeout issues
- Resolved FUSE mounting permissions on some systems
Submitting Changes
Pull Request Process
Prepare Your Changes
# Ensure your branch is up to date git checkout develop git pull upstream develop git checkout your-feature-branch git rebase develop
Run Quality Checks
# Run all quality checks python lint.py all # Run tests pytest # Check type hints mypy src/
Commit Your Changes
# Stage changes git add . # Commit with descriptive message git commit -m "feat: add support for DigitalOcean Spaces cloud provider - Implement DigitalOcean Spaces storage class - Add configuration validation and tests - Update provider registry and templates - Add documentation and examples Closes #123"
Push and Create Pull Request
# Push to your fork git push origin your-feature-branch # Create pull request on GitHub
Pull Request Guidelines:
Use a descriptive title
Include a detailed description of changes
Reference related issues
Include screenshots for UI changes
Ensure all checks pass
Be responsive to review feedback
Commit Message Format
We follow Conventional Commits:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types:
feat- New featurefix- Bug fixdocs- Documentation changesstyle- Code style changes (formatting, etc.)refactor- Code refactoringtest- Adding or updating testschore- Maintenance tasks
Examples:
feat(cloud-sync): add Azure Blob Storage support
fix: resolve FUSE mounting permission issues on Ubuntu
docs: update installation guide with Docker Compose examples
test: add integration tests for backup scheduling
Review Process
What We Look For:
Code quality and style compliance
Test coverage for new functionality
Documentation updates
Backward compatibility
Security considerations
Performance impact
Review Stages:
Automated Checks - CI/CD pipeline runs
Code Review - Maintainers review code
Testing - Manual testing if needed
Approval - At least one maintainer approval required
Merge - Squash and merge to develop branch
Community Guidelines
Getting Help
GitHub Discussions - General questions and community support
GitHub Issues - Bug reports and feature requests
Documentation - Check existing docs first
Code Review - Ask questions during review process
Communication
Be respectful and constructive
Provide context and examples
Be patient with responses
Help others when you can
Follow up on your issues and PRs
Recognition
Contributors are recognized in:
CONTRIBUTORS.md file
Release notes for significant contributions
GitHub contributors page
Special mentions in project communications
Project Maintenance
Release Process
Version Planning - Decide on next version features
Feature Freeze - Stop adding new features
Testing - Comprehensive testing of release candidate
Documentation - Update all documentation
Release - Tag version and publish
Post-Release - Monitor for issues and feedback
Release Schedule:
Major releases - Every 6-12 months
Minor releases - Every 2-3 months
Patch releases - As needed for critical fixes
Issue Triage
Issue Labels:
bug- Something isn’t workingenhancement- New feature or improvementdocumentation- Documentation relatedgood first issue- Good for newcomershelp wanted- Community help requestedpriority: high- Critical issuesstatus: needs-info- Waiting for more information
Triage Process:
Initial Review - Validate issue and add labels
Prioritization - Assign priority and milestone
Assignment - Assign to maintainer or contributor
Progress Tracking - Monitor progress and provide updates
Resolution - Close when fixed and verified
Thank You
Your contributions make Borgitory better for everyone. Whether you’re fixing a typo, adding a feature, or helping other users, every contribution is valuable and appreciated.
For questions about contributing, please:
Check the existing documentation
Search existing issues and discussions
Create a new discussion or issue
Reach out to maintainers
Happy contributing! 🎉