Contributing
Thank you for your interest in contributing to mjr.wtf! This guide will help you get started.
Releases
Section titled “Releases”Releases are automated:
- Release Please opens/updates a Release PR based on conventional commits.
- Merging that PR creates a semver tag (format:
mjrwtf-vX.Y.Z) and publishes a GitHub Release. - The published release triggers GoReleaser to upload
server+migratebinaries (and checksums), and also triggers the existing Docker publish workflow.
To keep versioning predictable, prefer conventional commits (e.g. feat: ..., fix: ...). Use feat!: ... or a BREAKING CHANGE: footer for breaking changes.
Development Workflow
Section titled “Development Workflow”1. Fork and Clone
Section titled “1. Fork and Clone”git clone <your-fork-url>cd mjrwtf2. Setup Environment
Section titled “2. Setup Environment”Install Code Generation Tools
Section titled “Install Code Generation Tools”# Install sqlc (for database code generation, requires v1.30.0+)
# Install templ (for template code generation)go install github.com/a-h/templ/cmd/templ@latestInitial Setup
Section titled “Initial Setup”# Copy environment configurationcp .env.example .env
# Run tests to verify setup (this will automatically run code generation)make testNote: The make test, make build, and make check targets automatically run code generation, so you don’t need to run sqlc generate or templ generate manually in most cases.
Alternative: You can also use go generate ./... to run code generation directly.
3. Create Feature Branch
Section titled “3. Create Feature Branch”git checkout -b feature/your-feature-name# orgit checkout -b fix/bug-description4. Make Changes
Section titled “4. Make Changes”Follow these guidelines when making changes:
- Hexagonal Architecture: Keep domain logic in
internal/domain/, implementations ininternal/adapters/ - After modifying SQL queries: Run
make generateor justsqlc generate - After modifying templates: Run
make generateor justtempl generate - Before committing: Run
make check(automatically runs code generation, formatting, linting, and tests) - Write tests: All new features and bug fixes require tests
5. Commit Your Changes
Section titled “5. Commit Your Changes”Use conventional commit format:
feat: add URL expiration featurefix: correct click count calculationdocs: update API documentationtest: add tests for URL validationrefactor: simplify repository error handling6. Create Pull Request
Section titled “6. Create Pull Request”- Fill out the PR template completely
- Reference related issues (e.g., “Closes #123”)
- Ensure all tests pass
- Request review from maintainers
Code Quality Standards
Section titled “Code Quality Standards”Tests Required
Section titled “Tests Required”- All new features must have unit tests
- All bug fixes must have regression tests
- Aim for >80% test coverage
- Test both happy path and error cases
- Repository tests must cover SQLite behavior
Linting
Section titled “Linting”- Run
make lintbefore committing - Fix all linter warnings (except known false positives)
- Known false positive: “undefined: sqliterepo” - ignore if tests pass
Documentation
Section titled “Documentation”- Update README.md for user-facing changes
- Update inline comments for complex logic
- Add GoDoc comments for exported functions
- Update schema/migration docs in
docs-site/for database changes (seedocs-site/src/content/docs/operations/)
Commit Messages
Section titled “Commit Messages”Use conventional commits format:
feat:- New featurefix:- Bug fixdocs:- Documentation onlytest:- Adding or updating testsrefactor:- Code change that neither fixes a bug nor adds a featurechore:- Maintenance tasks
For GitHub Copilot
Section titled “For GitHub Copilot”This project is optimized for GitHub Copilot coding agent assistance.
Automated PR Generation
Section titled “Automated PR Generation”When creating issues for Copilot to work on:
- Use issue templates (
.github/ISSUE_TEMPLATE/) - Provide clear acceptance criteria using Given-When-Then format
- List files that need modification
- Specify test requirements
- Note any security implications
What Copilot Can Do
Section titled “What Copilot Can Do”✅ Excellent for:
- Implementing new domain entities with validation
- Adding new repository methods with tests
- Creating database migrations (SQLite)
- Writing sqlc queries
- Adding test cases to existing test suites
- Fixing bugs with clear reproduction steps
- Updating documentation
⚠️ Needs Human Guidance:
- Complex architectural changes spanning multiple layers
- Performance optimization requiring profiling
- Security-critical code (always requires human review)
- Major refactoring (break into smaller issues)
- Production deployment decisions
What Requires Human Review
Section titled “What Requires Human Review”Even when Copilot generates the PR, always review:
- Security implications of changes
- Performance impact of database queries
- Breaking changes to public APIs
- Migration safety (both up and down)
- Test coverage adequacy
- Documentation completeness
Architecture Guidelines
Section titled “Architecture Guidelines”Hexagonal Architecture (Ports & Adapters)
Section titled “Hexagonal Architecture (Ports & Adapters)”Domain Layer (internal/domain/):
- Pure business logic, no external dependencies
- Define entities with validation
- Define repository interfaces (ports)
- Never import database, HTTP, or infrastructure packages
Adapter Layer (internal/adapters/):
- Implement repository interfaces
- Use sqlc-generated code for database access
- Map between domain entities and database models
- Handle database-specific error mapping
Infrastructure Layer (internal/infrastructure/):
- Configuration management
- Logging setup
- Database connection management
- Application initialization
Critical Workflows
Section titled “Critical Workflows”After Changing SQL Queries or Templates
Section titled “After Changing SQL Queries or Templates”make generate # Regenerate database and template code (or just `sqlc generate` / `templ generate`)go build ./... # Verify compilationmake test # Run all tests (automatically runs generation too)Note: If you’re running make test or make build, code generation is automatic.
After Creating Migration
Section titled “After Creating Migration”make build-migrate # Rebuild migrate tool (migrations are embedded, automatically runs generation)make migrate-up # Apply migrationmake migrate-status # Verify migration appliedmake migrate-down # Test rollbackmake migrate-up # Re-apply for final stateBefore Committing
Section titled “Before Committing”make check # Run generate, fmt, vet, lint, test, and validate-openapiNote: make check automatically runs code generation, so you don’t need to run it separately.
Layer Boundaries
Section titled “Layer Boundaries”Dependencies flow inward toward the domain:
Infrastructure → Adapters → Domain ↓ ↓ ↑ Config Repositories Entities Logging (impl) Interfaces Database ValidationRules:
- Domain NEVER imports from adapters or infrastructure
- Adapters import domain interfaces
- Infrastructure wires everything together
Getting Help
Section titled “Getting Help”- Read first:
.github/copilot-instructions.mdhas comprehensive project documentation - Check existing issues: Someone may have already asked
- Check existing PRs: See how similar changes were implemented
- Ask in discussions: For questions before opening issues
- Tag maintainers: For urgent issues or clarifications
Code of Conduct
Section titled “Code of Conduct”Please read and follow CODE_OF_CONDUCT.md.
Quick expectations:
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
- Assume good intentions
License
Section titled “License”By contributing, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to mjr.wtf! 🎉