diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..ce2b18d5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,117 @@ +# edp-codebase-operator + +Go module `github.com/epam/edp-codebase-operator/v2`. A kubebuilder operator (controller-runtime) that provisions and manages source-code entities. It is the **platform source of truth**: its CRDs are imported and watched by `edp-cd-pipeline-operator`, `edp-tekton`, `krci-portal`, and the CLI. + +CRD group `v2.edp.epam.com/v1`: `Codebase`, `CodebaseBranch`, `GitServer`, `JiraServer`, `JiraIssueMetadata`, `CDStageDeploy`, `CodebaseImageStream`, `QuickLink`. +There is also an `api/v1alpha1` group for the `Template` type. + +## Build & Test + +```bash +make build # compile → dist/manager- +make test # unit tests (requires envtest binaries; downloads automatically) +make lint # golangci-lint v2 +make lint-fix # golangci-lint with auto-fix +make fmt # go fmt ./... +make vet # go vet ./... + +# Run a single test package +KUBEBUILDER_ASSETS="$(./bin/setup-envtest use --bin-dir bin -p path)" \ + KUBECONFIG=hack/kubecfg-stub.yaml \ + go test ./controllers/codebase/... -run TestSomething -v +``` + +Tests rely on `setup-envtest` (controller-runtime's envtest framework). `make test` handles downloading the binaries. The `hack/kubecfg-stub.yaml` is a stub kubeconfig required by the test suite. + +## Code Generation + +```bash +make generate # DeepCopy methods (zz_generated.deepcopy.go) + CRD API docs +make manifests # CRDs, RBAC, webhooks → deploy-templates/crds/ and config/crd/bases/ +make mocks # mockery mocks (see .mockery.yaml for targets) +make api-docs # regenerate docs/api.md from CRDs (crdoc) +make helm-docs # regenerate deploy-templates/README.md (helm-docs) +make validate-docs # CI check: fails if api.md or README.md are out of date +``` + +**Never hand-edit:** + +- `api/v1/zz_generated.deepcopy.go` — regenerated by `make generate` +- `api/v1alpha1/zz_generated.deepcopy.go` — same +- `pkg/gitprovider/bitbucket/generated/bitbucket_client.generated.go` — oapi-codegen output; regenerate via `oapicfg.yaml` +- `deploy-templates/crds/` and `config/crd/bases/` — regenerated by `make manifests` +- `deploy-templates/README.md` and `docs/api.md` — regenerated by `make helm-docs` / `make api-docs` +- `*_generated.mock.go` files — regenerated by `make mocks` + +## Architecture + +``` +cmd/main.go + └── registers all 8 controllers + admission webhooks with controller-runtime Manager + +api/v1/ — CRD type definitions (spec, status, kubebuilder markers) +api/v1alpha1/ — Template CRD + +controllers// + ├── _controller.go — Reconcile() entry point + └── chain/ or service/chain/ — Sequential handler chain (chain-of-responsibility) + +pkg/gitprovider/ — Per-provider adapters: github.go, gitlab.go, bitbucket.go + Factory: NewProvider() dispatches on GitServer.Spec.GitProvider +pkg/client/jira/ — Jira REST client (go-jira wrapper + mockable Client interface) +pkg/gerrit/ — SSH-based Gerrit client +pkg/git/ — go-git wrapper + factory (supports SSH/HTTPS auth) +pkg/webhook/ — Admission webhooks: Codebase and CodebaseBranch validation +pkg/objectmodifier/ — Applies default values / label patches before reconcile logic +pkg/util/ — Shared helpers (workdir, timeouts, URL utilities, templates) +pkg/tektoncd/ — Tekton TriggerTemplate manager (for CDStageDeploy) +pkg/autodeploy/ — Auto-deploy logic for CDStageDeploy +``` + +### Controller Map + +| Controller | CRD | Chain location | +|---|---|---| +| `codebase` | `Codebase` | `controllers/codebase/service/chain/` | +| `codebasebranch` | `CodebaseBranch` | `controllers/codebasebranch/chain/` | +| `codebaseimagestream` | `CodebaseImageStream` | `controllers/codebaseimagestream/chain/` | +| `cdstagedeploy` | `CDStageDeploy` | `controllers/cdstagedeploy/chain/` | +| `gitserver` | `GitServer` | `controllers/gitserver/` (flat, no sub-chain) | +| `jiraserver` | `JiraServer` | `controllers/jiraserver/chain/` | +| `jiraissuemetadata` | `JiraIssueMetadata` | `controllers/jiraissuemetadata/chain/` | +| `integrationsecret` | `Secret` (native) | `controllers/integrationsecret/` | + +### Codebase reconcile chain (main creation path) + +`PutGitWebRepoUrl` → `PutProject` → `PutWebHook` → `PutGitLabCIConfig` → `PutDeployConfigs` → `PutDefaultCodeBaseBranch` → `Cleaner` + +Deletion runs a shorter chain: `DeleteWebHook` → `Cleaner`. + +### Multi-provider Git logic + +`pkg/gitprovider/NewProvider()` dispatches on `GitServer.Spec.GitProvider` (`gerrit`, `github`, `gitlab`, `bitbucket`). Gerrit uses SSH (`pkg/gerrit`); GitHub and GitLab use resty REST; Bitbucket uses an oapi-codegen client in `pkg/gitprovider/bitbucket/generated/`. When adding provider-specific behaviour, implement the `GitProvider` / `GitProjectProvider` / `GitWebHookProvider` interfaces and wire them into the factory. + +### Admission webhooks + +`pkg/webhook/` validates `Codebase` and `CodebaseBranch` on create/update. Disabled at runtime by setting `ENABLE_WEBHOOKS=false`. Webhook TLS cert paths are passed via CLI flags (`--webhook-cert-path`, etc.). + +### Environment variables + +- `WATCH_NAMESPACE` — namespace the operator watches (required) +- `CODEBASE_BRANCH_MAX_CONCURRENT_RECONCILES` — concurrency for CodebaseBranch reconciler (default 1) +- `ENABLE_WEBHOOKS` — set to `false` to disable admission webhooks +- `TELEMETRY_ENABLED` / `TELEMETRY_DELAY` — opt-in usage telemetry + +### Adding a new chain handler + +1. Create `controllers//chain/my_step.go` implementing the handler interface (`ServeRequest(ctx, cr) error`). +2. Register it in `controllers//chain/factory.go` (the `MakeChain` / `CreateChain` function) in the correct call order. +3. Add a `_test.go` alongside it; tests use `envtest` + `testify` (not Ginkgo). + +## Conventions + +- Tests use `testify` (`require`, `assert`) and controller-runtime's `envtest`. Mocks are generated by mockery v3 (see `.mockery.yaml`). +- `pkg/objectmodifier/CodebaseModifier` runs before any chain step, patching defaulted fields and labels so chain handlers see a normalised object. +- Failure count backoff: on reconcile error, `setFailureCount` increments `Status.FailureCount` and returns a `RequeueAfter` timeout calculated by `pkg/util.GetTimeout`. +- `CodebaseBranch.Status.FailureCount` similarly gates requeue delay. +- Deploy-templates Helm chart `README.md` is auto-generated by helm-docs from `values.yaml` annotations — do not edit manually.