fix: pr requirements
This commit is contained in:
@@ -56,10 +56,10 @@ jobs:
|
|||||||
- mcp__github__get_issue: Get issue details
|
- mcp__github__get_issue: Get issue details
|
||||||
- mcp__github__search_issues: Search for similar issues
|
- mcp__github__search_issues: Search for similar issues
|
||||||
- mcp__github__list_issues: List recent issues if needed
|
- mcp__github__list_issues: List recent issues if needed
|
||||||
- mcp__github__create_issue_comment: Add a comment if duplicate found
|
- mcp__github__add_issue_comment: Add a comment if duplicate found
|
||||||
- mcp__github__update_issue: Add labels
|
- mcp__github__update_issue: Add labels
|
||||||
|
|
||||||
Be thorough but efficient. Focus on finding true duplicates, not just similar issues.
|
Be thorough but efficient. Focus on finding true duplicates, not just similar issues.
|
||||||
|
|
||||||
claude_args: |
|
claude_args: |
|
||||||
--allowedTools "mcp__github__get_issue,mcp__github__search_issues,mcp__github__list_issues,mcp__github__create_issue_comment,mcp__github__update_issue,mcp__github__get_issue_comments"
|
--allowedTools "mcp__github__get_issue,mcp__github__search_issues,mcp__github__list_issues,mcp__github__add_issue_comment,mcp__github__update_issue,mcp__github__get_issue_comments"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check PR has linked issue with assignee
|
- name: Check PR has linked issue with assignee
|
||||||
@@ -74,9 +75,10 @@ jobs:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if any linked issue has an assignee
|
// Check if any linked issue has the PR author as assignee
|
||||||
let issueWithAssignee = null;
|
const prAuthor = pr.user.login;
|
||||||
let issuesWithoutAssignee = [];
|
let issueWithAuthorAssigned = null;
|
||||||
|
let issuesWithoutAuthor = [];
|
||||||
|
|
||||||
for (const issueNum of issueNumbers) {
|
for (const issueNum of issueNumbers) {
|
||||||
try {
|
try {
|
||||||
@@ -86,29 +88,38 @@ jobs:
|
|||||||
issue_number: issueNum,
|
issue_number: issueNum,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (issue.assignees && issue.assignees.length > 0) {
|
const assigneeLogins = (issue.assignees || []).map(a => a.login);
|
||||||
issueWithAssignee = issueNum;
|
if (assigneeLogins.includes(prAuthor)) {
|
||||||
console.log(` Issue #${issueNum} has assignee(s): ${issue.assignees.map(a => a.login).join(', ')}`);
|
issueWithAuthorAssigned = issueNum;
|
||||||
|
console.log(` Issue #${issueNum} has PR author ${prAuthor} as assignee`);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
issuesWithoutAssignee.push(issueNum);
|
issuesWithoutAuthor.push({
|
||||||
console.log(` Issue #${issueNum} has no assignee`);
|
number: issueNum,
|
||||||
|
assignees: assigneeLogins
|
||||||
|
});
|
||||||
|
console.log(` Issue #${issueNum} assignees: ${assigneeLogins.length > 0 ? assigneeLogins.join(', ') : 'none'} (PR author: ${prAuthor})`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(` Issue #${issueNum} not found or inaccessible`);
|
console.log(` Issue #${issueNum} not found or inaccessible`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!issueWithAssignee) {
|
if (!issueWithAuthorAssigned) {
|
||||||
|
const issueList = issuesWithoutAuthor.map(i =>
|
||||||
|
`#${i.number} (assignees: ${i.assignees.length > 0 ? i.assignees.join(', ') : 'none'})`
|
||||||
|
).join(', ');
|
||||||
|
|
||||||
const message = `## PR Closed - Requirements Not Met
|
const message = `## PR Closed - Requirements Not Met
|
||||||
|
|
||||||
This PR has been automatically closed because it doesn't meet the requirements.
|
This PR has been automatically closed because it doesn't meet the requirements.
|
||||||
|
|
||||||
**Found issues:** ${issuesWithoutAssignee.map(n => `#${n}`).join(', ')}
|
**PR Author:** @${prAuthor}
|
||||||
**Problem:** None of the linked issues have an assignee.
|
**Found issues:** ${issueList}
|
||||||
|
**Problem:** The PR author must be assigned to the linked issue.
|
||||||
|
|
||||||
**To fix:**
|
**To fix:**
|
||||||
1. Assign someone to one of the linked issues
|
1. Assign yourself (@${prAuthor}) to one of the linked issues
|
||||||
2. Re-open this PR`;
|
2. Re-open this PR`;
|
||||||
|
|
||||||
const comments = await github.rest.issues.listComments({
|
const comments = await github.rest.issues.listComments({
|
||||||
@@ -138,7 +149,7 @@ jobs:
|
|||||||
state: 'closed',
|
state: 'closed',
|
||||||
});
|
});
|
||||||
|
|
||||||
core.setFailed('Linked issue must have an assignee');
|
core.setFailed('PR author must be assigned to the linked issue');
|
||||||
} else {
|
} else {
|
||||||
console.log(`PR requirements met! Issue #${issueWithAssignee} has an assignee.`);
|
console.log(`PR requirements met! Issue #${issueWithAuthorAssigned} has ${prAuthor} as assignee.`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# PR Requirements Workflow
|
||||||
|
|
||||||
|
This repository enforces that all pull requests must be linked to an issue that has an assignee. PRs that don't meet this requirement are automatically closed.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
For a PR to be accepted, it must:
|
||||||
|
|
||||||
|
1. **Reference an issue** - Include `Fixes #123`, `Closes #123`, or `#123` in the PR title or description
|
||||||
|
2. **PR author is assigned to the issue** - You must be assigned to the issue you're working on
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐
|
||||||
|
│ PR Opened/ │
|
||||||
|
│ Reopened │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────┐ No ┌─────────────────┐
|
||||||
|
│ Has issue │────────────►│ Close PR + │
|
||||||
|
│ reference? │ │ Comment │
|
||||||
|
└────────┬────────┘ └─────────────────┘
|
||||||
|
│ Yes
|
||||||
|
▼
|
||||||
|
┌─────────────────┐ No ┌─────────────────┐
|
||||||
|
│ PR author is │────────────►│ Close PR + │
|
||||||
|
│ assigned to │ │ Comment │
|
||||||
|
│ the issue? │ │ │
|
||||||
|
└────────┬────────┘ └─────────────────┘
|
||||||
|
│ Yes
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ PR Passes │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow Triggers
|
||||||
|
|
||||||
|
The check runs when a PR is:
|
||||||
|
- `opened` - New PR created
|
||||||
|
- `reopened` - Previously closed PR reopened
|
||||||
|
- `edited` - PR title or description changed
|
||||||
|
- `synchronize` - New commits pushed
|
||||||
|
|
||||||
|
## Fixing a Closed PR
|
||||||
|
|
||||||
|
If your PR was automatically closed:
|
||||||
|
|
||||||
|
1. **Create or find an issue** for the work you're doing
|
||||||
|
2. **Assign yourself** to that issue
|
||||||
|
3. **Re-open your PR**
|
||||||
|
4. **Add the issue reference** to your PR description:
|
||||||
|
```
|
||||||
|
Fixes #123
|
||||||
|
```
|
||||||
|
|
||||||
|
## Valid Issue Reference Formats
|
||||||
|
|
||||||
|
Any of these patterns in your PR title or description will work:
|
||||||
|
|
||||||
|
- `Fixes #123`
|
||||||
|
- `fixes #123`
|
||||||
|
- `Fixed #123`
|
||||||
|
- `Closes #123`
|
||||||
|
- `closes #123`
|
||||||
|
- `Closed #123`
|
||||||
|
- `Resolves #123`
|
||||||
|
- `resolves #123`
|
||||||
|
- `Resolved #123`
|
||||||
|
- `#123` (plain reference)
|
||||||
|
|
||||||
|
## Why This Requirement?
|
||||||
|
|
||||||
|
- Ensures all work is tracked in issues
|
||||||
|
- Guarantees the person submitting the PR is responsible for the work
|
||||||
|
- Prevents PRs for issues assigned to others
|
||||||
|
- Improves project organization and accountability
|
||||||
|
- Makes it easier to understand what each PR accomplishes
|
||||||
Reference in New Issue
Block a user