Contributing
Issues and pull requests go to github.com/alexmond/kweblens. This page is the short version; Development has the detail behind every command here.
1. Before you push
scripts/dev-verify.sh
That is the gate: spring-javaformat:apply, then ./mvnw -B verify over the whole reactor —
compile, Checkstyle, PMD, Java tests, JaCoCo, and the front-end npm run check. CI runs the same
./mvnw -B verify on JDK 21, so green here means green on the PR.
While iterating, scripts/dev-test.sh <selector> runs one test or one pattern without a full
reactor build.
2. Code style
-
spring-javaformat (tabs, Spring conventions) —
./mvnw spring-javaformat:apply, or just letdev-verify.shdo it. -
Checkstyle hard-fails at 800 lines per file and 80 lines per method. Target under ~500 lines per source file as a guideline — split a fat controller into per-page
*PageServicehelpers rather than growing it. -
PMD (
pmd-ruleset.xml) fails on violation. -
Lombok
@RequiredArgsConstructorfor constructor injection;@ConfigurationPropertiesfor configuration. -
Front end: logic in
.ts, rendering in.vue, so behaviour is testable without a DOM.
The lint rules that most often fail a build are not fixed by :apply, so they surface at
validate on the next run: SpringLambda wants (e) → …; SpringTernary wants
(a != b) ? x : y; InnerTypeLast; UseUnderscoresInNumericLiterals (86_400);
AppendCharacterWithChar (sb.append('m')).
3. Tests must not hit a real cluster
The suite is hermetic. Use the fabric8 mock — @EnableKubernetesMockClient(crud = true) — and
set kweblens.load-kubeconfig=false in web tests so ClusterBootstrap skips ambient discovery;
then register the mock client into the autowired ClusterRegistry.
The CRUD mock ignores limit and dryRun, so a test that seeds objects and asserts on the
outcome passes whether or not the flag was ever sent. Assert on the exact outgoing request
instead. Coverage is gated: kweblens-core 0.70, kweblens-web 0.50, kweblens-cli 0.60 line
coverage.
If you add a live-updated list, add its watch to the per-animation-frame batching pattern — a
test in the gate asserts that invariant. If you add an SSE endpoint, attach SseKeepAlive;
another test fails the build if you do not.
4. A few standing constraints
Worth knowing before proposing a change, because these are decided rather than open:
-
One shared operator identity is the design, not a gap. No OIDC, no per-user identity, no RBAC-aware authorization. See Security and identity — user-facing text must keep saying this plainly.
-
Helm goes through the jhelm library, never the
helmbinary. -
Every surface is a
web/<area>/slice over akweblens-coreaccess service — cluster access is never reimplemented in a controller. See Architecture. -
Remediation is suggest → approve → apply. Never autonomous, always audited, all writes behind auth.
-
Never commit a kubeconfig.
.gitignoreblocks*.kubeconfig,kubeconfigand.kube/; screenshots under.playwright/are gitignored for the same reason — they carry a live cluster’s hostnames, node names and namespaces.
5. How a pull request is verified
.github/workflows/ci.yml runs on every pull request and on pushes to main: JDK 21 (Temurin),
./mvnw -B verify, with surefire and JaCoCo reports uploaded as artifacts even on failure.
That is the same command dev-verify.sh runs, so there should be no surprises.
scripts/pr-watch.sh <pr> waits for the checks and prints each result as it lands, exiting 1 on
any failure. Adding --merge squash-merges, but only when every check passed.
Commit subjects in this repository read as prose sentences describing the change, with the PR
number in parentheses — for example Say what the server said, and never call an unanswered
check clear (#306).
6. License
The repository is dual-licensed by module, and a contribution is taken under the license of the module it touches:
-
kweblens-coreandkweblens-cli— Apache-2.0 (LICENSE-APACHE-2.0.txt). These are libraries other code compiles against. -
kweblens-webandkweblens-it— AGPL-3.0 (LICENSE-AGPL-3.0.txt). This is the self-hosted server.
Keep new code on the right side of that line: if something belongs in the permissive access layer,
put it in kweblens-core rather than reaching for it from the server module.