From f021a793e6052a5ad3fc90f23df6b640b468bf0a Mon Sep 17 00:00:00 2001 From: John Collier Date: Thu, 25 Jun 2026 09:14:58 -0400 Subject: [PATCH 1/2] chore(agent-readiness): bootstrap basic AGENTS.md and minor repo updates for agents Signed-off-by: John Collier --- .claude/rules/api.md | 12 +++++++++ .claude/rules/controller.md | 12 +++++++++ .claude/rules/integration-tests.md | 12 +++++++++ .claude/settings.json | 15 ++++++++++++ AGENTS.md | 39 ++++++++++++++++++++++++++++++ CLAUDE.md | 1 + Makefile | 2 +- 7 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 .claude/rules/api.md create mode 100644 .claude/rules/controller.md create mode 100644 .claude/rules/integration-tests.md create mode 100644 .claude/settings.json create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.claude/rules/api.md b/.claude/rules/api.md new file mode 100644 index 000000000..ff5aea1e7 --- /dev/null +++ b/.claude/rules/api.md @@ -0,0 +1,12 @@ +--- +paths: + - "api/**/*.go" +--- + +# API Types Rules + +- New API versions go in `api/v1alphaN/` following the existing version directories. +- All exported types and fields must have godoc comments (Go convention: comment starts with the symbol name). +- After modifying any type in `api/`, run `make manifests generate` — the generated CRD YAML and deepcopy code must be committed with the source change. +- Validation markers (`+kubebuilder:validation:*`) go on struct fields, not separately. +- Check `api/current-types.go` to understand which API version is current/promoted. diff --git a/.claude/rules/controller.md b/.claude/rules/controller.md new file mode 100644 index 000000000..763705395 --- /dev/null +++ b/.claude/rules/controller.md @@ -0,0 +1,12 @@ +--- +paths: + - "internal/controller/**/*.go" +--- + +# Controller Rules + +- Reconcile logic lives in `internal/controller/backstage_controller.go`. +- Use `controllerutil.CreateOrUpdate` for idempotent resource management — avoid plain `Create` which fails on re-reconcile. +- Gate optional features on CRD presence before registering scheme or adding RBAC. +- Do not hard-code `replicas` in any Deployment/StatefulSet template — omit to allow HPA. +- After any controller change, run `make manifests generate fmt vet` before committing. diff --git a/.claude/rules/integration-tests.md b/.claude/rules/integration-tests.md new file mode 100644 index 000000000..99e00f669 --- /dev/null +++ b/.claude/rules/integration-tests.md @@ -0,0 +1,12 @@ +--- +paths: + - "integration_tests/**/*.go" + - "tests/**/*.go" +--- + +# Integration & E2E Test Rules + +- Integration tests require a running Kubernetes cluster. Use `make integration-test USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true`. +- The `PROFILE` variable selects the test suite: `backstage.io` (faster, default for CI) or `rhdh`. +- Staticcheck (ST1001) is excluded for test files — dot-imports are allowed. +- Use `--focus` to run a single test: `make integration-test ARGS='--focus "test name"' USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true`. diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..bd09f6e05 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write", + "hooks": [ + { + "type": "command", + "command": "case \"$CLAUDE_FILE_PATH\" in *.go) gofmt -w \"$CLAUDE_FILE_PATH\" 2>/dev/null || true ;; esac" + } + ] + } + ] + } +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..1d990431f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,39 @@ +# rhdh-operator + +Kubernetes operator for Red Hat Developer Hub (RHDH), based on the Backstage operator. +Manages `Backstage` CRs and reconciles them into Deployments, ConfigMaps, and related resources. + +## Build & Test Commands + +- Build: `make build` +- Test (unit): `make test` +- Integration test (requires running cluster): `make integration-test PROFILE=backstage.io USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true` +- Lint: `make lint` (golangci-lint + yamllint) +- Lint fix: `make lint-fix` +- Format: `make fmt` (goimports) +- Security scan: `make gosec` +- Generate CRD/deepcopy: `make manifests generate` +- Single-file lint: `golangci-lint run ./path/to/package/...` +- Single-file vet: `go vet ./path/to/package/...` + +## Key Conventions + + + +## Architecture + + + +## Pattern References + +- CR examples and dependent resources: `examples/` +- Operator coding patterns (from PR reviews): `best_practices.md` +- Design and configuration docs: `docs/` + +## PR Conventions + +- PR description must link the related issue (`Fixes #`) and include test and documentation checkboxes. +- Agent-assisted commits should include an `Assisted-by: ` footer. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/Makefile b/Makefile index fae5219f7..9af711187 100644 --- a/Makefile +++ b/Makefile @@ -204,7 +204,7 @@ gosec: addgosec ## run the gosec scanner for non-test files in this repo $(GOSEC) -no-fail -fmt $(GOSEC_FMT) -out $(GOSEC_OUTPUT_FILE) ./... .PHONY: lint -lint: golangci-lint ## Run golangci-lint linter & yamllint +lint: golangci-lint vet ## Run golangci-lint linter & yamllint & go vet $(GOLANGCI_LINT) run --timeout 15m .PHONY: lint-fix From 4c531329f790bbf8f500a222cbf110d0f88790a7 Mon Sep 17 00:00:00 2001 From: John Collier Date: Thu, 2 Jul 2026 10:27:03 -0400 Subject: [PATCH 2/2] fix: address PR review feedback on agent-readiness docs - Use server-side apply instead of controllerutil.CreateOrUpdate in controller rules - Clarify that only some integration tests require a cluster and/or controller - Clarify `make test` covers unit + integration tests not requiring a real cluster - Update integration test description to mention both cluster and controller - Add docs/design.md reference in Architecture section Assisted-by: Cursor (claude-4.6-opus) Co-authored-by: Cursor --- .claude/rules/controller.md | 2 +- .claude/rules/integration-tests.md | 2 +- AGENTS.md | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.claude/rules/controller.md b/.claude/rules/controller.md index 763705395..76b96339d 100644 --- a/.claude/rules/controller.md +++ b/.claude/rules/controller.md @@ -6,7 +6,7 @@ paths: # Controller Rules - Reconcile logic lives in `internal/controller/backstage_controller.go`. -- Use `controllerutil.CreateOrUpdate` for idempotent resource management — avoid plain `Create` which fails on re-reconcile. +- Use server-side apply (`r.Patch(.., client.Apply, ..)`) for idempotent resource management — avoid plain `Create` which fails on re-reconcile. - Gate optional features on CRD presence before registering scheme or adding RBAC. - Do not hard-code `replicas` in any Deployment/StatefulSet template — omit to allow HPA. - After any controller change, run `make manifests generate fmt vet` before committing. diff --git a/.claude/rules/integration-tests.md b/.claude/rules/integration-tests.md index 99e00f669..e40b6532b 100644 --- a/.claude/rules/integration-tests.md +++ b/.claude/rules/integration-tests.md @@ -6,7 +6,7 @@ paths: # Integration & E2E Test Rules -- Integration tests require a running Kubernetes cluster. Use `make integration-test USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true`. +- Some integration tests may require a running Kubernetes cluster and/or existing controller. Use `make integration-test USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true`. - The `PROFILE` variable selects the test suite: `backstage.io` (faster, default for CI) or `rhdh`. - Staticcheck (ST1001) is excluded for test files — dot-imports are allowed. - Use `--focus` to run a single test: `make integration-test ARGS='--focus "test name"' USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true`. diff --git a/AGENTS.md b/AGENTS.md index 1d990431f..a48f6ad61 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,8 +6,8 @@ Manages `Backstage` CRs and reconciles them into Deployments, ConfigMaps, and re ## Build & Test Commands - Build: `make build` -- Test (unit): `make test` -- Integration test (requires running cluster): `make integration-test PROFILE=backstage.io USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true` +- Test (unit and integration tests not requiring real cluster): `make test` +- Integration test (on running cluster and controller): `make integration-test PROFILE=backstage.io USE_EXISTING_CLUSTER=true USE_EXISTING_CONTROLLER=true` - Lint: `make lint` (golangci-lint + yamllint) - Lint fix: `make lint-fix` - Format: `make fmt` (goimports) @@ -24,6 +24,8 @@ Manages `Backstage` CRs and reconciles them into Deployments, ConfigMaps, and re ## Architecture +- Design and configuration overview: `docs/design.md` +