Skip to content

Add PR governance validation workflow#1295

Closed
jiaoshuntian wants to merge 1 commit intomasterfrom
jiaoshuntian-patch-1
Closed

Add PR governance validation workflow#1295
jiaoshuntian wants to merge 1 commit intomasterfrom
jiaoshuntian-patch-1

Conversation

@jiaoshuntian
Copy link
Copy Markdown
Collaborator

@jiaoshuntian jiaoshuntian commented Apr 15, 2026

This workflow validates pull request governance policies by checking for linked issues, project associations, and review statuses.

Summary by CodeRabbit

  • Chores
    • Added automated PR governance validation that enforces linking pull requests to issues and projects, requires approval reviews, and generates detailed validation reports in workflow summaries.

This workflow validates pull request governance policies by checking for linked issues, project associations, and review statuses.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 15, 2026

📝 Walkthrough

Walkthrough

A new GitHub Actions workflow file is added to implement PR governance validation. The workflow triggers on PR events, performs four-phase validation including linked issue detection, project requirement enforcement, review status checking, and generates a summary report with warnings for any governance violations.

Changes

Cohort / File(s) Summary
PR Governance Workflow
.github/workflows/pr_governance
Adds a new workflow that validates PR governance requirements in four phases: (1) detects linked issues via closing keywords and GraphQL closingIssuesReferences queries, with manual same-repo linking fallback; (2) enforces project linkage for the PR and all linked issues; (3) checks for at least one approved review; (4) generates a markdown summary report with counts and warnings. Fails the workflow if governance constraints are violated.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰✨ A governance guard hops into view,
Linking issues and projects through,
Checking reviews with careful sight,
Ensuring all PRs follow right!
With warnings clear and wisdom true,
The workflow keeps your codebase new. 🌟

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding a new PR governance validation workflow. It is specific enough to convey the primary purpose without being overly verbose.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jiaoshuntian-patch-1

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
.github/workflows/pr_governance (4)

126-219: Best-effort manual link detection may be expensive for large repositories.

Scanning up to 1000 issues to find ConnectedEvent timeline items that reference this PR could consume significant API quota and add latency for repositories with many issues. This is acknowledged with the warning at line 212-216, but consider documenting this behavior for maintainers.

The approach is reasonable given GitHub's API limitations, but if performance becomes an issue, consider caching results or reducing maxIssuePages with appropriate documentation about the trade-off.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr_governance around lines 126 - 219, The
getSameRepoManuallyLinkedIssues function performs an unbounded (up to
maxIssuePages) scan of issues which can be very expensive for large repos; to
mitigate, document this behavior and provide an opt-out/config option and a
lower default cap: add a clear comment and README note that scanning up to
maxIssuePages (currently 10) may consume API quota, expose maxIssuePages (or a
boolean to disable the scan) as a configurable parameter, and ensure the
warnings.push message refers to that config so maintainers can adjust or disable
the github.graphql pagination scan if needed.

41-42: Closing keyword regex requires whitespace, but GitHub allows closes#123.

The regex requires at least one whitespace (\s+) after the optional colon, so patterns like closes#123 or fixes#456 (no space) won't match. GitHub actually recognizes these as valid closing keywords. Since the actual linked issues come from the GraphQL API (closingIssuesReferences), this only affects the hasClosingKeywordText boolean used for diagnostics, making the impact minor.

♻️ Proposed fix to allow zero whitespace
 const closingKeywordRegex =
