This guide covers cloning, building, running, and debugging OpenFrame CLI in your local development environment. Follow these steps to get the code running and start contributing.
Before starting local development, ensure you have completed:
- Prerequisites - System requirements and dependencies
- Environment Setup - IDE, tools, and development configuration
-
Fork the repository on GitHub:
- Go to https://github.com/flamingo-stack/openframe-cli
- Click "Fork" in the top-right corner
- Choose your GitHub account
-
Clone your fork:
# Clone your fork git clone https://github.com/YOUR-USERNAME/openframe-cli.git cd openframe-cli # Add upstream remote for syncing git remote add upstream https://github.com/flamingo-stack/openframe-cli.git # Verify remotes git remote -v
For read-only access or testing:
git clone https://github.com/flamingo-stack/openframe-cli.git
cd openframe-cliFamiliarize yourself with the codebase structure:
openframe-cli/
├── main.go # Application entry point
├── go.mod # Go module definition
├── go.sum # Go dependency checksums
├── cmd/ # CLI command definitions
│ ├── root.go # Root command and version info
│ ├── bootstrap/ # Complete environment bootstrap
│ ├── cluster/ # Kubernetes cluster management
│ ├── chart/ # Helm chart and ArgoCD operations
│ └── dev/ # Development workflow tools
├── internal/ # Private application code
│ ├── bootstrap/ # Bootstrap orchestration service
│ ├── cluster/ # Cluster lifecycle management
│ ├── chart/ # Chart installation and ArgoCD integration
│ ├── dev/ # Development tools (intercept, scaffold)
│ └── shared/ # Common utilities and adapters
├── tests/ # Test suites and utilities
│ ├── integration/ # Integration tests
│ ├── mocks/ # Test mocks and fixtures
│ └── testutil/ # Test helper functions
├── docs/ # Documentation
├── examples/ # Usage examples and samples
└── scripts/ # Build and utility scripts
# Build for your current platform
go build -o openframe main.go
# Build with version information
VERSION=$(git describe --tags --always --dirty)
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
go build -ldflags "-X main.version=$VERSION -X main.commit=$COMMIT -X main.date=$DATE" -o openframe main.go
# Test the build
./openframe --versionFor rapid development cycles, run directly with Go:
# Run with go run (rebuilds automatically)
go run main.go --help
# Run specific commands
go run main.go bootstrap --help
go run main.go cluster status
go run main.go chart listInstall and use Air for automatic rebuilds:
# Install Air
go install github.com/cosmtrek/air@latest
# Create .air.toml configuration
cat > .air.toml << 'EOF'
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main main.go"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "docs"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
kill_delay = "0s"
log = "build-errors.log"
send_interrupt = false
stop_on_root = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
time = false
[misc]
clean_on_exit = false
EOF
# Run with hot reload
airNow changes to Go files will automatically trigger rebuilds.
# Run all tests
go test ./...
# Run tests with verbose output
go test -v ./...
# Run tests with coverage
go test -cover ./...
# Generate detailed coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
open coverage.html # macOS
# or xdg-open coverage.html # LinuxIntegration tests require a running Kubernetes cluster:
# Start a test cluster
k3d cluster create openframe-test
# Run integration tests
go test -tags=integration ./tests/integration/...
# Clean up
k3d cluster delete openframe-test# Test specific packages
go test ./internal/cluster/...
go test ./internal/chart/...
go test ./cmd/bootstrap/...
# Test with timeout
go test -timeout=30s ./internal/bootstrap/...
# Run specific tests
go test -run TestClusterCreate ./internal/cluster/...
go test -run TestBootstrapService ./internal/bootstrap/...# Sync with upstream (if using fork)
git fetch upstream
git checkout main
git merge upstream/main
# Create feature branch
git checkout -b feature/your-feature-name
# Or for bug fixes
git checkout -b fix/issue-description- Write Code: Implement your feature or fix
- Write Tests: Add or update tests for your changes
- Run Tests: Ensure all tests pass
- Format Code: Use
gofmtandgoimports - Lint Code: Run
golangci-lint
# Format and organize imports
gofmt -w .
goimports -w .
# Run linter
golangci-lint run
# Run all tests
go test ./...Follow conventional commit format:
# Stage changes
git add .
# Commit with descriptive message
git commit -m "feat(cluster): add support for custom node labels"
git commit -m "fix(bootstrap): handle timeout errors gracefully"
git commit -m "docs(readme): update installation instructions"
# Push to your fork
git push origin feature/your-feature-nameUse the launch configurations from Environment Setup:
- Set breakpoints in your code
- Press F5 or go to Run → Start Debugging
- Choose configuration:
- "Launch OpenFrame CLI" - Debug with
--help - "Debug Bootstrap Command" - Debug bootstrap process
- "Debug Cluster Status" - Debug cluster operations
- "Launch OpenFrame CLI" - Debug with
# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest
# Debug the application
dlv debug main.go -- bootstrap --verbose
# Debug tests
dlv test ./internal/bootstrap/
# Debug with arguments
dlv debug main.go -- cluster create --name=test-cluster(dlv) break main.main # Set breakpoint at main function
(dlv) break bootstrap.go:45 # Set breakpoint at line 45 in bootstrap.go
(dlv) continue # Continue execution
(dlv) next # Execute next line
(dlv) step # Step into function calls
(dlv) print variable_name # Print variable value
(dlv) goroutines # List all goroutines
(dlv) exit # Exit debugger
For quick debugging, add log statements:
package main
import (
"log"
"os"
)
func debugFunction() {
log.Printf("DEBUG: variable value: %+v", variable)
// Pretty print structs
log.Printf("DEBUG: struct: %#v", structVariable)
// Print with file and line info
log.Printf("DEBUG [%s:%d]: message", "filename.go", 123)
}
func init() {
// Enable debug logging during development
if os.Getenv("DEBUG") == "true" {
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
}Run with debug logging:
DEBUG=true go run main.go bootstrapCreate test scenarios to verify your changes:
# Test bootstrap functionality
go run main.go bootstrap --mode=oss-tenant --non-interactive
# Test cluster operations
go run main.go cluster create test-cluster
go run main.go cluster status test-cluster
go run main.go cluster delete test-cluster
# Test chart operations
go run main.go chart install test-app --repo=https://charts.example.com
go run main.go chart list
# Test development tools
go run main.go dev scaffold my-service --template=microservice
go run main.go dev intercept my-service --port=3000:8080Test with real Kubernetes clusters:
# Create test cluster
k3d cluster create openframe-test --agents 2
# Run your changes against the cluster
KUBECONFIG=$(k3d kubeconfig write openframe-test) go run main.go bootstrap
# Verify results
kubectl get pods --all-namespaces
kubectl get applications -n argocd
# Clean up
k3d cluster delete openframe-testMonitor resource usage and performance:
# Build optimized binary
go build -ldflags="-s -w" -o openframe main.go
# Monitor memory usage
/usr/bin/time -v ./openframe bootstrap
# Profile CPU usage
CPUPROFILE=cpu.prof go run main.go bootstrap
go tool pprof cpu.prof
# Profile memory usage
MEMPROFILE=mem.prof go run main.go bootstrap
go tool pprof mem.profRun all quality checks before committing:
#!/bin/bash
# quality-check.sh
echo "Running code quality checks..."
# Format code
echo "Formatting code..."
gofmt -l -w .
goimports -l -w .
# Vet code
echo "Vetting code..."
go vet ./...
# Run linter
echo "Running linter..."
golangci-lint run
# Run tests
echo "Running tests..."
go test -race -cover ./...
# Check for security issues
echo "Checking security..."
gosec ./...
# Check dependencies
echo "Checking dependencies..."
go mod tidy
go mod verify
echo "All checks passed!"Make it executable and run:
chmod +x quality-check.sh
./quality-check.shBefore submitting changes, review:
- Code Structure: Is the code well-organized and follows Go conventions?
- Error Handling: Are errors properly handled and user-friendly?
- Documentation: Are public functions and packages documented?
- Tests: Are there adequate unit and integration tests?
- Performance: Are there any obvious performance issues?
# Add a new dependency
go get github.com/new/dependency@latest
# Update dependencies
go get -u ./...
# Vendor dependencies (if needed)
go mod vendor
# Remove unused dependencies
go mod tidyUse build tags for conditional compilation:
// +build debug
package debug
func init() {
// Debug-only initialization
}# Build with debug tag
go build -tags debug -o openframe-debug main.go
# Run tests with integration tag
go test -tags integration ./...Build for multiple platforms:
# Build for Linux
GOOS=linux GOARCH=amd64 go build -o openframe-linux main.go
# Build for Windows
GOOS=windows GOARCH=amd64 go build -o openframe.exe main.go
# Build for macOS (Intel)
GOOS=darwin GOARCH=amd64 go build -o openframe-darwin-amd64 main.go
# Build for macOS (Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o openframe-darwin-arm64 main.go# Clear module cache
go clean -modcache
# Reinitialize modules
rm go.sum
go mod tidy# Clean build cache
go clean -cache
# Rebuild everything
go build -a main.go# Run tests with verbose output
go test -v -race ./...
# Run specific failing test
go test -v -run TestSpecificFunction ./path/to/package# Check current context
kubectl config current-context
# Switch to correct context
kubectl config use-context k3d-openframe-local
# Verify cluster connectivity
kubectl cluster-infoSet these for debugging:
export GODEBUG="gctrace=1" # GC tracing
export GOTRACEBACK="all" # Full stack traces
export OPENFRAME_LOG_LEVEL="debug" # Detailed logging
export KUBECONFIG="$HOME/.kube/config"Now that you have a working development environment:
- Architecture Overview - Understand the system design
- Contributing Guidelines - Learn the contribution process
- Testing Guide - Deep dive into testing strategies
If you encounter issues:
- Check existing issues: Search GitHub issues for similar problems
- Ask in Slack: Join the OpenMSP community
- Review documentation: Check other guides in this repository
- Debug systematically: Use logging and debugging tools to isolate issues
Happy coding! 🚀