Skip to content

Commit f4a5e57

Browse files
committed
RavenDB-26535: add pre-release-report skill + CLAUDE.md
1 parent 29df945 commit f4a5e57

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
name: pre-release-report
3+
description: Run if user wants to prepare for release. Six-pass audit of the repo before cutting a release. Passes 1-2 (CSV markers, samples) propose changes for user approval and commit them. Passes 3-6 (breaking changes, Helm parity, reviewers, dependencies) report findings; the user directs follow-up.
4+
---
5+
6+
Six-pass pre-release audit. Run them in order. End with a structured summary.
7+
8+
Use the current branch's ticket prefix (e.g., `RavenDB-26535`) for any commit subjects. Determine it from `git branch --show-current`.
9+
10+
## Pass 1 — CSV markers (action: propose → confirm → apply → commit)
11+
12+
Walk `api/v1/*.go`. For every exported field with a JSON tag, decide whether it needs a `+operator-sdk:csv:customresourcedefinitions:` marker.
13+
14+
**Skip:**
15+
- `Spec`, `Status`, `Items`, `TypeMeta`, `ObjectMeta`, `ListMeta` — structural plumbing.
16+
- Embedded k8s core types (`corev1.VolumeSource`, `corev1.EnvVar`, `corev1.SecretReference`).
17+
- Pure container fields whose descriptors come from nested children (e.g., `Data`, `Logs`, `RavenDB`, `Audit` in `StorageSpec` — descriptors live on `Size`, `StorageClassName`, etc., reached via `storage.data.size` etc.).
18+
19+
**Mark:** spec fields → `type=spec`, status fields → `type=status`. Format:
20+
`// +operator-sdk:csv:customresourcedefinitions:type=<spec|status>,displayName="<DisplayName>"`
21+
22+
DisplayName: CamelCase → "Space-Separated Words"; keep acronyms (URL, ID, IP, EIP, CA, TCP, DNS); prefer domain-clear (`CertSecretRef` → "Certificate Secret"). Match the style of existing markers in the same file. Do NOT add `description="..."` — operator-sdk's parser rejects it at this level.
23+
24+
Show proposals as `file:line field → marker`, ask for confirmation/overrides, apply, run `make verify-samples` and (if available) `make bundle` in WSL to verify operator-sdk parses everything. Commit: `<ticket>: refresh CSV markers in api/v1`.
25+
26+
## Pass 2 — Samples (action: validate + propose updates → confirm → apply → commit)
27+
28+
First, run `make verify-samples`. If it fails, the strict-unmarshal error names the file/field — fix and re-run.
29+
30+
Then, judgment pass: diff `api/v1/` spec types against the most recent release tag (`git describe --tags --abbrev=0`).
31+
32+
For incremental additions (new optional fields, new array entries on existing types), ask: "Should this field appear in `ravendb_v1_ravendbcluster_letsencrypt.yaml`, `..._selfsigned.yaml`, both, or neither?"
33+
34+
For changes that introduce a fundamentally distinct use case — a new `mode:` value, a new external-access provider type, a new storage backend, a new auth scheme — propose adding a NEW sample file: `ravendb_v1_ravendbcluster_<scenario>.yaml`. The user may also request a new sample even for incremental changes if they want a separate example. Register any new sample in `config/samples/kustomization.yaml` so operator-sdk folds it into alm-examples.
35+
36+
Apply approved additions/files. Re-run `make verify-samples`. Commit: `<ticket>: update config/samples for new spec fields`.
37+
38+
## Pass 3 — CRD breaking-change review (report only)
39+
40+
Render the CRD at the most recent release tag and at HEAD, then diff. Render with `kustomize build config/crd | yq` (or operator-sdk equivalent). Surface:
41+
42+
| Change | Severity | Why it matters |
43+
|---|---|---|
44+
| Removed field | High | Breaks users who set it |
45+
| Type change | High | Wire-incompatible |
46+
| New required field, no default | High | Breaks existing CRs on upgrade |
47+
| Narrowed enum or smaller min/max | Medium | Breaks users at the boundary |
48+
| Changed default | Medium | Silent behavior change |
49+
50+
Output severity, field path, before → after. Do NOT auto-fix — these are deliberate decisions (keep with a major version bump, document migration, or revert).
51+
52+
## Pass 4 — Helm chart parity (report only)
53+
54+
`helm/chart/templates/` and `config/` are maintained in parallel. Diff them across:
55+
- **RBAC**: verbs/resources/apiGroups in `config/rbac/role.yaml` vs `helm/chart/templates/rbac.yaml` (or equivalent).
56+
- **Manager Deployment**: env vars, volume mounts, args, resource limits in `config/manager/manager.yaml` vs `helm/chart/templates/deployment.yaml`.
57+
- **Webhook**: cert-manager Issuer/Certificate refs, service ports.
58+
59+
Report drift as `area | config has | helm has | risk`. Do NOT auto-fix — which side is canonical depends on what the change was for.
60+
61+
## Pass 5 — Reviewer list (report + interactive)
62+
63+
Read `bundle/ravendb-operator/ci.yaml`. Surface the current `reviewers:` list (or note absence — without it OperatorHub auto-merge doesn't fire). Ask: "Is this list current? Anyone to add or remove?" If the user wants edits, propose, confirm, apply, commit `<ticket>: refresh OperatorHub reviewers list`.
64+
65+
## Pass 6 — Dependencies audit (report + interactive, top-level only)
66+
67+
Surface pin vs latest for these only — don't go deep into transitive Go modules:
68+
69+
- `OPERATOR_SDK_VERSION` in `Makefile` vs latest `operator-framework/operator-sdk` GitHub release.
70+
- `CONTROLLER_TOOLS_VERSION`, `KUSTOMIZE_VERSION`, `ENVTEST_VERSION`, `GOLANGCI_LINT_VERSION` in `Makefile`.
71+
- `go` directive in `go.mod` vs current stable Go.
72+
- cert-manager version in `.github/workflows/release.yml` smoke-test URL.
73+
- GitHub Action versions in `.github/workflows/*.yml` — surface floating tags (`@v3`, `@v4`); recommend SHA pinning where missing.
74+
75+
Report as `dep | pinned | latest | gap | recommendation`. Recommendation tone: "consider bumping" or "looks current". Do NOT auto-bump — bumps need a deliberate test cycle, not a release-prep slipstream. Ask the user if they want to schedule any bumps as separate work.
76+
77+
## Final summary
78+
79+
```
80+
Pre-release report — <ticket>
81+
=============================
82+
Pass 1 (CSV markers): <committed sha | "no gaps">
83+
Pass 2 (Samples): <committed sha | "no updates needed">
84+
Pass 3 (CRD breaking): <N items by severity>
85+
Pass 4 (Helm parity): <N drift items>
86+
Pass 5 (Reviewers): <committed sha | "current">
87+
Pass 6 (Dependencies): <N items behind>
88+
```
89+
90+
After this report, the user has a clear picture of what's actionable before invoking `prepare-release.yml`.

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# RavenDB Operator — Claude context
2+
3+
Go controller (kubebuilder, `go.kubebuilder.io/v4`) that reconciles `RavenDBCluster` CRs into running RavenDB clusters. Shipped as both an OLM bundle and a Helm chart.
4+
5+
## Layout
6+
7+
| Path | Contents |
8+
| --- | --- |
9+
| `api/v1/` | `RavenDBCluster` CRD types + admission webhook glue. Field-level `+operator-sdk:csv:customresourcedefinitions:` markers drive CSV descriptors. |
10+
| `cmd/main.go` | Manager entrypoint |
11+
| `internal/controller/` | Reconciliation loop |
12+
| `pkg/actor/` | Actor-style sub-reconcilers (RBAC, secrets, certs) |
13+
| `pkg/director/` | Coordinates actors |
14+
| `pkg/resource/` | Builders for k8s resources (StatefulSet, Service, RBAC, …) |
15+
| `pkg/scripts/` | Bash mounted into RavenDB pods (init, cert update, discovery) |
16+
| `pkg/webhook/{adapter,validator}/` | Admission webhook plumbing and validators |
17+
| `config/` | Kustomize manifests (CRD, RBAC, manager, webhook, manifests bases) |
18+
| `config/manifests/bases/...csv.yaml` | CSV base — operator-level metadata (description, icon, keywords, links, maintainers). `make bundle` merges marker-derived descriptors into this. |
19+
| `config/samples/` | CR examples folded into CSV `alm-examples` by operator-sdk. New samples must be registered in `config/samples/kustomization.yaml`. |
20+
| `helm/chart/` | Helm chart (parallel to `config/`, not auto-generated from it) |
21+
| `helm/` | Packaged `.tgz` artifacts and `index.yaml` (served via GH Pages) |
22+
| `bundle/ravendb-operator/<version>/` | Current OLM bundle. Generated by `make bundle` + `make bundle-relocate`. |
23+
| `bundle/ravendb-operator/ci.yaml` | OperatorHub config — `updateGraph: semver-mode` |
24+
| `.github/workflows/operator-ci.yml` | CI: tests + e2e on PR / push to main |
25+
| `.github/workflows/lint-workflows.yml` | actionlint on PRs touching `.github/workflows/**` |
26+
| `.github/workflows/prepare-release.yml` | Release phase 1: bumps + `make bundle` + helm package + opens release PR labeled `release:auto`. First step is `make verify-samples` — gates the entire release. |
27+
| `.github/workflows/release.yml` | Release phase 2: auto-fires on merge of a `release:auto`-labeled PR (or manual `workflow_dispatch`). Multi-arch image push + multi-arch verify + kind smoke test + git tag + published GitHub Release with `install.yaml` attached |
28+
| `.github/workflows/release-dryrun.yml` | Biweekly cron that runs prepare-release + release with `dry_run=true` to surface pipeline rot. Opens an issue on failure. |
29+
| `docker/release.{sh,ps1}` | Legacy DockerHub release scripts. Superseded by the workflows above; keep as a manual fallback. |
30+
| `test/e2e/` | E2E tests (kustomize + helm install paths, namespace isolation, upgrades) |
31+
| `test/samples/` | Strict-unmarshal samples against api/v1 types. Run by `make verify-samples`. |
32+
33+
## Common commands
34+
35+
```bash
36+
make manifests # Regenerate CRDs/RBAC/webhook from Go annotations
37+
make generate # Regenerate DeepCopy methods
38+
make test # envtest unit tests
39+
make test-e2e # Kind-based e2e
40+
make lint # golangci-lint
41+
make build # Build manager binary into bin/
42+
make verify-samples # Strict-unmarshal config/samples/ against api/v1 types (no envtest)
43+
make bundle VERSION=<v> IMG=docker.io/ravendb/ravendb-operator:<v> CHANNELS=stable DEFAULT_CHANNEL=stable
44+
make bundle-relocate VERSION=<v> # Move flat bundle/ output into nested bundle/ravendb-operator/<v>/
45+
```
46+
47+
Never run `docker/release.sh`, `make docker-push-*`, `make bundle-push`, `make catalog-push`, `helm push`, `gh release create`, or `git push` (commits, branches, or tags) without an explicit per-action go-ahead. Routine releases happen by clicking **Prepare Release** in the [Actions tab](https://github.com/ravendb/ravendb-operator/actions), reviewing the auto-generated PR, and merging it — the Release workflow auto-fires on merge if the `release:auto` label is still attached. Remove the label before merging to delay publishing.
48+
49+
## Conventions
50+
51+
- Webhook validators live in `pkg/webhook/validator/`. The adapter in `pkg/webhook/adapter/` wires them to controller-runtime. New validators go through the adapter, not directly on CRD types.
52+
- One `RavenDBCluster` per namespace. Enforced in `pkg/webhook/validator/namespace_validator.go`.
53+
- Secret lookups are namespace-scoped — never fall back to the operator's namespace.
54+
- Helm chart and `config/` are maintained in parallel. RBAC/env/volume changes must land in both.
55+
- CSV descriptors are emitted from `+operator-sdk:csv:customresourcedefinitions:displayName="..."` markers on api/v1 fields. Operator-level metadata (description, icon, keywords, links, maintainers, minKubeVersion) lives in `config/manifests/bases/...csv.yaml` and is preserved across `make bundle` runs.
56+
57+
## Repo gotchas
58+
59+
- `bundle/ravendb-operator/ci.yaml` uses `updateGraph: semver-mode`. Do not add `spec.replaces` to the CSV.
60+
- `helm/index.yaml` is committed and served from `https://ravendb.github.io/ravendb-operator/helm/`. ArtifactHub crawls it via `helm/artifacthub-repo.yml`.
61+
- `Makefile` `IMAGE_TAG_BASE` defaults to `ravendb.io/ravendb-operator` — not a real registry. Bundle/catalog targets need it overridden to `docker.io/ravendb/ravendb-operator`.
62+
- The OLM bundle uses a nested layout (`bundle/ravendb-operator/<version>/{manifests,metadata,tests}/`). `make bundle` writes operator-sdk's flat output at repo root; `make bundle-relocate` moves it into the nested layout and rewrites `bundle.Dockerfile` `COPY` paths.
63+
- `make bundle` rewrites `config/manager/kustomization.yaml` (image tag) as a side-effect of `kustomize edit set image`. The release workflow reverts that file post-bundle so the tracked default stays at `:latest`.
64+
- The marker parser rejects `description="..."` at customresourcedefinitions level — only `displayName=` is supported. Per-field descriptions must live in the base file (or be accepted as lost).
65+
- operator-sdk markers emit descriptor paths as `nodes[0].field`; OLM convention is `nodes[].field` ("applies to all array elements"). `prepare-release.yml` post-processes the CSV with a scoped sed to fix this. Same workflow re-injects the `containerImage:` annotation that operator-sdk does not emit.
66+
- `make bundle` is Linux/macOS only — operator-sdk doesn't ship Windows binaries. Use WSL or run via the `prepare-release.yml` workflow.
67+
- `controller-gen paths=./...` fails on Windows for this repo (interaction with the hostname-less `module ravendb-operator` in `go.mod`). Use `paths='ravendb-operator/...'` if running on Windows.

0 commit comments

Comments
 (0)