Files
Aleksei Sviridkin dd00deb5e2 ci(labeler): add area/crds for the CRD-bundle packages
packages/system/ holds eight charts that exist only to ship a CRD
bundle. Seven of them ship nothing else; gateway-api-crds also carries
upstream's safe-upgrades ValidatingAdmissionPolicy, which is why the
label and the map say CRD-bundle rather than CRD-only. None of the
eight is a key in .github/workflows/pr-labeler.yaml, so a PR
scoped to one lands on area/uncategorized — or pushes its author to a
broader scope that does map, which is the shoehorning AGENTS.md tells
contributors not to do. Seven get a key here; the eighth is left out
for a reason of its own, below.

No existing area fits. Routing each package to its component's area
— cert-manager-crds to platform, prometheus-operator-crds to
monitoring — misdescribes the work these directories receive: clean
the chart dir before helm pull, ship the full upstream CRD bundle,
make CRD vendoring fail loudly, extract the CRDs into their own
package. That is packaging, not the component, and it would send a
chart-vendoring change to whoever filters monitoring. It also adds
nothing, since fix(cert-manager) already resolves to area/platform.
area/crds names the concern that has none: vendoring, install
ordering and retention across all of them. area/* already mixes
subsystems with cross-cutting concerns — build, ci, testing,
release, dependencies — so this joins an existing group rather than
opening a third axis.

The map asked for a scope to recur 3+ times before it earned an
entry. That rule is for discovering scopes from traffic; here the set
is closed and enumerable, seven existing directories with no area at
all. Bare `crds` covers a change spanning several of them.

One key is observed and the rest are seeded, and the comment says
which is which. The observed one is prometheus-operator-crds: a PR
titled `fix(prometheus-operator-crds): ship full upstream CRD bundle`
landed on area/uncategorized, which is exactly the failure this block
ends. It is also the only one -- across every commit touching those
seven directories no other directory name has been used as a scope,
and the title is the only place the labeler takes a scope from.
Authors reach for the component scope --
cert-manager, etcd-operator, linstor, vpa -- which has to keep meaning
the component, since a change to cert-manager itself is not CRD
packaging. The directory name is the one scope that names the
packaging without taking the component's.

`labeler` and `pr-labeler` map to area/ci. Both are observed: three
PRs changing this file carried one of them in the title, and every one
landed on area/uncategorized. Not `labels`, and on evidence rather
than on a rule: the sole commit carrying it as a scope was about
Kubernetes object labels on chart templates, so the one observed use
points somewhere else entirely. Mapping it would answer that use
confidently wrong, which is worse than area/uncategorized saying out
loud that it could not tell. This commit is scoped `labeler` for the
same reason.

Bare `crds` is the one key that is a guess rather than a directory
name, and the comment says so: it has never been used as a scope
either, and it is here for a change spanning several of the packages.
The exposure is an author reaching for it on a CRD change that is not
packaging; a differently scoped one cannot reach it, since the lookup
is an exact key match.

application-definition-crd is deliberately left out: its CRD is
cozystack's own API surface rather than a vendored upstream bundle,
its changes ship under the `api` scope, and `api` already resolves
to area/api.

Add hack/pr-labeler-areas.bats. What issues.addLabels does with a
label the repository has not declared is not documented for that
endpoint, and the test does not need it to be: either it creates
one undeclared, which nothing reports, or it fails the job on every
PR whose title hits that scope. The first test requires every label
the workflow can apply -- area/* and kind/* alike, since both travel
through that same call -- to be declared in .github/labels.yml. The
second requires every CRD-bundle package to carry a scope key that
maps to area/crds, so the ninth one does not land back on
area/uncategorized. The labeler does warn on an unmapped scope, but
only once someone opens such a PR; the test fires when the package is
added, which is when it is still cheap to fix.
.github/workflows/labels.yaml validates labels.yml alone, and its path
filter names labels.yml and itself, so neither check runs today.

Both tests evaluate the labeler rather than pattern-match it, because
the pattern-matched version was defeated five ways: a double-quoted
key, a space before the colon, a value built by concatenation, a key
repeated lower down that wins at runtime, and an object parked where
nothing consults it. Fixing those spellings one at a time had already
produced the next three, so hack/pr-labeler-probe.js runs the step in
node and reports the labels it reaches and the map it resolves. node
and python3 become requirements of the two tests, failing loudly when
absent on the precedent hack/md-no-hardwrap.bats sets for its own
interpreter. All five defeats were reproduced as green before the
change and red after.

The two rules this departs from are amended rather than left
standing, though not identically. The map now says the 3+ threshold
is how a scope is discovered out of traffic rather than a bar every
key must clear. The label file keeps its 3+ open issues and gains a
second way in: a set of packages that share a concern and have no
area at all.

docs/agents/contributing.md said the labeler also runs on `edited`.
That trigger was removed deliberately, so retitling an open PR does
not relabel it, and the sentence promised the opposite.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-08-07 16:22:40 +03:00
..
2026-07-22 14:01:14 +05:00