Thank you for your interest in contributing to kubenow! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Submitting Changes
- Code Style
- Project Structure
Be respectful, constructive, and professional in all interactions.
- Go ≥ 1.25
- kubectl configured with access to a Kubernetes cluster (for testing)
- make (for build automation)
- git
- golangci-lint (optional, for local linting)
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/kubenow.git
cd kubenow
# Add upstream remote
git remote add upstream https://github.com/ppiankov/kubenow.gitmake depsThis downloads all Go modules and tidies dependencies.
make buildBinary will be created at bin/kubenow.
make testmake lintNote: If golangci-lint is not installed:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \
sh -s -- -b $(go env GOPATH)/binCreate a feature branch from main:
git checkout -b feature/my-new-feature
# or
git checkout -b fix/bug-descriptionBranch naming conventions:
feature/*- New featuresfix/*- Bug fixesdocs/*- Documentation updatesrefactor/*- Code refactoringtest/*- Test improvements
Follow Conventional Commits:
type: concise imperative statement
Lowercase after colon, no period. Max 72 chars.
Types: feat, fix, docs, refactor, test, chore, perf, ci, build
Examples:
feat: add requests-skew analysis command
fix: handle empty prometheus response
docs: update architecture diagram
Body (optional, separated by blank line) for WHY, not WHAT.
# Run all tests
make test
# Run specific package tests
go test ./internal/analyzer -v
# Run with coverage
make test-coverage# Run integration tests (requires Kubernetes cluster)
go test ./test/integration -v- Write tests for new features
- Maintain or improve code coverage
- Use table-driven tests where appropriate
- Mock external dependencies (Prometheus, Kubernetes API)
Example test structure:
func TestMyFeature(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{"case1", "input1", "output1"},
{"case2", "input2", "output2"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := MyFeature(tt.input)
assert.Equal(t, tt.expected, result)
})
}
}-
Run all checks:
make check
-
Ensure tests pass:
make test -
Update documentation if needed
-
Add or update tests for your changes
-
Push your branch:
git push origin feature/my-new-feature
-
Open a Pull Request on GitHub
-
Fill in the PR template:
- Description of changes
- Related issue numbers
- Testing performed
- Screenshots (if UI changes)
- CI checks must pass (tests, lint, build)
- At least one approving review required
- Maintainers may request changes
- Be responsive to feedback
- Squash commits if requested
- Maintainer will merge when ready
Follow standard Go conventions:
- Use
gofmtfor formatting - Follow Effective Go
- Use meaningful variable names
- Add comments for exported functions
We use golangci-lint with configuration in .golangci.yml.
Key rules:
- Max line length: 140 characters
- Max cyclomatic complexity: 15
- Required error checking
- No unused code
# Format code
make fmt
# Run vet
make vetkubenow/
├── cmd/
│ └── kubenow/ # Main entry point
├── internal/
│ ├── analyzer/ # Analysis logic (requests-skew, node-footprint)
│ ├── cli/ # CLI commands (Cobra)
│ ├── export/ # Export formats (JSON, Markdown, HTML)
│ ├── llm/ # LLM client
│ ├── metrics/ # Prometheus integration
│ ├── models/ # Data models
│ ├── prompt/ # LLM prompt templates
│ ├── result/ # Result rendering
│ ├── snapshot/ # Kubernetes snapshot collection
│ ├── util/ # Utilities
│ └── watch/ # Watch mode
├── test/
│ ├── fixtures/ # Test data
│ └── integration/ # Integration tests
├── docs/ # Documentation
├── .github/workflows/ # CI/CD
├── Makefile # Build automation
├── .golangci.yml # Linter config
└── go.mod # Go modules
-
Create command file:
# internal/cli/mycommand.go -
Implement command:
package cli import "github.com/spf13/cobra" var myCmd = &cobra.Command{ Use: "mycommand", Short: "My command description", RunE: runMyCommand, } func init() { rootCmd.AddCommand(myCmd) // Add flags } func runMyCommand(cmd *cobra.Command, args []string) error { // Implementation return nil }
-
Add tests:
# internal/cli/mycommand_test.go -
Update documentation
- Create analyzer in
internal/analyzer/ - Implement analyzer logic
- Create CLI command in
internal/cli/ - Add unit tests
- Update README with examples
- Update
internal/metrics/query.go - Add query builder method
- Test with mock Prometheus
- Document query purpose
- Update
internal/prompt/templates.go - Test with local LLM
- Verify JSON response parsing
- Update result rendering if schema changes
- GitHub Issues: Report bugs or request features
- Discussions: Ask questions
- Documentation: Read the docs
Contributors will be recognized in:
- Release notes
- GitHub contributors page
- Changelog
Thank you for contributing to kubenow! 🙏