-  /\b(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\b\s*:?\s+(?:[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)?#\d+\b/i;
+  /\b(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\b\s*:?\s*(?:[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)?#\d+\b/i;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr_governance around lines 41 - 42, The diagnostic regex
stored in closingKeywordRegex requires at least one whitespace after the
optional colon which misses matches like "closes#123"; update the pattern by
replacing the `\s+` with `\s*` so zero or more whitespace characters are allowed
(keep the rest of the regex and the case-insensitive flag intact) to match both
"closes `#123`" and "closes#123".

273-298: Dead code: issueNodeId is always populated from upstream functions.

The condition at line 278 (!issueNodeId) will never be true because both getKeywordLinkedIssuesFromPR (line 91) and getSameRepoManuallyLinkedIssues (line 198-199) always populate the id field. The fallback logic to call getSameRepoIssueNodeId is unreachable.

♻️ Proposed fix to remove dead code
 for (const linkedIssue of linkedIssues) {
   try {
-    let issueNodeId = linkedIssue.id;
-
-    // If the issue is in the same repo and we only have the number, refresh via REST if needed.
-    if (!issueNodeId && linkedIssue.repository?.nameWithOwner === `${owner}/${repo}`) {
-      issueNodeId = await getSameRepoIssueNodeId(linkedIssue.number);
-    }
+    const issueNodeId = linkedIssue.id;

     if (!issueNodeId) {
       warnings.push(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr_governance around lines 273 - 298, The branch that
checks and refreshes issueNodeId is dead because linkedIssue.id is always set by
getKeywordLinkedIssuesFromPR and getSameRepoManuallyLinkedIssues; remove the
unreachable if-block that calls getSameRepoIssueNodeId and the associated
warning about unresolved node ID, and simplify the loop to assume issueNodeId
exists (keeping error handling around getProjectCountForContent and the catch
that pushes the validation warning). Update references to issueNodeId,
linkedIssue, getProjectCountForContent, getKeywordLinkedIssuesFromPR,
getSameRepoManuallyLinkedIssues, and getSameRepoIssueNodeId accordingly (remove
the unreachable getSameRepoIssueNodeId usage and related message).

321-326: sameRepoRefsInBody may include PR references, not just issues.

The regex at line 44 matches any #N pattern, which includes references to PRs as well as issues. This could produce a misleading warning suggesting manual linking when the body actually references other PRs (e.g., "Related to #1234" where #1234 is a PR).

Consider validating that the numbers correspond to actual issues before emitting this diagnostic, or clarifying the warning text.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr_governance around lines 321 - 326, The warning is being
triggered by extractSameRepoIssueNumbersFromBody returning any `#N` (which can be
PRs), so update the logic that builds sameRepoRefsInBody (or post-filter it) to
only include numbers that are actual issues before pushing the warning: either
call the existing linkedIssues (or a new helper like isIssueNumber) to verify
each referenced number is an issue (not a PR) via the repo metadata/GitHub API
and filter out PR numbers, or change the warning text to explicitly say
"references other PRs/issues" instead of implying manual linking; ensure you
update the code paths around sameRepoRefsInBody, hasClosingKeywordText,
linkedIssues and warnings so the warning is emitted only when a referenced
number is confirmed to be an issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr_governance:
- Around line 1-17: Rename the workflow file named "pr_governance" to include a
YAML extension (e.g., "pr_governance.yml" or "pr_governance.yaml") so GitHub
Actions recognizes and executes it; ensure the file content (the "name:
pr-governance" workflow and its "on: pull_request_target" and "permissions"
blocks) remains unchanged after renaming.

---

Nitpick comments:
In @.github/workflows/pr_governance:
- Around line 126-219: The getSameRepoManuallyLinkedIssues function performs an
unbounded (up to maxIssuePages) scan of issues which can be very expensive for
large repos; to mitigate, document this behavior and provide an opt-out/config
option and a lower default cap: add a clear comment and README note that
scanning up to maxIssuePages (currently 10) may consume API quota, expose
maxIssuePages (or a boolean to disable the scan) as a configurable parameter,
and ensure the warnings.push message refers to that config so maintainers can
adjust or disable the github.graphql pagination scan if needed.
- Around line 41-42: The diagnostic regex stored in closingKeywordRegex requires
at least one whitespace after the optional colon which misses matches like
"closes#123"; update the pattern by replacing the `\s+` with `\s*` so zero or
more whitespace characters are allowed (keep the rest of the regex and the
case-insensitive flag intact) to match both "closes `#123`" and "closes#123".
- Around line 273-298: The branch that checks and refreshes issueNodeId is dead
because linkedIssue.id is always set by getKeywordLinkedIssuesFromPR and
getSameRepoManuallyLinkedIssues; remove the unreachable if-block that calls
getSameRepoIssueNodeId and the associated warning about unresolved node ID, and
simplify the loop to assume issueNodeId exists (keeping error handling around
getProjectCountForContent and the catch that pushes the validation warning).
Update references to issueNodeId, linkedIssue, getProjectCountForContent,
getKeywordLinkedIssuesFromPR, getSameRepoManuallyLinkedIssues, and
getSameRepoIssueNodeId accordingly (remove the unreachable
getSameRepoIssueNodeId usage and related message).
- Around line 321-326: The warning is being triggered by
extractSameRepoIssueNumbersFromBody returning any `#N` (which can be PRs), so
update the logic that builds sameRepoRefsInBody (or post-filter it) to only
include numbers that are actual issues before pushing the warning: either call
the existing linkedIssues (or a new helper like isIssueNumber) to verify each
referenced number is an issue (not a PR) via the repo metadata/GitHub API and
filter out PR numbers, or change the warning text to explicitly say "references
other PRs/issues" instead of implying manual linking; ensure you update the code
paths around sameRepoRefsInBody, hasClosingKeywordText, linkedIssues and
warnings so the warning is emitted only when a referenced number is confirmed to
be an issue.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d95ad5ca-d4cf-48db-8b34-cb6ba368efa7

📥 Commits

Reviewing files that changed from the base of the PR and between 97b5b0c and 02b25e6.

📒 Files selected for processing (1)
  • .github/workflows/pr_governance

Comment on lines +1 to +17
name: pr-governance

on:
pull_request_target:
types:
- opened
- edited
- synchronize
- reopened
- ready_for_review
- labeled
- unlabeled

permissions:
contents: read
pull-requests: read
issues: read
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.

⚠️ Potential issue | 🔴 Critical

File extension missing: workflow will not run.

GitHub Actions requires workflow files to have a .yml or .yaml extension. The file is named pr_governance but should be pr_governance.yml or pr_governance.yaml. Without the extension, GitHub will not recognize or execute this workflow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr_governance around lines 1 - 17, Rename the workflow
file named "pr_governance" to include a YAML extension (e.g.,
"pr_governance.yml" or "pr_governance.yaml") so GitHub Actions recognizes and
executes it; ensure the file content (the "name: pr-governance" workflow and its
"on: pull_request_target" and "permissions" blocks) remains unchanged after
renaming.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant