Skip to content

fix(ci): tolerate null PR fields and honour existing area/* in pr-labeler#17

Merged
Maxim Kitsunoff (kitsunoff) merged 1 commit into
mainfrom
fix/pr-labeler-null-safe
May 26, 2026
Merged

fix(ci): tolerate null PR fields and honour existing area/* in pr-labeler#17
Maxim Kitsunoff (kitsunoff) merged 1 commit into
mainfrom
fix/pr-labeler-null-safe

Conversation

@lexfrei
Copy link
Copy Markdown
Contributor

Follow-up to #16. Addresses two correctness bugs in computeLabels (.github/scripts/pr-labeler.js) caught in review.

The bugs

  1. Null inputs crash body.match(). computeLabels destructured title / body / existingLabels with = '' defaults. Destructuring defaults only fire on undefined. GitHub PR payloads carry an explicit null for an empty body (and, less commonly, for missing fields), which would slip past the default and crash on the first .match() or Set iteration. Switched to explicit rawTitle || '' / rawBody || '' / new Set(rawExisting || []) so null on any input is treated as the empty value.

  2. hasArea ignored existing area/ labels.* A maintainer-added area/forms followed by a scopeless retitle (e.g. chore: housekeeping) would re-add area/uncategorized on top of the real area. The next labeler run would clean it up, but the PR carried both labels until then. Fixed hasArea to also consider already-attached real area/*, with area/uncategorized itself excluded so a scopeless retitle of an only-uncategorized PR still routes through the fallback path.

Tests

Five new cases in pr-labeler.test.js, all pinning behaviour that fails without the corresponding fix:

  • null body does not throw
  • null title is treated as empty
  • null existingLabels does not throw
  • retitle to scopeless when maintainer-added area/* exists: no area/uncategorized — stale fallback gets removed
  • existing only has area/uncategorized: scopeless title keeps area/uncategorized (no churn) — fallback path still taken, no flapping

26 tests pass (node --test .github/scripts/*.test.js).

Note

pr-labeler.yaml already coerces pr.title || '', pr.body || '', (pr.labels || []) at the caller, so fix #1 is defense-in-depth at the function boundary. Worth keeping — the function contract should not rely on every caller doing the coercion.

…eler

Two correctness bugs surfaced after the initial labeler landed:

1. Null inputs. computeLabels destructured title/body/existingLabels
with defaults, but destructuring defaults only fire on undefined.
GitHub PR payloads carry an explicit null for an empty description,
which would crash body.match() at runtime. Switched to explicit ||
fallbacks on rawTitle/rawBody/rawExisting so null on any of the three
is treated as the empty value.

2. hasArea ignored existing area/* labels. A maintainer-added area/*
followed by a scopeless retitle would re-add area/uncategorized on
top of the real area, leaving the PR with both labels until the next
edit cycle cleared the fallback. Now hasArea checks the new
derivation AND existing labels (excluding area/uncategorized itself
so a scopeless retitle of an only-uncategorized PR still reaches the
fallback path).

Five new tests pin the behaviour: null body, null title, null
existingLabels, scopeless retitle with maintainer-added area/* (no
fallback added, stale fallback removed), and the edge case where the
only existing area is area/uncategorized (fallback is not frozen in
place).

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@lexfrei, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 31 minutes and 20 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fb6b12e7-9ec8-4b1b-b31d-566368ca813d

📥 Commits

Reviewing files that changed from the base of the PR and between 92ff040 and 65fe842.

📒 Files selected for processing (2)
  • .github/scripts/pr-labeler.js
  • .github/scripts/pr-labeler.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pr-labeler-null-safe

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added area/ci Issues or PRs related to CI workflows, GitHub Actions, automation kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files labels May 26, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the robustness of the PR labeler script by adding null-safety checks to the destructured parameters of computeLabels, preventing runtime errors when GitHub payloads contain explicit null values. Additionally, it updates the fallback logic to honor existing, maintainer-added area/* labels (excluding area/uncategorized) so that the fallback label is not redundantly applied. Comprehensive unit tests have been added to verify these changes. No review comments were provided.

@lexfrei Aleksei Sviridkin (lexfrei) marked this pull request as ready for review May 26, 2026 14:38
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Null-safety at the function boundary is the right call (defence in depth even with caller-side coercion), and excluding area/uncategorized from the hasArea check avoids freezing the fallback in place.

@kitsunoff Maxim Kitsunoff (kitsunoff) merged commit cd25edf into main May 26, 2026
8 checks passed
@kitsunoff Maxim Kitsunoff (kitsunoff) deleted the fix/pr-labeler-null-safe branch May 26, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci Issues or PRs related to CI workflows, GitHub Actions, automation kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants