Thank you for your interest in contributing! This project follows a set of guidelines to ensure code quality and consistency.
-
Fork the repository on GitHub
-
Clone your fork:
git clone https://github.com/PlatformStackPulse/go-template.git cd go-template -
Setup development environment:
make dev-setup
-
Create a feature branch:
git checkout -b feature/my-awesome-feature
- Review existing issues and PRs to avoid duplicates
- Open an issue first for significant changes
- Discuss your approach with maintainers
-
Ensure tests pass:
make test -
Follow code style:
make fmt lint
-
Run security checks:
make security
-
Commit with conventional format:
git commit -m "feat: add new feature" git commit -m "fix: resolve issue"
All commits must follow the Conventional Commits specification:
Format:
<type>(<scope>): <description>
<optional body>
<optional footer>
Types:
feat— A new featurefix— A bug fixdocs— Documentation only changesstyle— Changes that don't affect code meaning (formatting, etc.)refactor— Code change that neither fixes bugs nor adds featuresperf— Code change that improves performancetest— Adding missing tests or correcting existing testschore— Changes to build process, dependencies, etc.ci— Changes to CI configurationbuild— Changes to build system
Examples:
feat: add support for feature flags
feat(cli): add hello command
fix: resolve nil pointer exception
fix(logger): fix timestamp formatting
docs: update README with examples
chore: upgrade Go to 1.22
- Add tests for new features
- Update tests for bug fixes
- Follow table-driven test pattern
- Use
testifyfor assertions
func TestSomething(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{
name: "test case 1",
input: "input",
expected: "output",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
result := MySomething(tc.input)
assert.Equal(t, tc.expected, result)
})
}
}make test # Run all tests
make test-unit # Unit tests only
make test-integration # Integration tests only
make coverage # Generate coverage report- Follow Effective Go guidelines
- Use
gofmtfor formatting - Run
golangci-lintregularly
make fmt
make lintThe template follows Clean Architecture principles:
internal/
├── domain/ # Pure business entities (no external deps)
│ └── greeter.go # Example: Domain entity with business logic
├── usecase/ # Business logic orchestration
│ └── greeting.go # Example: Orchestrates domain + adapters
├── adapter/ # External integrations (database, HTTP, etc)
│ └── (empty - add as needed)
├── cli/ # CLI interface layer
│ ├── root.go # Root command
│ └── hello.go # Example command
├── config/ # Configuration loading
├── logger/ # Structured logging
└── errors/ # Error types (if needed)
test/
├── unit/ # Unit tests (mirrors internal/)
│ ├── domain/
│ ├── usecase/
│ ├── cli/
│ └── config/
└── integration/ # Integration/end-to-end tests
Domain Layer (Pure Business Logic)
// test/unit/domain/greeter_test.go
func TestGreeterGreet(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{name: "greet with name", input: "Alice", expected: "Hello, Alice!"},
{name: "greet without name", input: "", expected: "Hello, World!"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
greeter := domain.NewGreeter(tc.input)
assert.Equal(t, tc.expected, greeter.Greet())
})
}
}Usecase Layer (Orchestration)
- Mock adapters/repositories
- Verify business logic flow
- Test error handling
CLI Layer
- Mock logger and usecase
- Test command parsing and flags
- Verify output format
- Update README if adding features
- Add comments to exported functions
- Update CHANGELOG for significant changes
- Use clear, concise language
-
Push your changes:
git push origin feature/my-awesome-feature
-
Create a Pull Request on GitHub
-
PR Title: Must follow Conventional Commits
feat: add new feature fix: resolve issue -
PR Description:
- Clear description of changes
- Reference related issues (#123)
- Explain motivation and impact
-
Wait for review:
- Ensure all checks pass
- Respond to feedback
- Make requested changes
- PR title follows Conventional Commits
- All tests pass (
make test) - Coverage maintained/improved
- Linting passes (
make lint) - Security checks pass (
make security) - Documentation updated
- No breaking changes (or documented if breaking)
- Commits follow Conventional Commits
- Create command file in
internal/cli/:
// internal/cli/mycommand.go
package cli
import (
"github.com/spf13/cobra"
"github.com/PlatformStackPulse/go-template/internal/logger"
)
func NewMyCommand(log *logger.Logger) *cobra.Command {
return &cobra.Command{
Use: "mycommand",
Short: "Description",
RunE: func(cmd *cobra.Command, args []string) error {
log.Info("Command started")
// Your logic here
return nil
},
}
}- Register in
cmd/app/main.go:
cmd.AddCommand(cli.NewMyCommand(log))- Add tests in
test/unit/cli/:
func TestMyCommand(t *testing.T) {
// Test command execution
}- Define entity in
internal/domain/ - Create usecase in
internal/usecase/ - Write unit tests for both
- Update CLI to use the usecase
- Minimum: 70% coverage required
- Target: 80%+ coverage for new code
- Check coverage locally:
make coverage - View report:
open coverage.html
- At least one approval required
- All checks must pass
- CI/CD pipeline must succeed
- Maintainer will merge when ready
- 📖 Check documentation
- 🐛 Open an issue
- 💬 Start a discussion
By contributing to this project, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing! 🙏