forked from drasi-project/drasi-core
-
Notifications
You must be signed in to change notification settings - Fork 0
178 lines (149 loc) · 7.49 KB
/
Copy pathpr-assignment-check.yml
File metadata and controls
178 lines (149 loc) · 7.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# Copyright 2026 The Drasi Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: PR Assignment Check
on:
pull_request_target:
types: [opened, reopened, edited]
jobs:
check-assignment:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
steps:
- name: Check PR has linked issue and author is assigned
uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const prNumber = context.payload.pull_request.number;
const prAuthor = context.payload.pull_request.user.login;
const prBody = context.payload.pull_request.body || '';
console.log(`Checking PR #${prNumber} by @${prAuthor}`);
// Skip check for maintainers (write or admin access)
const { data: permData } = await github.rest.repos.getCollaboratorPermissionLevel({
owner,
repo,
username: prAuthor,
});
const permission = permData.permission;
if (permission === 'admin' || permission === 'write') {
console.log(`@${prAuthor} has '${permission}' access — skipping assignment check`);
return;
}
// Extract linked issue numbers from PR body
// Matches: "Fixes #123", "Closes #123", "Resolves #123", "#123", etc.
const issuePattern = /(?:(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s*:?\s*)?#(\d+)/gi;
const linkedIssues = [];
let match;
while ((match = issuePattern.exec(prBody)) !== null) {
linkedIssues.push(parseInt(match[1], 10));
}
// Remove duplicates
const uniqueIssues = [...new Set(linkedIssues)];
console.log(`Found linked issues: ${uniqueIssues.join(', ') || 'none'}`);
// Case 1: No linked issue found
if (uniqueIssues.length === 0) {
const prLabels = context.payload.pull_request.labels.map(l => l.name);
const alreadyLabeled = prLabels.includes('needs-issue');
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: ['needs-issue']
});
// Only comment the first time to avoid spamming on repeated edits
if (!alreadyLabeled) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: `Hi @${prAuthor}, thanks for your contribution!
This PR doesn't appear to have a linked issue. Per our [contributing guidelines](https://github.com/drasi-project/drasi-core/blob/main/CONTRIBUTING.md#current-status), please:
1. Find an existing issue or [open a new one](https://github.com/drasi-project/drasi-core/issues/new/choose)
2. Wait to be assigned to the issue
3. Link the issue in your PR description using "Fixes #<issue-number>"
Please update the PR description to link to the relevant issue. If you need help finding an appropriate issue, check our [good first issues](https://github.com/drasi-project/drasi-core/issues?q=is:issue+is:open+label:%22good+first+issue%22).
Join our [Discord server](https://aka.ms/drasidiscord) to engage with maintainers and the community!`
});
}
console.log(alreadyLabeled
? 'PR already labeled needs-issue, skipping duplicate comment'
: 'Added label and comment for missing linked issue');
return;
}
// Case 2: Check if PR author is assigned to any of the linked issues
let authorAssignedToAny = false;
let checkedIssues = [];
for (const issueNumber of uniqueIssues) {
try {
const issue = await github.rest.issues.get({
owner,
repo,
issue_number: issueNumber,
});
const assignees = issue.data.assignees.map(a => a.login);
checkedIssues.push({ number: issueNumber, assignees });
if (assignees.includes(prAuthor)) {
authorAssignedToAny = true;
console.log(`Author @${prAuthor} is assigned to issue #${issueNumber}`);
break;
}
} catch (e) {
console.log(`Could not fetch issue #${issueNumber}: ${e.message}`);
}
}
if (!authorAssignedToAny) {
const prLabels = context.payload.pull_request.labels.map(l => l.name);
const alreadyLabeled = prLabels.includes('needs-assignment');
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: ['needs-assignment']
});
// Only comment the first time to avoid spamming on repeated edits
if (!alreadyLabeled) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: `Hi @${prAuthor}, thanks for your interest in contributing to drasi-core!
It looks like you are not currently assigned to the linked issue(s). Per our [contributing guidelines](https://github.com/drasi-project/drasi-core/blob/main/CONTRIBUTING.md#current-status):
> Please start by choosing an existing issue, or opening an issue to work on. The maintainers will respond to your issue, please work with the maintainers to ensure that what you're doing is in scope for the project before writing any code.
**To get assigned:**
1. Comment on the issue you'd like to work on to request assignment
2. Wait for a maintainer to assign you
This helps us coordinate work and avoid duplicate efforts. A maintainer will review your PR once assignment is confirmed.
Join our [Discord server](https://aka.ms/drasidiscord) to engage with maintainers and the community!`
});
}
console.log(alreadyLabeled
? `PR #${prNumber} already labeled needs-assignment, skipping duplicate comment`
: `PR #${prNumber} - author not assigned to linked issues, added label and comment`);
} else {
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'needs-assignment'
});
console.log(`Removed "needs-assignment" label from PR #${prNumber}`);
} catch (e) {
// Label might not exist, that's fine
if (e.status !== 404) throw e;
}
console.log(`PR #${prNumber} passed assignment check`);
}