- ci: reject a manual dispatch with tag "latest"; concurrency group per tag - Dockerfile: declare GIT_COMMIT after the module download layer - Makefile: docker-build targets linux/amd64 by default - patch.go: no shared package-level pointers; main.go: no init() - tests: assert that merge replaces managed listener content - docs: flows.md startup section matches main.go; review saved to docs/reviews Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
156 lines
7.0 KiB
Markdown
156 lines
7.0 KiB
Markdown
# Execution: Bring gateway-helper-operator up to house conventions
|
|
|
|
Plan: `docs/plans/2026-10-08-2028-house-conventions.md`
|
|
|
|
- [x] Step 0 — Save and commit the plan
|
|
- [x] Step 1 — CLAUDE.md
|
|
- [x] Step 2 — `.claude/` and docs scaffolding
|
|
- [x] Step 3 — Makefile, lint, formatting
|
|
- [x] Step 4 — Module path and version identity
|
|
- [x] Step 5 — Baseline tests
|
|
- [x] Step 6 — CI build workflow
|
|
- [ ] Step 7 — Close out
|
|
|
|
## Step 1 — CLAUDE.md
|
|
|
|
Rewrote `CLAUDE.md` in the five-section shape. The Go, Testing, Changelog and
|
|
Branching text comes from the `go-project-bootstrap` skill references; the plan
|
|
ordering and execution-summary rules come from `egress-proxies-operator/CLAUDE.md`,
|
|
condensed from prose into bullets.
|
|
|
|
Deviations from the plan:
|
|
|
|
- The house container rules about Ubuntu dev images and separate dev/prod
|
|
Dockerfiles were left out: this repo has one production Dockerfile and no dev
|
|
image, and listing rules nobody follows only adds noise.
|
|
- The `listener-port` row was removed from the annotation table and moved to
|
|
Gotchas, so the table lists only what works.
|
|
- Added a short Reviews subsection so the reviewer agents and `docs/reviews/` have a
|
|
documented trigger.
|
|
- `README.md` also claimed that deleting a certificate removes its listeners
|
|
"instantly". Reworded and added the known limitation.
|
|
|
|
Worth noting: Commands and CI/CD describe the repo as it is at this commit; Steps 3,
|
|
4 and 6 update them. `docs/flows.md` cites `main.go` line numbers that Step 4 shifts.
|
|
|
|
## Step 2 — `.claude/` and docs scaffolding
|
|
|
|
Copied the two reviewer agents and `/ship` from `egress-proxies-operator/.claude/`.
|
|
`/release` was rewritten for the semver rule instead of copied, because the egress
|
|
text says "no tagging scheme is documented" and this repo now has one.
|
|
|
|
Deviations from the plan:
|
|
|
|
- `/ship` names "a `Co-Authored-By:` trailer for Claude" instead of the fixed
|
|
`Claude <noreply@anthropic.com>` string, matching CLAUDE.md.
|
|
- `.gitignore` already covered `/bin/` and `*.out`, so only
|
|
`.claude/settings.local.json` was added.
|
|
- `settings.json` also allows `kubectl kustomize`, which the Commands section uses.
|
|
|
|
Worth noting: `.claude/settings.json` leaves out `git commit`, `git push` and
|
|
`git tag` on purpose, but `~/.claude/settings.json` allows `git commit` and
|
|
`git push` globally, so on this machine the push confirmation rests on CLAUDE.md,
|
|
not on the permission system.
|
|
|
|
## Step 3 — Makefile, lint, formatting
|
|
|
|
Added `Makefile` (uh-cli's shape plus `run`, `docker-build` and `-race` on `test`),
|
|
`.golangci.yml` (v2 defaults) and `.dockerignore` (egress's allowlist).
|
|
|
|
`make lint` failed on first run, before reaching this repo's code:
|
|
|
|
```
|
|
$ golangci-lint run ./...
|
|
.../go/1.27.1/libexec/src/crypto/internal/randutil/randutil.go:11:2: could not import math/rand/v2
|
|
(.../math/rand/v2/rand.go:213:17: method must have no type parameters) (typecheck)
|
|
```
|
|
|
|
The installed golangci-lint 2.12.2 was built with go1.26.4 and cannot type-check the
|
|
Go 1.27 standard library. The `lint` target now runs under the go.mod toolchain,
|
|
which is also what CI uses:
|
|
|
|
```make
|
|
GO_MOD_VERSION := $(shell awk '$$1 == "go" {print $$2}' go.mod)
|
|
lint:
|
|
GOTOOLCHAIN=go$(GO_MOD_VERSION) golangci-lint run ./...
|
|
```
|
|
|
|
With that, lint reported the two expected dead variables (`gatewayGroup`,
|
|
`gatewayKind` in `patch.go`), which were removed. `make fmt` reformatted `main.go`
|
|
(import order) and the `patch.go` var block.
|
|
|
|
Worth noting: this is likely the same failure the egress changelog records as
|
|
"`make lint` is blocked by a Go 1.27 toolchain/staticcheck panic"; the same
|
|
`GOTOOLCHAIN` pin should unblock it there. Rebuilding golangci-lint with Go 1.27 is
|
|
the other fix. `.golangci.yml` carries no settings yet: uh-cli's `errcheck`
|
|
exclusions are CLI-specific and nothing here needed one.
|
|
|
|
## Step 4 — Module path and version identity
|
|
|
|
Module renamed to `gitea.home.hrajfrisbee.cz/kacerr/gatewayapi-certificates-operator`.
|
|
`internal/version` copied from egress unchanged (code and test). `main.go` gained
|
|
`--version`, a first log line with commit and Go version, the standard `--zap-*`
|
|
flags, and passes `--metrics-bind-address` to the manager.
|
|
|
|
```
|
|
$ make build && ./bin/manager --version
|
|
0eb588e8bd3a-dirty
|
|
$ make docker-build && docker run --rm gateway-cert-operator:dev --version
|
|
0eb588e8bd3a-dirty
|
|
$ docker inspect gateway-cert-operator:dev --format '{{index .Config.Labels "org.opencontainers.image.revision"}} {{.Config.User}}'
|
|
0eb588e8bd3a-dirty 65532:65532
|
|
```
|
|
|
|
Deviations from the plan:
|
|
|
|
- The Dockerfile build also got `-trimpath`, and keeps `-s -w` (egress has neither).
|
|
- The Dockerfile now does `COPY . .` and relies on the new `.dockerignore`
|
|
allowlist, instead of copying `main.go` and `internal/` by name.
|
|
- The `gozap.AddCaller()` option was kept so log lines look the same as before.
|
|
|
|
Worth noting: the manager was not started against a cluster in this step; the
|
|
flag wiring is verified by `--help` output and the build only. `GOARCH` defaults to
|
|
`amd64` when `TARGETARCH` is empty (legacy builder, as on the CI runner) and follows
|
|
the host under BuildKit, so a local build on an Apple Silicon machine is arm64.
|
|
`docs/flows.md` still cites pre-change `main.go` line numbers in §2.
|
|
|
|
## Step 5 — Baseline tests
|
|
|
|
`internal/gateway/patch_test.go`: five table-driven tests over the pure functions.
|
|
|
|
```
|
|
$ go test -race -cover ./...
|
|
ok .../internal/gateway 1.870s coverage: 96.9% of statements
|
|
ok .../internal/version 2.196s coverage: 94.7% of statements
|
|
```
|
|
|
|
Worth noting: `internal/controller` and `main` are at 0%; reconciler tests with the
|
|
fake client come with the first reconcile fix. Wildcard names, name collisions and
|
|
truncation are deliberately not asserted, so the suite does not pin behaviour that
|
|
the bug-fix phase will change. `TestListenersEqual_managedFields` only asserts the
|
|
four fields the comparison covers today; it says nothing about protocol, allowed
|
|
routes or TLS mode.
|
|
|
|
## Step 6 — CI build workflow
|
|
|
|
`.gitea/workflows/build.yaml` is now a verbatim copy of the egress workflow; it has
|
|
no project-specific strings (the image name comes from `github.repository`).
|
|
|
|
Worth noting: not run yet. The first tag push or manual dispatch is the test. Two
|
|
things could differ from egress on this repo's runner: `actions/setup-go@v5` (uh-cli
|
|
had to install Go with curl instead), and lint is not part of the `check` job, same
|
|
as egress. The unused `GIT_TAG` and `BUILD_DATE` build args are gone;
|
|
`kubernetes-deploy.yaml` is untouched.
|
|
|
|
## Step 7 — Close out (review)
|
|
|
|
Ran both reviewer agents on `main...HEAD`; findings and their status are in
|
|
`docs/reviews/2026-10-08-2040-house-conventions.md`. Ten items fixed on the branch, four new
|
|
bugs deferred to the bug-fix phase, one test simplification declined.
|
|
|
|
Worth noting: the reviewer agents were not registered as agent types when the review
|
|
started (they were added in this session), so they were run as general-purpose
|
|
agents told to follow the agent files. The `:latest` dispatch hole came in with the
|
|
workflow copied from egress and is still open there. Step 7 stays unchecked until
|
|
the branch is pushed and the MR is open.
|