- check job runs go vet, go build and go test -short before the build - images are pushed as :<tag> and :sha-<12>; :latest moves only on tag pushes - GIT_COMMIT build arg and OCI source/created labels Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.4 KiB
Execution: Bring gateway-helper-operator up to house conventions
Plan: docs/plans/2026-10-08-2028-house-conventions.md
- Step 0 — Save and commit the plan
- Step 1 — CLAUDE.md
- Step 2 —
.claude/and docs scaffolding - Step 3 — Makefile, lint, formatting
- Step 4 — Module path and version identity
- Step 5 — Baseline tests
- 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-portrow 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.mdalso 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:
/shipnames "aCo-Authored-By:trailer for Claude" instead of the fixedClaude <noreply@anthropic.com>string, matching CLAUDE.md..gitignorealready covered/bin/and*.out, so only.claude/settings.local.jsonwas added.settings.jsonalso allowskubectl 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:
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.dockerignoreallowlist, instead of copyingmain.goandinternal/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.