This file provides AI agent context for working with the HyperFleet Adapter codebase.
Language: Go 1.25.0+ Build System: Make Test Framework: Go testing + Testcontainers Linter: golangci-lint (managed via bingo)
make build # Build binary → bin/hyperfleet-adapter
make fmt # Format code with goimports
make lint # Run golangci-lint
make tidy # Tidy dependencies
make verify # Run fmt-check and vetmake test # Unit tests only (fast)
make test-integration # Integration tests with envtest (unprivileged, CI-safe)
make test-all # All checks: lint, unit, integration, and helm tests
make test-coverage # Generate coverage reportmake image # Build image
make image-push # Build and push to quay.io/openshift-hyperfleet/hyperfleet-adapter
QUAY_USER=myuser make image-dev # Build and push to personal QuayBefore committing code, run these in order:
make fmt- Format codemake lint- Check lintingmake test- Unit testsmake test-integration- Integration tests (ormake test-all)make build- Ensure binary builds
pkg/ # Exported packages (can be imported by other projects)
├── constants/ # Shared constants (annotations, labels)
├── errors/ # Error handling utilities with codes
├── health/ # Health and metrics HTTP servers
├── logger/ # Structured logging with context
├── metrics/ # Prometheus metrics recorder
├── otel/ # OpenTelemetry tracing
├── utils/ # General utilities
└── version/ # Version info
internal/ # Internal packages (not importable)
├── configloader/ # YAML config loading + validation
├── criteria/ # Precondition and CEL evaluation
├── dryrun/ # Dry-run API client and recording transport
├── executor/ # Event execution pipeline (phases)
├── generation/ # Generation tracking
├── hyperfleetapi/ # HyperFleet API client
├── k8sclient/ # Kubernetes client wrapper
├── maestroclient/ # Maestro ManifestWork client
├── manifest/ # Manifest generation and rendering
└── transportclient/ # Unified apply interface
cmd/adapter/ # Main entry point
test/integration/ # Integration tests
charts/ # Helm chart
configs/ # Config templates and examples
scripts/ # Build scripts
Always use structured logging with context:
logger.Info(ctx, "message")
logger.Error(ctx, "error occurred")
// Add structured fields via context or logger chaining
ctx = logger.WithLogField(ctx, "cluster_id", clusterID)
log := logger.With("resource", name).With("error", err)Never use fmt.Printf or log.Println - use the logger package.
Use typed error constructors from pkg/errors:
return errors.NotFound("cluster %s not found", clusterID)
return errors.KubernetesError("failed to get resource: %v", err)
return errors.ConfigurationError("invalid config: %v", err)Always propagate errors up with context, don't silently ignore them.
All long-running operations must accept context.Context as first parameter:
func ProcessEvent(ctx context.Context, event cloudevents.Event) errorUse logger.WithLogField(ctx, key, value) or logger.WithLogFields(ctx, fields) to attach structured fields to the context for logging.
CEL expressions in config must use exact field names from the CEL environment:
<param_name>- extracted parameters are injected as top-level variables (e.g.,clusterID, notparams.clusterID)resources.*- discovered resources (post-phase), e.g.,resources.myClusteradapter.*- adapter metadata (name, status, etc.)- Custom functions:
now()(RFC3339 timestamp),toJson(val),dig(map, "dot.path")
Configuration uses snake_case (Viper convention):
adapter.name,clients.hyperfleet_api.base_url
Code uses camelCase (Go convention):
AdapterName,HyperFleetAPIBaseURL
Helm uses camelCase (Helm convention)
adapterConfig,baseUrl
- Do not modify files in
.bingo/- these are managed by bingo - Do not edit
go.summanually - usemake tidy
- Do not skip integration tests in PRs - they run in CI and catch real issues
- Do not mock Kubernetes clients in integration tests - use envtest/K3s
- Do not use time.Sleep in tests - use context timeouts or test utilities
- Do not add hardcoded values - use configuration or environment variables
- Do not add CLI flags without also supporting env vars (Viper convention)
- Do not change config field names without migration path (breaking change)
- Do not add dependencies without license check (Apache 2.0 compatible only)
- Do not update hyperfleet-broker without verifying metric compatibility
- Do not vendor dependencies - this project uses Go modules
- Do not force push to main or release branches
- Do not amend published commits - create new commits
- Do not commit
.envfiles, credentials, or sensitive data
- Do not break backward compatibility in config schema without version bump
- Do not change CloudEvent types without coordinating with HyperFleet API team
- Do not modify status payload schema without API spec update
Use subtests for multiple scenarios:
func TestFunction(t *testing.T) {
tests := []struct {
name string
input string
want string
wantErr bool
}{
{"valid", "input", "output", false},
{"invalid", "", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Function(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("unexpected error: %v", err)
}
if got != tt.want {
t.Errorf("got %v, want %v", got, tt.want)
}
})
}
}Use testcontainers for real dependencies:
func TestIntegration(t *testing.T) {
ctx := context.Background()
env := testutil.SetupEnvTest(t, ctx) // Sets up K8s API
defer env.Teardown()
// Test with real K8s client
}- Add extractor to
internal/executor/param_extractor.go - Add tests in same package
- Document in
docs/configuration.md - Add example in
configs/adapter-task-config-template.yaml
- Add evaluator to
internal/criteria/evaluator.go - Add tests with mock clients
- Update schema in
internal/configloader/types.go - Document in adapter authoring guide
- Define metric in
pkg/metrics/recorder.go - Instrument code with metric calls
- Add Prometheus query to
docs/metrics.md - Add recommended alert to
docs/alerts.md
Version follows semver (MAJOR.MINOR.PATCH):
- Version is derived from
APP_VERSIONinMakefile(auto-set from git tags viagit describe) - Update
CHANGELOG.mdwith release notes - Tag:
git tag -a v0.2.0 -m "Release v0.2.0" - Push:
git push origin v0.2.0 - CI builds and pushes image with version tag