-
Notifications
You must be signed in to change notification settings - Fork 19
HYPERFLEET-930 - docs: rewrite CLAUDE.md as AGENTS.md #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kuudori
wants to merge
5
commits into
openshift-hyperfleet:main
Choose a base branch
from
kuudori:HYPERFLEET-930
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
044a954
HYPERFLEET-930 - docs: rewrite CLAUDE.md as AGENTS.md with @import pa…
kuudori 225c5f9
HYPERFLEET-930 - chore: enable gci import ordering via golangci-lint
kuudori 3db6ae6
HYPERFLEET-930 - style: run gci import reordering across all Go files
kuudori 2bc0b66
HYPERFLEET-930 - chore: add pre-commit hooks via hyperfleet-hooks
kuudori e2007af
HYPERFLEET-930 - fix: correct CEL adapter.* field names in convention…
kuudori File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| default_install_hook_types: [pre-commit, commit-msg] | ||
|
|
||
| repos: | ||
| - repo: https://github.com/openshift-hyperfleet/hyperfleet-hooks | ||
| rev: v0.2.1 | ||
| hooks: | ||
| - id: hyperfleet-commitlint | ||
| stages: [commit-msg] | ||
| - id: hyperfleet-gofmt | ||
| - id: hyperfleet-golangci-lint | ||
| - id: hyperfleet-go-vet |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| # HyperFleet Adapter | ||
|
|
||
| Event-driven Kubernetes resource manager. Consumes CloudEvents from a message broker, executes configured actions (K8s resource apply, HyperFleet API calls, Maestro ManifestWork), and reports status back. | ||
|
|
||
| Go 1.25.0 · Cobra CLI · Viper config · golangci-lint (bingo-managed) · Tekton CI (Konflux) | ||
|
|
||
| ## Verification Checklist | ||
|
|
||
| ```bash | ||
| make fmt # Format code + imports (golangci-lint fmt with gci) | ||
| make lint # golangci-lint (config: .golangci.yml) | ||
| make test # Unit tests with race detection (excludes test/ dir) | ||
| make test-integration # Integration tests via testcontainers (needs Docker/Podman) | ||
| make build # Build binary → bin/hyperfleet-adapter | ||
| ``` | ||
|
|
||
| `make test-all` runs all of the above plus `make test-helm`. Pre-commit hooks: `make install-hooks`. | ||
|
|
||
| ## CLI | ||
|
|
||
| Subcommands: `adapter serve`, `adapter config-dump`, `adapter version`. Config paths via `-c`/`HYPERFLEET_ADAPTER_CONFIG` and `-t`/`HYPERFLEET_TASK_CONFIG`. All flags have env var equivalents — run `adapter serve --help`. | ||
|
|
||
| Dry-run mode: `adapter serve --dry-run-event event.json` processes a single event with mock clients, no broker or cluster needed. | ||
|
|
||
| ## Two Config Files | ||
|
|
||
| Adapter loads two configs merged at startup: deployment config (`adapter-config.yaml` — infra, clients, logging) and task config (`adapter-task-config.yaml` — params, preconditions, resources, post-actions). Override rules differ — see Gotchas. Templates in `configs/`. | ||
|
|
||
| ## Source of Truth | ||
|
|
||
| | Topic | Location | | ||
| |-------|----------| | ||
| | Configuration reference | `docs/configuration.md` | | ||
| | Adapter authoring guide | `docs/adapter-authoring-guide.md` | | ||
| | Metrics & Prometheus queries | `docs/metrics.md` | | ||
| | Alerts | `docs/alerts.md` | | ||
| | Runbook | `docs/runbook.md` | | ||
| | Helm chart | `charts/` | | ||
| | CI pipelines | `.tekton/` (Konflux/Tekton PipelineRuns) | | ||
|
|
||
| ## Code Conventions | ||
|
|
||
| @docs/conventions/logging.md | ||
| @docs/conventions/cel.md | ||
|
|
||
| ### Error Handling | ||
|
|
||
| `pkg/errors` provides ServiceError constructors for API-style errors with numeric codes and HTTP status: | ||
|
|
||
| ```go | ||
| errors.NotFound("cluster %s not found", clusterID) // → *ServiceError | ||
| errors.KubernetesError("failed to get resource: %v", err) | ||
| ``` | ||
|
|
||
| IMPORTANT: These return `*ServiceError`, not `error`. Use `.AsError()` to convert. | ||
|
|
||
| ## Boundaries | ||
|
|
||
| - Every CLI flag must have a corresponding env var (Viper convention) | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - IMPORTANT: **Two config files, different override rules.** Deployment config supports env/flag overrides via Viper. Task config is pure YAML — env vars do nothing there. Mixing them up wastes debugging time. | ||
| - IMPORTANT: **Naming conventions differ by layer.** Config YAML: `snake_case` (`subscription_id`). Go code: `CamelCase` (`SubscriptionID`). Helm values: `camelCase` (`subscriptionId`). Wrong casing silently drops values. | ||
| - **Tracing default mismatch.** Binary defaults to tracing ON. Helm chart defaults to OFF. Local `adapter serve` will attempt OTLP export unless you set `HYPERFLEET_TRACING_ENABLED=false`. | ||
| - **Integration tests build a container on first run.** `make test-integration` calls `make image-integration-test` if `INTEGRATION_ENVTEST_IMAGE` is unset. First run takes minutes. | ||
|
|
||
| ## Non-Obvious Packages | ||
|
|
||
| - `internal/executor/` — event execution pipeline (params → preconditions → resources → post-actions) | ||
| - `internal/transportclient/` — unified apply interface abstracting K8s direct and Maestro ManifestWork | ||
|
|
||
| ## Links | ||
|
|
||
| - [Architecture Docs](https://github.com/openshift-hyperfleet/architecture) | ||
| - [HyperFleet API Spec](https://github.com/openshift-hyperfleet/hyperfleet-api-spec) | ||
| - [Broker Library](https://github.com/openshift-hyperfleet/hyperfleet-broker) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,263 +1 @@ | ||
| # Claude Code Context for HyperFleet Adapter | ||
|
|
||
| This file provides AI agent context for working with the HyperFleet Adapter codebase. | ||
|
|
||
| ## Quick Reference | ||
|
|
||
| **Language:** Go 1.25.0+ | ||
| **Build System:** Make | ||
| **Test Framework:** Go testing + Testcontainers | ||
| **Linter:** golangci-lint (managed via bingo) | ||
|
|
||
| ## Essential Commands | ||
|
|
||
| ### Build and Verify | ||
|
|
||
| ```bash | ||
| 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 vet | ||
| ``` | ||
|
|
||
| ### Testing | ||
|
|
||
| ```bash | ||
| make 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 report | ||
| ``` | ||
|
|
||
| ### Container Images | ||
|
|
||
| ```bash | ||
| make 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 Quay | ||
| ``` | ||
|
|
||
| ## Validation Checklist | ||
|
|
||
| Before committing code, run these in order: | ||
|
|
||
| 1. `make fmt` - Format code | ||
| 2. `make lint` - Check linting | ||
| 3. `make test` - Unit tests | ||
| 4. `make test-integration` - Integration tests (or `make test-all`) | ||
| 5. `make build` - Ensure binary builds | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| 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 | ||
| ``` | ||
|
|
||
| ## Code Conventions | ||
|
|
||
| ### Logging | ||
|
|
||
| Always use structured logging with context: | ||
|
|
||
| ```go | ||
| 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. | ||
|
|
||
| ### Error Handling | ||
|
|
||
| Use typed error constructors from `pkg/errors`: | ||
|
|
||
| ```go | ||
| 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. | ||
|
|
||
| ### Context Propagation | ||
|
|
||
| All long-running operations must accept `context.Context` as first parameter: | ||
|
|
||
| ```go | ||
| func ProcessEvent(ctx context.Context, event cloudevents.Event) error | ||
| ``` | ||
|
|
||
| Use `logger.WithLogField(ctx, key, value)` or `logger.WithLogFields(ctx, fields)` to attach structured fields to the context for logging. | ||
|
|
||
| ### CEL Expressions | ||
|
|
||
| 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`, not `params.clusterID`) | ||
| - `resources.*` - discovered resources (post-phase), e.g., `resources.myCluster` | ||
| - `adapter.*` - adapter metadata (name, status, etc.) | ||
| - Custom functions: `now()` (RFC3339 timestamp), `toJson(val)`, `dig(map, "dot.path")` | ||
|
|
||
| ### Resource Names | ||
|
|
||
| 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` | ||
|
|
||
| ## Boundaries - Do NOT Do This | ||
|
|
||
| ### Generated Files | ||
|
|
||
| - **Do not modify** files in `.bingo/` - these are managed by bingo | ||
| - **Do not edit** `go.sum` manually - use `make tidy` | ||
|
|
||
| ### Testing | ||
|
|
||
| - **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 | ||
|
|
||
| ### Configuration | ||
|
|
||
| - **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) | ||
|
|
||
| ### Dependencies | ||
|
|
||
| - **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 | ||
|
|
||
| ### Git | ||
|
|
||
| - **Do not force push** to main or release branches | ||
| - **Do not amend published commits** - create new commits | ||
| - **Do not commit** `.env` files, credentials, or sensitive data | ||
|
|
||
| ### API Changes | ||
|
|
||
| - **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 | ||
|
|
||
| ## Testing Patterns | ||
|
|
||
| ### Table-Driven Tests | ||
|
|
||
| Use subtests for multiple scenarios: | ||
|
|
||
| ```go | ||
| 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) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Integration Test Setup | ||
|
|
||
| Use testcontainers for real dependencies: | ||
|
|
||
| ```go | ||
| 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 | ||
| } | ||
| ``` | ||
|
|
||
| ## Common Tasks | ||
|
|
||
| ### Adding a New Parameter Extractor | ||
|
|
||
| 1. Add extractor to `internal/executor/param_extractor.go` | ||
| 2. Add tests in same package | ||
| 3. Document in `docs/configuration.md` | ||
| 4. Add example in `configs/adapter-task-config-template.yaml` | ||
|
|
||
| ### Adding a New Precondition Type | ||
|
|
||
| 1. Add evaluator to `internal/criteria/evaluator.go` | ||
| 2. Add tests with mock clients | ||
| 3. Update schema in `internal/configloader/types.go` | ||
| 4. Document in adapter authoring guide | ||
|
|
||
| ### Adding Metrics | ||
|
|
||
| 1. Define metric in `pkg/metrics/recorder.go` | ||
| 2. Instrument code with metric calls | ||
| 3. Add Prometheus query to `docs/metrics.md` | ||
| 4. Add recommended alert to `docs/alerts.md` | ||
|
|
||
| ## Release Process | ||
|
|
||
| Version follows semver (MAJOR.MINOR.PATCH): | ||
|
|
||
| - Version is derived from `APP_VERSION` in `Makefile` (auto-set from git tags via `git describe`) | ||
| - Update `CHANGELOG.md` with 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 | ||
|
|
||
| ## Links | ||
|
|
||
| - [Architecture Docs](https://github.com/openshift-hyperfleet/architecture) | ||
| - [HyperFleet API Spec](https://github.com/openshift-hyperfleet/hyperfleet-api-spec) | ||
| - [Broker Library](https://github.com/openshift-hyperfleet/hyperfleet-broker) | ||
| @AGENTS.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Consider documenting pre-commit hook caveats.
Based on the linked hyperfleet-api repository,
.pre-commit-config.yamlmay include internal hooks (e.g.,rh-pre-commit) that external contributors cannot access and should skip or comment out. Consider adding a note to help external contributors avoid setup friction.📝 Suggested documentation addition
📝 Committable suggestion
🤖 Prompt for AI Agents