Skip to content

Commit 442f66d

Browse files
chores: add AGENTS.md (#158)
1 parent 63d0edc commit 442f66d

3 files changed

Lines changed: 156 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to coding agents when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Kubernetes operator for managing ClickHouse database clusters and ClickHouse Keeper clusters. Built with `Kubebuilder` and `controller-runtime`. Manages two CRDs: `ClickHouseCluster` and `KeeperCluster` (both `v1alpha1` in the `clickhouse.com` API group).
8+
9+
## Common Commands
10+
11+
### Build & Run
12+
```bash
13+
make build # Build binary (bin/clickhouse-manager). Runs manifests, generate, fmt, vet first.
14+
make build-linux-manager # Build binary (bin/clickhouse-manager) for linux platform. Used to build Docker image.
15+
make docker-build # Build Docker image
16+
```
17+
18+
### Testing
19+
```bash
20+
make test # Unit tests (excludes e2e and deploy tests). Uses `envtest` with Ginkgo.
21+
make test-ci # CI tests with coverage (cover.out), race detection, JUnit report
22+
make fuzz # Fuzz tests for keeper and clickhouse spec validation
23+
make test-e2e # Full e2e tests (requires Kind cluster, 30m timeout)
24+
make test-keeper-e2e # Keeper-only e2e tests (--ginkgo.label-filter keeper)
25+
make test-clickhouse-e2e # ClickHouse-only e2e tests (--ginkgo.label-filter clickhouse)
26+
make test-compat-e2e # Compatibility smoke tests across ClickHouse versions
27+
```
28+
29+
Run a single test file or spec:
30+
```bash
31+
# Single package
32+
go test ./internal/controller/keeper/ -v --ginkgo.v
33+
# Single spec by name
34+
go test ./internal/controller/keeper/ -v --ginkgo.v --ginkgo.focus="spec name pattern"
35+
```
36+
37+
### Testing rules
38+
- Run `make lint-fix` before tests
39+
- Run `make test` or specific unit tests
40+
- Do NOT run `make test-e2e`, `test-keeper-e2e`, `test-clickhouse-e2e`, `test-compat-e2e`
41+
- If changes complex and require e2e testing run target with `--ginkgo.focus` to limit scope to a single test at a time
42+
43+
### Test patterns
44+
- **Functional tests** (`controller_test.go`): Use `testutil.SetupEnvironment()` which starts `envtest` (real API server + `etcd`). Use for full reconciliation flow testing.
45+
- **Unit tests** (`sync_test.go`, `commands_test.go`): Use `fake.NewClientBuilder()` for faster, focused tests on individual methods.
46+
- **E2E tests** (`test/e2e/`): Real Kind cluster. Label tests with `Label("clickhouse")` or `Label("keeper")` for filtered runs.
47+
48+
### Code Generation (run after modifying api/v1alpha1/ types)
49+
```bash
50+
make generate # DeepCopy methods (zz_generated.deepcopy.go)
51+
make manifests # CRDs, RBAC roles, webhooks → config/crd/bases/
52+
make generate-helmchart-ci # Generate Helm chart templates and reset manually maintained files (dist/chart/templates/)
53+
make docs-generate-api-ref # Generate API reference docs (docs/api-reference.md)
54+
```
55+
56+
### Helm Chart
57+
The Helm chart in `dist/chart/` is partially **generated from `Kustomize` configs** — do not edit templates directly. Regenerate with `make generate-helmchart-ci`. Except you are directly asked.
58+
59+
### Linting & Formatting
60+
```bash
61+
make lint # golangci-lint + codespell + actionlint
62+
make lint-fix # golangci-lint with --fix
63+
make golangci-fmt # gofmt + goimports formatting
64+
make docs-lint # markdownlint for docs
65+
```
66+
67+
### Running E2E Locally
68+
Kind cluster configuration at `ci/kind-cluster.config` creates 1 control-plane + 3 workers with zone topology labels:
69+
```bash
70+
kind create cluster --config ci/kind-cluster.config
71+
```
72+
73+
### CRD Compatibility
74+
```bash
75+
make check-crd-compat # Check CRD backward compatibility against origin/main
76+
```
77+
78+
## Coding Rules
79+
- Do not introduce new dependencies without justification
80+
- Follow existing error handling patterns
81+
- Try to minimize diff
82+
- Avoid API changes unless necessary
83+
- Always ensure `make lint` passes, use `make lint-fix` to automatically fix issues before writing code
84+
85+
## CI Pipeline (what runs on PRs)
86+
1. Lint: `go mod tidy` check, `make manifests`/`make generate` freshness, CRD backward compatibility, golangci-lint, codespell, actionlint
87+
2. Build + unit tests (`make test-ci`)
88+
3. Fuzz tests
89+
4. Helm chart generation + lint
90+
5. OLM bundle + scorecard validation
91+
6. Compatibility e2e (multiple K8s + ClickHouse version matrices)
92+
7. Full e2e (Keeper + ClickHouse, on self-hosted runners)
93+
94+
## Architecture
95+
96+
### CRD API Types (`api/v1alpha1/`)
97+
- `clickhousecluster_types.go` — ClickHouseCluster spec: shards, replicas per shard, keeper reference, storage, settings
98+
- `keepercluster_types.go` — KeeperCluster spec: replicas (odd, 0-15), storage, settings
99+
- `common.go` — Shared types: ContainerImage, LoggerConfig, PodDisruptionBudgetSpec, ClickHouseSettings, KeeperSettings
100+
- `defaults.go` — Default value logic applied by webhooks
101+
- `conditions.go` — Status condition helpers
102+
103+
After modifying types, always run `make generate manifests generate-helmchart-ci docs-generate-api-ref`.
104+
105+
### Controllers (`internal/controller/`)
106+
Both controllers follow the same pattern, extending a shared base:
107+
108+
- `reconcilerbase.go` — Base reconciliation logic shared by both controllers
109+
- `clickhouse/controller.go` — ClickHouseCluster reconciler (manages StatefulSets, ConfigMaps, Services)
110+
- `keeper/controller.go` — KeeperCluster reconciler
111+
- `clickhouse/sync.go`, `keeper/sync.go` — Sync desired state to Kubernetes
112+
- `clickhouse/templates.go`, `keeper/templates.go` — Generate Kubernetes resource specs
113+
- `clickhouse/config.go` — Generate ClickHouse YAML configuration
114+
- `clickhouse/commands.go`, `keeper/commands.go` — Interfaces to communicate to running containers
115+
- `overrides.go` — Pod/container spec overrides helpers via strategic merge patch
116+
- `versionprobe.go` — Creates Jobs to detect actual ClickHouse/Keeper versions
117+
- `upgradecheck.go` — Checks for newer version availability
118+
- `resources.go` — Shared Kubernetes resource creation helpers
119+
- `status.go` — Status update logic
120+
121+
### Reconciliation Pattern
122+
Controllers execute reconcile as a sequence of step functions (`func(ctx, log) (*Result, error)`). Steps are defined in `sync()` and executed sequentially.
123+
124+
### Resource Change Detection
125+
Resources are tracked via annotation hashes (`checksum/spec`, `checksum/configuration`). Before updating a K8s resource, compare `util.DeepHashResource()` output against the stored annotation. Skip updates when hashes match. Always call `util.AddSpecHashToObject()` on reconciled resources.
126+
127+
### Webhooks (`internal/webhook/v1alpha1/`)
128+
Validation and defaulting webhooks for both CRDs. `ENABLE_WEBHOOKS` Env var controls whether they are registered.
129+
130+
### Key Packages
131+
- `internal/upgrade/` — Version update checking (fetcher + compatibility checker)
132+
- `internal/version/` — Build version info injected via `ldflags`
133+
- `internal/environment/` — Environment variable processing (`ENABLE_WEBHOOKS`, `WATCH_NAMESPACE`)
134+
- `internal/controllerutil/` — Shared utilities (annotations, dialer, logger)
135+
136+
### Config/Deploy (`config/`)
137+
Kustomize-based configuration: `config/default/` is the main overlay composing CRDs, RBAC, manager deployment, webhooks, and cert-manager integration.
138+
139+
### Entry Point
140+
`cmd/main.go` — Sets up controller-runtime manager, registers both controllers and webhooks, configures metrics and health probes.
141+
142+
## Code Style & Conventions
143+
144+
- **Import ordering**: `stdlib`, third-party, then `github.com/ClickHouse/clickhouse-operator` (enforced by goimports with local-prefixes)
145+
- **`interface{}``any`**: gofmt rewrites `interface{}` to `any` automatically
146+
- **Testing**: Ginkgo v2 BDD style with Gomega matchers. Dot imports for `ginkgo/v2` and `gomega` are allowed.
147+
- **Linting**: 80+ linters enabled in `.golangci.yml`. Notable: `wsl_v5` (whitespace), `mnd` (magic numbers, `2` is exempted), `godot` (comment periods), `ireturn` (interface return restrictions with whitelisted types)
148+
- **Generated files**: Never edit `zz_generated.deepcopy.go` or files in `config/crd/bases/`, `config/rbac/` directly

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ docs-generate-api-ref: crd-ref-docs ## Generate API reference documentation from
553553
.PHONY: docs-lint-vale
554554
docs-lint-vale: ## Run Vale linter on documentation
555555
@command -v vale >/dev/null 2>&1 || { echo "Vale is required but not installed. https://vale.sh/docs/install"; exit 1; }
556-
vale --config='.vale.ini' README.md docs
556+
vale --config='.vale.ini' *.md docs
557557

558558
.PHONY: docs-link-check
559559
docs-link-check: ## Run markdown-link-check on documentation

docs/styles/config/vocabularies/ClickHouse/accept.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ ANDed
1616
boolean
1717
lts
1818
liveness
19+
codespell
20+
actionlint
21+
goimports
22+
gofmt
23+
Gomega
24+
matchers
25+
configs

0 commit comments

Comments
 (0)