Comprehensive guides and references for the OpenFrame platform
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:
Fork the repository on GitHub:
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-cli
Familiarize 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 --version
For 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 list
Install 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
air
Now 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 # Linux
Integration 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
gofmt and goimportsgolangci-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-name
Use the launch configurations from Environment Setup:
--help# 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 bootstrap
Create 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:8080
Test 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-test
Monitor 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.prof
Run 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.sh
Before submitting changes, review:
# 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 tidy
Use 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-info
Set 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:
If you encounter issues:
Happy coding! 🚀