Remove guidance section from CLAUDE.md and add independent versioning design document
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
This project is called "Wild Cloud". Wild Cloud is a platform for managing and orchestrating cloud-native applications on local networks using a network appliance called "Wild Central".
|
||||
|
||||
549
future/independent-versioning.md
Normal file
549
future/independent-versioning.md
Normal file
@@ -0,0 +1,549 @@
|
||||
# Independent Component Versioning (Future Design)
|
||||
|
||||
This document describes a future enhancement for Wild Cloud where each component (API, CLI, Web) can have independent versions while still being bundled together in versioned packages.
|
||||
|
||||
**Status**: Design document for future implementation
|
||||
**Current Implementation**: Unified versioning (single VERSION file)
|
||||
**Migration Path**: Can be implemented once we reach v1.0.0 and need API stability
|
||||
|
||||
---
|
||||
|
||||
## Why Independent Versioning?
|
||||
|
||||
### Current Limitations (Unified Versioning)
|
||||
- CLI can't be updated without releasing entire package
|
||||
- API bug fix requires new package even if CLI/Web unchanged
|
||||
- Can't signal API breaking changes vs CLI enhancements independently
|
||||
- Users can't install just CLI on CI machines with specific version
|
||||
|
||||
### Benefits of Independent Versioning
|
||||
- **CLI Independence**: Download/install CLI separately for CI/automation
|
||||
- **API Stability Signals**: API version communicates breaking changes
|
||||
- **Flexible Release Cadence**: Update components on different schedules
|
||||
- **Better Compatibility Communication**: "CLI v0.9 works with API v1.2-1.3"
|
||||
- **Reduced Package Churn**: Don't republish entire package for small fixes
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Version Files (4 files)
|
||||
|
||||
```
|
||||
wild-cloud/
|
||||
├── VERSION # Package/distribution version: 0.1.1
|
||||
├── api/VERSION # API version: 1.2.3
|
||||
├── cli/VERSION # CLI version: 0.8.1
|
||||
└── web/VERSION # Web version: 0.5.2
|
||||
```
|
||||
|
||||
### Compatibility Matrix
|
||||
|
||||
```yaml
|
||||
# wild-cloud/MANIFEST.yaml
|
||||
package:
|
||||
version: "0.1.1"
|
||||
name: "wild-cloud-central"
|
||||
description: "Wild Cloud Central Management Service"
|
||||
|
||||
components:
|
||||
api:
|
||||
version: "1.2.3"
|
||||
compatibility:
|
||||
min_cli_version: "0.7.0" # Oldest CLI that works
|
||||
max_cli_version: "0.9.x" # Newest CLI tested
|
||||
|
||||
cli:
|
||||
version: "0.8.1"
|
||||
compatibility:
|
||||
min_api_version: "1.1.0" # Oldest API supported
|
||||
max_api_version: "1.2.x" # Newest API supported
|
||||
|
||||
web:
|
||||
version: "0.5.2"
|
||||
compatibility:
|
||||
requires_api_version: "1.2.3" # Exact API version required
|
||||
|
||||
# What combinations have been tested and certified
|
||||
tested_combinations:
|
||||
- package: "0.1.1"
|
||||
api: "1.2.3"
|
||||
cli: "0.8.1"
|
||||
web: "0.5.2"
|
||||
notes: "Stable release, all features tested"
|
||||
|
||||
- package: "0.1.0"
|
||||
api: "1.2.2"
|
||||
cli: "0.8.0"
|
||||
web: "0.5.1"
|
||||
notes: "Previous stable release"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Version Semantics
|
||||
|
||||
### API Version (Server/Backend)
|
||||
**Format**: `MAJOR.MINOR.PATCH`
|
||||
|
||||
- **MAJOR**: Breaking API changes
|
||||
- Endpoints removed or renamed
|
||||
- Request/response format changes
|
||||
- Authentication mechanism changes
|
||||
- Example: `1.2.3` → `2.0.0`
|
||||
|
||||
- **MINOR**: New features, backward compatible
|
||||
- New endpoints added
|
||||
- New optional parameters
|
||||
- New response fields
|
||||
- Example: `1.2.3` → `1.3.0`
|
||||
|
||||
- **PATCH**: Bug fixes only
|
||||
- No API contract changes
|
||||
- Performance improvements
|
||||
- Security patches
|
||||
- Example: `1.2.3` → `1.2.4`
|
||||
|
||||
**Stability Promise**:
|
||||
- CLI version `0.8.x` guaranteed to work with API `1.2.x`
|
||||
- CLI version `0.8.x` should work with API `1.3.x` (newer minor)
|
||||
- CLI version `0.8.x` will NOT work with API `2.0.x` (major bump)
|
||||
|
||||
### CLI Version (Client Tool)
|
||||
**Format**: `MAJOR.MINOR.PATCH`
|
||||
|
||||
- **MAJOR**: Breaking CLI changes
|
||||
- Command structure changes
|
||||
- Flag renames or removal
|
||||
- Configuration format changes
|
||||
- Example: `0.8.1` → `1.0.0`
|
||||
|
||||
- **MINOR**: New features
|
||||
- New commands
|
||||
- New flags (backward compatible)
|
||||
- Can use new API features if available
|
||||
- Example: `0.8.1` → `0.9.0`
|
||||
|
||||
- **PATCH**: Bug fixes and improvements
|
||||
- Error message improvements
|
||||
- Performance fixes
|
||||
- Documentation updates
|
||||
- Example: `0.8.1` → `0.8.2`
|
||||
|
||||
**Compatibility Promise**:
|
||||
- CLI gracefully degrades when API doesn't support new features
|
||||
- `wild app deploy` with new flag works with old API (ignores new features)
|
||||
- CLI checks API version and warns about incompatibilities
|
||||
|
||||
### Web Version (Frontend UI)
|
||||
**Format**: `MAJOR.MINOR.PATCH`
|
||||
|
||||
- **MAJOR**: Major UI redesign or breaking changes
|
||||
- **MINOR**: New features, new pages
|
||||
- **PATCH**: Bug fixes, UX improvements
|
||||
|
||||
**Note**: Web is typically tightly coupled to API and bundled together. Rarely released independently.
|
||||
|
||||
### Package Version (Distribution)
|
||||
**Format**: `MAJOR.MINOR.PATCH`
|
||||
|
||||
- **MAJOR**: Major milestone releases (v1.0.0, v2.0.0)
|
||||
- **MINOR**: New features or significant updates
|
||||
- **PATCH**: Bug fixes, component version bumps
|
||||
|
||||
**Purpose**: Tracks the tested, certified combination of components.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### 1. Build System Changes
|
||||
|
||||
#### Makefile Reads All Versions
|
||||
```makefile
|
||||
# Read all version files
|
||||
PACKAGE_VERSION := $(shell cat ../VERSION 2>/dev/null || echo "0.0.0-dev")
|
||||
API_VERSION := $(shell cat ../api/VERSION 2>/dev/null || echo "0.0.0-dev")
|
||||
CLI_VERSION := $(shell cat ../cli/VERSION 2>/dev/null || echo "0.0.0-dev")
|
||||
WEB_VERSION := $(shell cat ../web/VERSION 2>/dev/null || echo "0.0.0-dev")
|
||||
|
||||
# Version info target
|
||||
version:
|
||||
@echo "Package: v$(PACKAGE_VERSION)"
|
||||
@echo " API: v$(API_VERSION)"
|
||||
@echo " CLI: v$(CLI_VERSION)"
|
||||
@echo " Web: v$(WEB_VERSION)"
|
||||
|
||||
# Build with component versions injected
|
||||
build-api:
|
||||
cd $(API_SOURCE) && GOOS=linux GOARCH=amd64 \
|
||||
go build -ldflags="-X main.Version=$(API_VERSION) -X main.PackageVersion=$(PACKAGE_VERSION)" \
|
||||
-o ../dist/$(AMD64_BINARY) .
|
||||
|
||||
build-cli:
|
||||
cd ../cli && GOOS=linux GOARCH=amd64 \
|
||||
go build -ldflags="-X main.Version=$(CLI_VERSION)" \
|
||||
-o ../dist/build/wild-cli-$(CLI_VERSION)-amd64 .
|
||||
```
|
||||
|
||||
### 2. CLI Version Command with Compatibility Check
|
||||
|
||||
```go
|
||||
// cli/cmd/version.go
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Version = "dev" // Injected at build time
|
||||
|
||||
type APIVersion struct {
|
||||
Version string `json:"version"`
|
||||
MinCLIVersion string `json:"minCliVersion"`
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show version information and API compatibility",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("Wild CLI v%s\n", Version)
|
||||
|
||||
// Try to get API version if connected
|
||||
apiURL := getAPIURL() // From config
|
||||
if apiURL != "" {
|
||||
apiVersion, err := getAPIVersion(apiURL)
|
||||
if err == nil {
|
||||
compatible := checkCompatibility(Version, apiVersion)
|
||||
status := "✓"
|
||||
if !compatible {
|
||||
status = "⚠️"
|
||||
}
|
||||
fmt.Printf("Connected to API v%s %s\n", apiVersion.Version, status)
|
||||
|
||||
if !compatible {
|
||||
fmt.Printf(" Warning: CLI v%s may not be fully compatible with API v%s\n",
|
||||
Version, apiVersion.Version)
|
||||
fmt.Printf(" Recommended CLI version: >= v%s\n", apiVersion.MinCLIVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func getAPIVersion(apiURL string) (*APIVersion, error) {
|
||||
resp, err := http.Get(apiURL + "/api/v1/version")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var version APIVersion
|
||||
if err := json.NewDecoder(resp.Body).Decode(&version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &version, nil
|
||||
}
|
||||
|
||||
func checkCompatibility(cliVersion string, apiVersion *APIVersion) bool {
|
||||
// Simple semantic version comparison
|
||||
// Full implementation would use proper semver library
|
||||
cliMajor := strings.Split(cliVersion, ".")[0]
|
||||
minMajor := strings.Split(apiVersion.MinCLIVersion, ".")[0]
|
||||
|
||||
return cliMajor >= minMajor
|
||||
}
|
||||
```
|
||||
|
||||
### 3. API Version Endpoint
|
||||
|
||||
```go
|
||||
// api/internal/api/v1/handlers_version.go
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var Version = "dev" // Injected at build
|
||||
var PackageVersion = "dev" // Injected at build
|
||||
|
||||
type VersionResponse struct {
|
||||
Version string `json:"version"`
|
||||
PackageVersion string `json:"packageVersion"`
|
||||
MinCLIVersion string `json:"minCliVersion"`
|
||||
MaxCLIVersion string `json:"maxCliVersion"`
|
||||
}
|
||||
|
||||
func (api *API) GetVersion(w http.ResponseWriter, r *http.Request) {
|
||||
respondJSON(w, http.StatusOK, VersionResponse{
|
||||
Version: Version,
|
||||
PackageVersion: PackageVersion,
|
||||
MinCLIVersion: "0.7.0", // Could read from MANIFEST.yaml
|
||||
MaxCLIVersion: "0.9.x",
|
||||
})
|
||||
}
|
||||
|
||||
// Register route in handlers.go
|
||||
// r.HandleFunc("/api/v1/version", api.GetVersion).Methods("GET")
|
||||
```
|
||||
|
||||
### 4. Release Script Support for Component Releases
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/create-release.sh
|
||||
|
||||
PACKAGE_VERSION=$(cat ../VERSION)
|
||||
API_VERSION=$(cat ../api/VERSION)
|
||||
CLI_VERSION=$(cat ../cli/VERSION)
|
||||
WEB_VERSION=$(cat ../web/VERSION)
|
||||
|
||||
RELEASE_TYPE="$1" # "package", "cli", "api"
|
||||
|
||||
case "$RELEASE_TYPE" in
|
||||
"package")
|
||||
# Full package release
|
||||
TAG="v${PACKAGE_VERSION}"
|
||||
TITLE="Wild Cloud Central v${PACKAGE_VERSION}"
|
||||
BODY="Package includes: API v${API_VERSION}, CLI v${CLI_VERSION}, Web v${WEB_VERSION}"
|
||||
|
||||
create_release "$TAG" "$TITLE" "$BODY"
|
||||
upload_debs
|
||||
;;
|
||||
|
||||
"cli")
|
||||
# CLI-only release
|
||||
TAG="cli-v${CLI_VERSION}"
|
||||
TITLE="Wild CLI v${CLI_VERSION}"
|
||||
BODY="Standalone CLI release. Compatible with API v${API_VERSION}"
|
||||
|
||||
create_release "$TAG" "$TITLE" "$BODY"
|
||||
upload_cli_binaries
|
||||
;;
|
||||
|
||||
"api")
|
||||
# API update within existing package
|
||||
TAG="v${PACKAGE_VERSION}"
|
||||
|
||||
if release_exists "$TAG"; then
|
||||
update_release_assets "$TAG"
|
||||
else
|
||||
echo "Package version not changed, updating existing release"
|
||||
update_release_assets "$(get_latest_release_tag)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
### 5. Compatibility Validation Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# scripts/check-compatibility.sh
|
||||
|
||||
MANIFEST="wild-cloud/MANIFEST.yaml"
|
||||
|
||||
API_VERSION=$(cat wild-cloud/api/VERSION)
|
||||
CLI_VERSION=$(cat wild-cloud/cli/VERSION)
|
||||
WEB_VERSION=$(cat wild-cloud/web/VERSION)
|
||||
|
||||
echo "Checking version compatibility..."
|
||||
|
||||
# Check if this combination is in tested_combinations
|
||||
TESTED=$(yq eval ".tested_combinations[] | select(.api == \"$API_VERSION\" and .cli == \"$CLI_VERSION\" and .web == \"$WEB_VERSION\")" "$MANIFEST")
|
||||
|
||||
if [ -n "$TESTED" ]; then
|
||||
echo "✓ Component versions have been tested together"
|
||||
else
|
||||
echo "⚠️ Warning: This combination has not been tested"
|
||||
echo " API: $API_VERSION"
|
||||
echo " CLI: $CLI_VERSION"
|
||||
echo " Web: $WEB_VERSION"
|
||||
echo ""
|
||||
echo "Run full integration tests before release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check CLI compatibility with API
|
||||
MIN_CLI=$(yq eval ".components.api.compatibility.min_cli_version" "$MANIFEST")
|
||||
if version_less_than "$CLI_VERSION" "$MIN_CLI"; then
|
||||
echo "✗ CLI version $CLI_VERSION is older than minimum required $MIN_CLI"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ All compatibility checks passed"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Path
|
||||
|
||||
### Phase 1: Preparation (Current: v0.x.x)
|
||||
- Continue using unified VERSION file
|
||||
- Build foundation for independent versioning
|
||||
- Document API surface and breaking changes
|
||||
|
||||
### Phase 2: Soft Migration (v0.9.x)
|
||||
- Create component VERSION files
|
||||
- Keep them in sync with package VERSION
|
||||
- Add compatibility checking code (unused)
|
||||
- Test infrastructure
|
||||
|
||||
### Phase 3: Independent Releases (v1.0.0+)
|
||||
- Start versioning components independently
|
||||
- First CLI-only release
|
||||
- Update MANIFEST.yaml with compatibility matrix
|
||||
- Enable compatibility warnings
|
||||
|
||||
### Phase 4: Mature State (v1.1.0+)
|
||||
- Components release on different cadences
|
||||
- API maintains backward compatibility
|
||||
- CLI works with multiple API versions
|
||||
- Well-tested compatibility matrix
|
||||
|
||||
---
|
||||
|
||||
## Release Workflows
|
||||
|
||||
### Workflow 1: Bug Fix in API Only
|
||||
```bash
|
||||
# Bump only API version
|
||||
echo "1.2.4" > api/VERSION
|
||||
|
||||
# Optionally bump package patch version
|
||||
echo "0.1.2" > VERSION
|
||||
|
||||
# Build and release
|
||||
make package-all
|
||||
make release-package # Updates/creates v0.1.2 with API v1.2.4
|
||||
```
|
||||
|
||||
### Workflow 2: New CLI Feature (Standalone)
|
||||
```bash
|
||||
# Bump CLI version
|
||||
echo "0.9.0" > cli/VERSION
|
||||
|
||||
# Build CLI
|
||||
cd cli && make build
|
||||
|
||||
# Release CLI independently
|
||||
make release-cli # Creates cli-v0.9.0 tag with standalone binary
|
||||
|
||||
# Users can: wget .../cli-v0.9.0/wild-amd64
|
||||
```
|
||||
|
||||
### Workflow 3: Major Package Release
|
||||
```bash
|
||||
# Bump all versions
|
||||
echo "2.0.0" > api/VERSION # Breaking API changes
|
||||
echo "1.0.0" > cli/VERSION # CLI redesign
|
||||
echo "1.0.0" > web/VERSION # New UI
|
||||
echo "1.0.0" > VERSION # Major package milestone
|
||||
|
||||
# Update MANIFEST.yaml with new compatibility rules
|
||||
vim wild-cloud/MANIFEST.yaml
|
||||
|
||||
# Run compatibility checks
|
||||
./scripts/check-compatibility.sh
|
||||
|
||||
# Build and release
|
||||
make package-all
|
||||
make release-package # Creates v1.0.0
|
||||
```
|
||||
|
||||
### Workflow 4: Hotfix in Testing
|
||||
```bash
|
||||
# Fix bug, no version bump
|
||||
git commit -m "Fix: cluster deletion bug"
|
||||
|
||||
# Rebuild and update current release
|
||||
make package-all
|
||||
make release-package # Updates existing release assets
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Benefits Summary
|
||||
|
||||
### For Users
|
||||
- Download just CLI for automation/CI (smaller, faster)
|
||||
- Know when API changes might break scripts (version signals)
|
||||
- Get bug fixes without reinstalling entire package
|
||||
- Clear compatibility information (`wild --version`)
|
||||
|
||||
### For Developers
|
||||
- Release components independently (faster iteration)
|
||||
- Signal breaking changes appropriately (API major version)
|
||||
- Test combinations in compatibility matrix
|
||||
- Reduce package release churn
|
||||
|
||||
### For DevOps
|
||||
- Pin CLI version in CI/CD pipelines
|
||||
- Upgrade API without updating all CLI installations
|
||||
- Clear upgrade paths and compatibility docs
|
||||
- Automated compatibility checking
|
||||
|
||||
---
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
### Phase 1: Foundation
|
||||
- [ ] Create component VERSION files (keep in sync initially)
|
||||
- [ ] Add version injection to all components
|
||||
- [ ] Create MANIFEST.yaml structure
|
||||
- [ ] Add `GET /api/v1/version` endpoint
|
||||
- [ ] Add `wild version` command with compatibility check
|
||||
|
||||
### Phase 2: Build System
|
||||
- [ ] Update Makefile to read all VERSION files
|
||||
- [ ] Add compatibility validation script
|
||||
- [ ] Create release script for different release types
|
||||
- [ ] Test version injection in builds
|
||||
- [ ] Document version management workflow
|
||||
|
||||
### Phase 3: Release Infrastructure
|
||||
- [ ] Support package releases (current behavior)
|
||||
- [ ] Support CLI-only releases (new tag structure)
|
||||
- [ ] Support updating existing release assets
|
||||
- [ ] Create GitHub/Gitea release templates
|
||||
- [ ] Add CI/CD integration for automated releases
|
||||
|
||||
### Phase 4: Documentation
|
||||
- [ ] Document versioning strategy
|
||||
- [ ] Create compatibility matrix documentation
|
||||
- [ ] Write upgrade guides
|
||||
- [ ] Add troubleshooting for version mismatches
|
||||
- [ ] Create developer guide for version bumping
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **CLI Distribution**: Should CLI be in separate GitHub releases or same repo with different tags?
|
||||
- Recommendation: Same repo, different tags (`cli-v0.9.0`)
|
||||
|
||||
2. **Version Discovery**: Should CLI auto-update check?
|
||||
- Recommendation: No auto-update, but check for new versions on `--version`
|
||||
|
||||
3. **API Version in URL**: Should we support `/api/v2/` for major versions?
|
||||
- Recommendation: Not initially, version in header is sufficient
|
||||
|
||||
4. **Deprecation Policy**: How long to support old API versions?
|
||||
- Recommendation: N-1 major version (API v2.x supports v1.x clients)
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **Kubernetes**: kubectl ±1 minor version skew policy
|
||||
- **Docker**: CLI forward compatibility with engine
|
||||
- **Terraform**: Provider versioning model
|
||||
- **HashiCorp Consul**: API versioning strategy
|
||||
|
||||
This design provides maximum flexibility for component independence while maintaining package simplicity during development.
|
||||
Submodule wild-cloud updated: b0362dc1ca...d0fdb2daf6
Reference in New Issue
Block a user