Contributing¶
Thank you for considering contributing to WireBuddy! This guide will help you get started.
Code of Conduct¶
Our Pledge¶
We pledge to make participation in our project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity, experience level, nationality, personal appearance, race, religion, or sexual identity and orientation.
Our Standards¶
Positive behavior:
- ✅ Using welcoming and inclusive language
- ✅ Being respectful of differing viewpoints
- ✅ Gracefully accepting constructive criticism
- ✅ Focusing on what is best for the community
Unacceptable behavior:
- ❌ Trolling, insulting/derogatory comments, personal attacks
- ❌ Public or private harassment
- ❌ Publishing others' private information
- ❌ Other conduct which could reasonably be considered inappropriate
How to Contribute¶
Reporting Bugs¶
Found a bug? Please open an issue on GitHub:
Before creating an issue:
- Check existing issues (open and closed)
- Update to latest version and test again
- Collect debug information
Bug report should include:
- Title: Short, descriptive summary
- Description: Detailed explanation of the issue
- Steps to reproduce: Clear steps to reproduce the bug
- Expected behavior: What should happen
- Actual behavior: What actually happens
- Environment:
- WireBuddy version
- Docker version
- Host OS and version
- Browser (if UI issue)
- Logs: Relevant log output (use ``` code blocks)
- Screenshots: If applicable
Example:
### Bug: DNS queries not being blocked
**Description:**
DNS ad-blocking is not working. All queries are allowed even with blocklists enabled.
**Steps to Reproduce:**
1. Enable DNS resolver
2. Enable StevenBlack blocklist
3. Restart DNS resolver
4. Query known ad domain: `nslookup ad.doubleclick.net 10.8.0.1`
5. Query is allowed instead of blocked
**Expected:** Query should be blocked
**Actual:** Query resolves to IP address
**Environment:**
- WireBuddy: 1.3.2
- Docker: 24.0.7
- Host OS: Ubuntu 22.04
- Browser: Chrome 120
**Logs:**
Requesting Features¶
Have an idea? Open a feature request:
Feature request should include:
- Title: Clear feature name
- Problem: What problem does this solve?
- Solution: Proposed solution
- Alternatives: Other solutions considered
- Additional context: Screenshots, mockups, examples
Example:
### Feature: Two-Factor Authentication via SMS
**Problem:**
Some users don't have smartphones with authenticator apps and need SMS-based MFA.
**Proposed Solution:**
Add SMS as an MFA option alongside TOTP.
**Alternatives Considered:**
- Email-based codes (less secure)
- Hardware tokens only (expensive)
**Additional Context:**
- Could integrate with Twilio or similar
- Should be optional (admin configurable)
Pull Requests¶
Ready to contribute code?
Before starting:
- Check existing PRs (avoid duplicates)
- Open an issue first (for large changes)
- Fork the repository
- Create a feature branch
Development process:
-
Fork and clone:
-
Create branch:
-
Make changes:
- Follow code style (see below)
- Add tests for new features
-
Update documentation
-
Test:
-
Commit:
Use Conventional Commits: - feat: New feature - fix: Bug fix - docs: Documentation only - style: Formatting, missing semi-colons, etc. - refactor: Code change that neither fixes a bug nor adds a feature - perf: Performance improvement - test: Adding tests - chore: Updating build tasks, package manager configs, etc.
-
Push:
-
Create PR:
- Go to GitHub and create Pull Request
- Fill in PR template
- Link related issues
Pull request checklist:
- Code follows project style guidelines
- Tests added/updated (if applicable)
- Documentation added/updated (if applicable)
- All tests pass (
pytest) - No linting errors (
ruff check .) - Type checking passes (
mypy app/) - Commits follow conventional commit format
- PR description is clear and complete
Code Style¶
Python¶
Style guide: PEP 8 (enforced by Black and Ruff)
Tools:
- Formatter: Black
- Linter: Ruff
- Type checker: mypy
Run before committing:
Type hints:
def create_peer(name: str, ip: str, interface: str) -> Peer:
pass
# Use Optional for nullable
from typing import Optional
def get_user(user_id: int) -> Optional[User]:
pass
# Use List, Dict for collections
from typing import List, Dict
def list_peers() -> List[Peer]:
pass
Docstrings:
def create_peer(name: str, ip: str) -> Peer:
"""
Create a new WireGuard peer.
Args:
name: Descriptive peer name
ip: IP address in CIDR notation
Returns:
Peer: Created peer object
Raises:
ValueError: If IP is invalid
PeerExistsError: If peer already exists
"""
pass
JavaScript¶
Style:
- Use modern ES6+ syntax
- const/let (no var)
- Arrow functions preferred
- Semicolons required
Example:
const fetchPeers = async () => {
try {
const response = await fetch('/api/peers');
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch peers:', error);
throw error;
}
};
HTML/CSS¶
- Indent with 2 spaces
- Bootstrap 5 classes preferred
- Custom CSS in
wb-ui-system.css - Follow existing patterns
Testing¶
Writing Tests¶
import pytest
from fastapi.testclient import TestClient
from app.main import app
@pytest.fixture
def client():
return TestClient(app)
@pytest.fixture
def admin_token(client):
"""Get admin API token."""
response = client.post("/api/auth/login", json={
"username": "admin",
"password": "admin"
})
return response.json()["token"]
def test_create_peer(client, admin_token):
"""Test peer creation."""
response = client.post(
"/api/peers",
headers={"Authorization": f"Bearer {admin_token}"},
json={
"name": "Test Peer",
"interface": "wg0",
"ip": "10.8.0.100"
}
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Peer"
assert data["ip"] == "10.8.0.100"
def test_create_peer_duplicate(client, admin_token):
"""Test duplicate peer creation fails."""
# Create first peer
client.post("/api/peers", headers={"Authorization": f"Bearer {admin_token}"}, json={...})
# Attempt duplicate
response = client.post("/api/peers", headers={"Authorization": f"Bearer {admin_token}"}, json={...})
assert response.status_code == 409
Running Tests¶
# All tests
pytest
# Specific test file
pytest tests/test_api.py
# Specific test
pytest tests/test_api.py::test_create_peer
# With coverage
pytest --cov=app --cov-report=html
# Verbose
pytest -v
# Stop on first failure
pytest -x
Documentation¶
Code Comments¶
# Good: Explain why, not what
# Generate random token for CSRF protection (crypto-safe)
token = secrets.token_urlsafe(32)
# Bad: Obvious comment
# Create a token
token = secrets.token_urlsafe(32)
Docstrings¶
All public functions, classes, and modules should have docstrings.
Documentation Pages¶
When adding features, update relevant docs:
docs/features/- Feature documentationdocs/api/- API documentationdocs/configuration/- Configuration guidesREADME.md- Update if needed
Git Workflow¶
Branch Naming¶
feature/feature-name- New featuresfix/bug-description- Bug fixesdocs/what-changed- Documentationrefactor/what-changed- Refactoringtest/what-tested- Tests only
Commit Messages¶
Follow Conventional Commits:
Examples:
feat(dns): add DNS-over-HTTPS support
Implement DoH in addition to DoT for upstream queries.
Includes configuration UI and Unbound integration.
Closes #123
fix(auth): prevent session fixation attack
Regenerate session ID after successful login to prevent
session fixation vulnerability.
Keeping Fork Updated¶
# Add upstream remote (once)
git remote add upstream https://github.com/Gill-Bates/wirebuddy.git
# Fetch upstream changes
git fetch upstream
# Merge into main
git checkout main
git merge upstream/main
# Update feature branch
git checkout feature/my-feature
git rebase main
Review Process¶
PR Review¶
All PRs are reviewed by maintainers:
- Automated checks: Tests, linting, type checking
- Code review: Maintainer reviews code
- Feedback: Maintainer may request changes
- Approval: Once approved, PR is merged
Addressing Feedback¶
PR automatically updates.
Release Process¶
(For maintainers)
- Update
VERSIONfile - Update
CHANGELOG.md - Create git tag:
git tag v1.3.3 - Push tag:
git push --tags - GitHub Actions builds and publishes Docker image
- Create GitHub release with notes
Security Vulnerabilities¶
Do not open public issues for security vulnerabilities.
Email: [security contact - update as needed]
Include:
- Vulnerability description
- Steps to reproduce
- Impact assessment
- Suggested fix (if any)
Getting Help¶
- GitHub Issues: Questions, bugs, features
- GitHub Discussions: General discussion, ideas
- Discord: (if/when created) Real-time chat
Recognition¶
Contributors are recognized in:
- GitHub contributors list
CHANGELOG.md(for significant contributions)- Special thanks in release notes
Thank you for contributing to WireBuddy! 🎉