Thank you for your interest in contributing to MoMorph CLI! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Development Workflow
- Code Standards
- Testing
- Pull Request Process
- Release Process
By participating in this project, you agree to abide by our Code of Conduct. Please be respectful and inclusive in all interactions.
- Go 1.25 or higher
- Git
- Make (optional, for using Makefile targets)
- GoReleaser (for release builds)
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/momorph-cli.git
cd momorph-cli- Add upstream remote:
git remote add upstream https://github.com/momorph/cli.gitgo mod download# Build binary
go build -o momorph .
# Or use make
make build# Run directly
go run main.go <command>
# Or use built binary
./momorph <command>main- Production-ready codedevelop- Integration branch for featuresfeature/*- Feature branchesfix/*- Bug fix branchesdocs/*- Documentation updates
# Fetch latest changes
git fetch upstream
git checkout main
git merge upstream/main
# Create feature branch
git checkout -b feature/your-feature-nameFollow the Conventional Commits specification:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Examples:
feat(auth): add MoMorph token exchange
fix(init): handle empty directory correctly
docs(readme): update installation instructions
test(login): add integration tests for OAuth flow
- Follow the official Go Code Review Comments
- Use
gofmtandgoimportsfor formatting - Use
golangci-lintfor linting
# Run linter
golangci-lint run
# Or use make
make lint- Use the
internal/errorspackage for CLI errors - Wrap errors with context using
fmt.Errorf("context: %w", err) - Provide user-friendly error messages
- Log technical details for debugging
- Use the
internal/loggerpackage - Use
logger.Debug()for detailed information - Use
logger.Info()for important events - Never log sensitive data (tokens, passwords)
- Config files:
0600 - Config directories:
0700 - Public files:
0644 - Public directories:
0755
# Run all tests
go test ./...
# Run with verbose output
go test -v ./...
# Run with coverage
go test -cover ./...
# Run specific package
go test ./tests/integration/...
# Run specific test
go test -run TestHelpRootCommand ./tests/integration/...- Place unit tests in the same package as the code
- Place integration tests in
tests/integration/ - Use
testify/assertfor assertions - Use table-driven tests when appropriate
- Mock external services for unit tests
func TestFunctionName(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{"case1", "input1", "expected1"},
{"case2", "input2", "expected2"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := FunctionName(tt.input)
assert.Equal(t, tt.expected, result)
})
}
}- Ensure all tests pass:
go test ./... - Run linter:
golangci-lint run - Update documentation if needed
- Add/update tests for new functionality
- Rebase on latest upstream main
- Push your branch to your fork
- Create a Pull Request against
main - Fill in the PR template
- Request review from maintainers
- Tests pass
- Linter passes
- Documentation updated
- Commit messages follow convention
- No merge conflicts
- PRs require at least one approval
- Address all review comments
- Keep PRs focused and small when possible
- Squash commits before merging if requested
Releases are automated using GoReleaser and GitHub Actions.
# Create version tag
git tag v1.0.0
git push origin v1.0.0GoReleaser creates:
- Binary releases for Linux, macOS, Windows (amd64, arm64)
- Checksums
- Homebrew formula
- Changelog
# Create snapshot release
goreleaser release --snapshot --clean
# Build only
goreleaser build --snapshot --cleanIf you have questions, please:
- Check existing issues
- Search the documentation
- Open a new issue with the "question" label
Thank you for contributing! 🚀