From 5197597bbfcda37ace196942d70fa65f23e81862 Mon Sep 17 00:00:00 2001 From: Mike Odnis Date: Thu, 20 Aug 2026 06:37:32 -0400 Subject: [PATCH] fix(labeler): give each C-* label a single automation owner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit follow-up: C-Documentation, C-Testing, and C-Chore were applied by BOTH the path labeler (.github/labeler.yml) and the conventional-title labeler. Because the path labeler runs actions/labeler with sync-labels:true, a later `synchronize` event removes any label defined in labeler.yml whose globs no longer match — clobbering a title-applied C-* label. Resolve the two-owner conflict by scoping each family to one owner: - .github/labeler.yml: drop the C-Documentation / C-Testing / C-Chore path rules. The path labeler now owns only area/scope labels (A-*, pkg:*), which it applies exclusively, so sync-labels:true can never strip a change-type label another workflow set. - .github/workflows/conventional-title-labeler.yml: the title labeler is now the sole owner of the change-type C-* labels, so its convergence set covers all seven (feat/fix/perf/docs/refactor/test/chore) and it can remove the stale one on a retitle without racing the path labeler. labels.yml still defines all C-* labels (used by the title labeler and release.yml categories). YAML parses clean under js-yaml; no literal tabs. --- .github/labeler.yml | 27 +++---------------- .../workflows/conventional-title-labeler.yml | 12 ++++----- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index edd62e3..fe1fd78 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -4,7 +4,10 @@ # actions/labeler config. Adapted from resq-software/npm's format # (label -> changed-files -> any-glob-to-any-file). This is a Cargo/Anchor # monorepo whose members are the two on-chain programs; pkg:* labels track -# each program dir, A-* track cross-cutting areas, C-* track categories. +# each program dir and A-* track cross-cutting areas. Change-type C-* labels +# are owned solely by the conventional-title labeler (.github/workflows/ +# conventional-title-labeler.yml); keeping them out of this path config so +# actions/labeler's sync-labels:true cannot strip a title-applied C-* label. # ── Program (package) scope labels ────────────────────────────────────── @@ -45,25 +48,3 @@ - any-glob-to-any-file: - scripts/**/* - "**/*.sh" - -# ── Category labels ───────────────────────────────────────────────────── - -"C-Documentation": - - changed-files: - - any-glob-to-any-file: - - "**/*.md" - - docs/**/* - -"C-Testing": - - changed-files: - - any-glob-to-any-file: - - "**/tests/**/*" - - scripts/test.sh - -"C-Chore": - - changed-files: - - any-glob-to-any-file: - - package.json - - osv-scanner.toml - - .gitignore - - .gitattributes \ No newline at end of file diff --git a/.github/workflows/conventional-title-labeler.yml b/.github/workflows/conventional-title-labeler.yml index 8b54c9f..d08fb8a 100644 --- a/.github/workflows/conventional-title-labeler.yml +++ b/.github/workflows/conventional-title-labeler.yml @@ -46,12 +46,12 @@ jobs: esac # Converge the title-derived label: on an `edited` re-run the type may have # changed (feat -> fix) or lost its prefix, so a prior C-* would go stale and - # mis-categorize the release notes. Remove the previously applied change-type - # label before adding the current one. Only the four types below are managed - # here because the path labeler (.github/labeler.yml) never applies them; - # C-Documentation / C-Testing / C-Chore are co-owned by paths and are left - # untouched so this workflow never strips a label the path labeler owns. - exclusive="C-Feature C-Bug C-Performance C-Refactor" + # mis-categorize the release notes. This workflow is the SOLE owner of the + # change-type C-* labels below (the path labeler in .github/labeler.yml owns + # only A-* / pkg:* area labels), so it can safely remove the previously + # applied change-type label before adding the current one without racing + # actions/labeler's sync-labels:true. + exclusive="C-Feature C-Bug C-Performance C-Documentation C-Refactor C-Testing C-Chore" current="$(gh pr view "$PR" --repo "$GITHUB_REPOSITORY" --json labels --jq '.labels[].name')" for l in $exclusive; do if [ "$l" != "$label" ] && printf '%s\n' "$current" | grep -qxF "$l"; then