Thank you for your interest in contributing to hz! This document provides guidelines and instructions for contributing.
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
- Go 1.21 or later
- Git
- ngrok account (for tunnel testing)
# Clone the repository
git clone https://github.com/zymawy/hz.git
cd hz
# Install dependencies
go mod download
# Build the project
go build -o hz .
# Run tests
go test ./...hz/
├── cmd/hz/ # CLI command implementations
├── internal/ # Private packages
│ ├── config/ # Configuration loading and hot-reload
│ ├── proxy/ # HTTP/WebSocket reverse proxy
│ ├── registry/ # Service registry and health checks
│ ├── router/ # Route matching engine
│ └── tunnel/ # ngrok tunnel management
├── pkg/types/ # Public shared types
└── main.go # Entry point
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/hz.git
cd hz
git remote add upstream https://github.com/zymawy/hz.gitgit checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fixFollow these guidelines:
- Code Style: Follow standard Go conventions (
gofmt,golint) - Testing: Add tests for new functionality
- Documentation: Update docs for user-facing changes
- Commits: Write clear, descriptive commit messages
# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Build and test manually
go build -o hz .
./hz init --force
./hz add test 8080
./hz statusgit push origin feature/your-feature-nameThen open a pull request on GitHub with:
- Clear description of changes
- Related issue numbers (if applicable)
- Screenshots for UI changes
| Package | Purpose |
|---|---|
cmd/hz |
CLI commands (Cobra) |
internal/config |
YAML parsing, hot-reload |
internal/proxy |
Request forwarding |
internal/registry |
Service management |
internal/router |
Route matching |
internal/tunnel |
ngrok integration |
pkg/types |
Shared type definitions |
// Wrap errors with context
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
// Use meaningful error messages
return fmt.Errorf("service '%s' not found", name)// Use the provided logger
logger.Printf("starting proxy on %s", addr)
// Include relevant context
logger.Printf("health check failed for %s: %v", svc.Name, err)func TestRouter_Match(t *testing.T) {
// Setup
router := router.New()
// Test
route := router.Match(req)
// Assert
if route == nil {
t.Error("expected route match")
}
}- Create
cmd/hz/yourcommand.go:
package hz
import (
"github.com/spf13/cobra"
)
var yourCmd = &cobra.Command{
Use: "yourcommand",
Short: "Brief description",
RunE: runYourCommand,
}
func init() {
rootCmd.AddCommand(yourCmd)
}
func runYourCommand(cmd *cobra.Command, args []string) error {
// Implementation
return nil
}- Add tests in
cmd/hz/yourcommand_test.go - Update README.md with usage examples
- Update
pkg/types/types.gowith new RouteConfig field - Update
internal/router/router.gowith matching logic - Update
cmd/hz/add.goto parse new route type - Add tests and documentation
- Add field to appropriate struct in
pkg/types/types.go - Add default value in
internal/config/config.go - Add validation if needed
- Update documentation
- Code follows Go conventions
- Tests added/updated
- Documentation updated
- Commit messages are clear
- No breaking changes (or clearly documented)
- Works on Linux, macOS, and Windows
When reporting issues, include:
- hz version (
hz --version) - Go version (
go version) - Operating system
- Steps to reproduce
- Expected vs actual behavior
- Relevant config (sanitized)
- Open a GitHub issue for bugs or features
- Start a discussion for questions or ideas
Thank you for contributing!