Thanks for contributing. This repository provides a kcp controller for resource deletion protection in a dependency tree.
Every pull request needs an issue, and every issue needs an assignee before work starts. This is not bureaucracy: design discussion belongs in the issue, where it costs a comment to change direction rather than a rewrite.
- Open an issue, or find an open one. New issues carry
needs-triageuntil a maintainer has looked at them — wait for triage before starting. - Get it assigned. Maintainers assign themselves. GitHub does not let people outside the org self-assign, so comment on the issue and a maintainer will assign you.
- Work only on issues assigned to you. If an assigned issue has been quiet for a couple of weeks, ask in the thread before picking it up.
- Link the issue from the pull request body (
Closes #123).
A PR without a linked issue, or from someone other than the assignee, gets closed with a pointer back here. Three cases are exempt:
| Exempt | Why |
|---|---|
| Renovate and other bot PRs | Opened by automation and tracked on the Renovate dependency dashboard |
| Typos and docs-only fixes | Nothing to design — the diff is the discussion |
| Security fixes | These start privately, never in a public issue. See Security |
main is protected with required_signatures. An unsigned commit cannot be
merged. The rule is applied by make repo-settings from
dev-kit.
SSH signing is the least friction if you already push over SSH:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign trueThen add the same key to GitHub as a signing key (Settings → SSH and GPG keys → New SSH key → type Signing Key). A key added only as an authentication key will sign locally but show as Unverified on GitHub.
For GPG instead, see GitHub's guide.
Check before pushing — git log --show-signature -1, or:
git log -5 --format='%h %G? %s' # G = good signature, N = unsignedCertify that you wrote the change and may submit it under the project's license, per the Developer Certificate of Origin:
git commit -s -m "fix: bump dependency-controller to 0.5.0"-s appends a Signed-off-by: trailer with your user.name and user.email.
Use a real name and a reachable address.
Not enforced in CI today, so nothing fails if you forget. Sign off anyway — retrofitting it across a history means rewriting commits.
There is no config that adds the trailer to every git commit (format.signOff
only affects git format-patch). Use an alias instead:
git config --global alias.cs 'commit -s'Conventional Commits, enforced twice:
commitlint checks every commit in the PR against
.commitlintrc.yml, and a separate check validates the PR
title. Allowed types and examples are documented once, in
dev-kit's CONTRIBUTING.
PRs land as merge commits — squash and rebase are disabled — so every commit in
your branch keeps its own message and gets linted. Tidy the branch before
review rather than leaving fixup commits for the merge to swallow.
Scope with the component where it applies:
feat(webhook): reject deletion when a dependent resource exists
fix(controller): requeue on transient APIExport errors
ci: pin actions/checkout to a commit sha
direnv allow (or nix develop) gives you a shell with the toolchain on
$PATH; pre-commit install registers the hooks. Then:
make lint # golangci-lint plus license headers
make test # unit and integration tests; KCP_VERSION=<x.y.z> picks the kcp version
make test-e2e # kind + kcp + helm, creates its own cluster (needs docker)make test-matrix and make test-e2e-kcp-matrix run the same suites across
every supported kcp version. make help lists the rest, and
docs/development.md covers the test internals.
| Check | Runs on | Does |
|---|---|---|
| OSV-Scanner | every PR | Scans the dependency tree. The only required status check — nothing merges until it is green |
| Conventional Commits | every PR | commitlint over every commit, plus the PR title |
| Zizmor | every PR | Static analysis of the workflows — unpinned actions, template injection, over-broad permissions, credential persistence |
| Golang CI | Go sources, go.mod, go.sum, Makefile, flake.nix |
golangci-lint, license headers, go build, go vet, and make test against every kcp version in docs/compatibility.md |
| Helm Lint | charts/** |
helm lint over each chart |
| Docker build | ok-to-image label |
Builds the container image. A maintainer adds the label |
| Helm publish | ok-to-helm label |
Packages the chart. A maintainer adds the label |
Path filters mean a docs-only PR skips Golang CI and Helm Lint. Only OSV-Scanner blocks the merge today; the rest are advisory, so read them rather than merging past a red one.
Beyond green checks, the main ruleset requires:
- one approving review, including a CODEOWNERS approval
- every review conversation resolved
- the branch up to date with
main - approval of the most recent push — pushing new commits dismisses earlier approvals, so re-request review after a fixup
Publishing happens after the merge, not on the PR: pushes to main build the
container image, and a published GitHub release (or a v* tag) publishes both
the image and the Helm chart.
Do not open a public issue for a vulnerability. Report it through the private advisory form linked from SECURITY.md, and expect coordinated disclosure.
Reports must show that the finding is reachable in this controller. Raw dependency-scanner output, without evidence the CVE can be used against the dependency-controller, is not accepted.