Skip to content

ci(triage): detect harness test attributes, not just #[test] - #277

Open
beardthelion wants to merge 1 commit into
mainfrom
fix/triage-detect-namespaced-test-attrs
Open

ci(triage): detect harness test attributes, not just #[test]#277
beardthelion wants to merge 1 commit into
mainfrom
fix/triage-detect-namespaced-test-attrs

Conversation

@beardthelion

@beardthelion beardthelion commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

The needs-tests triage label fires on PRs that do add tests. The detector matched an added #[test] or #[cfg(test)] line and nothing else, so it missed every test written with a harness attribute. That is most of this repo: 345 #[tokio::test] and 189 #[sqlx::test] against 540 bare #[test]. A PR whose tests are all DB or async tests got told it had none.

It caught #275 (three added #[sqlx::test] functions) and #262 (eight) while I was reviewing them.

What changed

One regex. It now matches an added attribute whose last path component contains test, followed by ] or (:

/^\+\s*#\[(cfg\(test\)|(?:\w+::)*\w*test\w*[\](])/m

That covers the four forms in the tree today and the harnesses someone might reach for later (#[rstest], #[test_case], #[wasm_bindgen_test]) without enumerating them one by one.

Anchoring to the start of the added line also drops three false positives the old .* prefix accepted: a comment, a string literal, and a doc example that merely mention #[test].

What it deliberately does not do

An earlier cut of this also counted an added assert!, on the theory that it catches any test regardless of how it was declared. That is wrong in the direction that matters. A production assertion is ordinary Rust, so a PR adding assert!(!input.is_empty()) to a handler and no tests at all would have cleared the label silently.

The two failure directions are not symmetric here. Labeling a PR that did add tests is loud and the author corrects it. Clearing a PR that added none is invisible. For an advisory nudge, the heuristic should fail loud, so the assertion signal is out.

Test plan

There is no harness for workflow JS, so this was verified by running the regex directly.

  • 20-case table, both directions, with the regex read back out of the parsed YAML rather than the source: all four current forms plus #[rstest], #[test_case], #[wasm_bindgen_test], #[proptest], and an #[rstest] asserting only via unwrap() are detected. Production assert!/assert_eq! alone, a doc-comment assert, a removed - line, #[derive(Debug)], #[serde(rename = "test")], #[attest::verify], and comment/string mentions of #[test] are all correctly not.
  • Replayed against the real patches of 14 open PRs through the full label logic: fix(node): honor pre-assigned task assignee on claim #275 and fix(node): bound the request body the signature middleware buffers before it verifies #262 stop being labeled, both of which do add tests, and no other verdict changes.
  • Both halves shown to be load-bearing: #[rstest] with unwrap() goes undetected to detected on the broadened path component, and a production-assert-only diff goes cleared to labeled when the assertion signal comes out.
  • pr-triage.yml parses, and node --check is clean on the extracted github-script body, so the regex survives the YAML block scalar.

Nothing else in the workflow changes. It still adds and removes labels only, with no setFailed.

Summary by CodeRabbit

  • Bug Fixes
    • Improved detection of Rust inline tests in pull request triage.
    • Recognizes standard, qualified, and parameterized test attributes such as #[test] and #[tokio::test(...)].

The needs-tests detector matched an added `#[test]` or `#[cfg(test)]` line
and nothing else, so it missed every test written with a harness attribute.
That is most of this repo: 345 `#[tokio::test]` and 189 `#[sqlx::test]`
against 540 bare `#[test]`. Any PR whose tests are all DB or async tests got
labeled needs-tests, which is what happened on #275 (three added
`#[sqlx::test]` functions) and #262 (eight).

Match an added attribute whose last path component contains `test`, followed
by `]` or `(`. That covers the four forms in the tree today and the harnesses
a contributor might reach for later (`#[rstest]`, `#[test_case]`,
`#[wasm_bindgen_test]`) without enumerating them.

Deliberately not keying on an added `assert!`: a production assertion is
ordinary Rust, so that signal would let a testless PR clear the label
silently. The label is a nudge, so it should fail loud. Labeling a PR that
did add tests gets corrected by the author; clearing one that did not is
invisible.

Anchoring to the start of the added line also drops three false positives the
old `.*` prefix accepted: a comment, a string literal, and a doc example that
merely mention `#[test]`.

Verified against the real patches of 14 open PRs: #275 and #262 stop being
labeled, both of which do add tests, and no other verdict changes.
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR triage workflow updates its Rust inline test heuristic to detect qualified and parameterized test attributes while requiring the attribute to appear at the start of an added line.

Changes

Rust inline test detection

Layer / File(s) Summary
Expand inline test attribute matching
.github/workflows/pr-triage.yml
The addsInlineTest regex now supports attributes such as #[test], #[tokio::test], and parameterized forms anchored to added Rust lines.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: kevincodex1

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main CI triage change.
Description check ✅ Passed It covers summary, rationale, changes, and verification, so the description is mostly complete despite missing some template sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/triage-detect-namespaced-test-attrs

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-triage.yml:
- Around line 85-89: Update addsInlineTest to detect Rust test attributes only
in code, not inside multiline comments or raw strings, by tracking lexical state
across patch lines or using a Rust-aware parser. Preserve the existing
added-line and Rust-file filtering, and add regressions covering multiline
comments and raw strings containing lines beginning with #[test].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 95aa1bd2-8355-4c96-8f60-8dfbf80f9296

📥 Commits

Reviewing files that changed from the base of the PR and between 111cff7 and 203d156.

📒 Files selected for processing (1)
  • .github/workflows/pr-triage.yml

Comment on lines +85 to +89
// Anchored to the start of the added line, so a comment or a string that
// merely mentions #[test] does not count.
const addsInlineTest = files.some(f =>
f.filename.endsWith(".rs") && f.patch &&
/^\+.*#\[(test\]|cfg\(test\))/m.test(f.patch));
/^\+\s*#\[(cfg\(test\)|(?:\w+::)*\w*test\w*[\](])/m.test(f.patch));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

The line anchor does not exclude multiline comments or raw strings.

A production-only change such as /*\n#[test]\n*/ or a raw string containing a line beginning with #[test] still produces a matching +#[test] patch line, so needs-tests is incorrectly omitted. Track Rust lexical state across patch lines (or use a Rust-aware parser), and add regressions for these cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-triage.yml around lines 85 - 89, Update addsInlineTest
to detect Rust test attributes only in code, not inside multiline comments or
raw strings, by tracking lexical state across patch lines or using a Rust-aware
parser. Preserve the existing added-line and Rust-file filtering, and add
regressions covering multiline comments and raw strings containing lines
beginning with #[test].

@beardthelion beardthelion added the kind:ci CI, release, or packaging pipeline label Jul 29, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I found one item that needs maintainer input before this merges.

Findings

  • [P2] Resolve overlap with open PR #202 before merging
    .github/workflows/pr-triage.yml (same file, competing fix)
    Open PR #202 (fix/pr-triage-async-test-detection, +208/−4) fixes the same needs-tests inline-test detector, closes #201, and already went through multiple review rounds (lexical stripping of comments/strings/raw literals, head-file lexing across hunks, blob API fetch, bounded-scan inconclusive handling, #[r#test] / #[::tokio::test]). This PR (+15/−1) is a regex-only subset of that work. Only one should land; merging both would conflict. Please close or supersede #202 explicitly, or close this PR in favor of #202 if the fuller approach is preferred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind:ci CI, release, or packaging pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants