Skip to content

Commit c5dda79

Browse files
committed
feat: planning labels validation for epic owners
related: #327 This new GitHub Actions workflow listens for the 'opened' and 'labeled' events on GitHub issues and ensures any issue opened (or labelled) with a `planning` label meets the following criteria: - only users listed in the `AUTHORIZED_USER` JSON array can label an issue with the `planning` label - the `planning` label must be accompanied by exactly one of the following labels: - `epic`, `feature`, `task`, `bug` If an issue (with a `planning` label) is **opened** by a non-authorized user - the issue will be automatically closed when the GitHub action fires. If an issue is labelled with the `planning` label by an unauthorized user - the `planning` label is removed. In both cases, a GitHub comment is added to the issue explaining why the issue was updated by the bot. Please note, when opening a GH issue - **BOTH** the `opened` and `labeled` events will fire (if the issue has a label on it). As such, the GitHub action in this PR was deliberately structured to account for multiple instances running in parallel on the same underlying GitHub issue. Also, this work complements #361 - which defines GH issue templates that use the labels in a manner appropriate to satisfy the checks of this action. Signed-off-by: Andy Stoneberg <[email protected]>
1 parent b2bee1d commit c5dda79

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: Validate Planning Issue
2+
3+
on:
4+
issues:
5+
types: [opened, labeled]
6+
7+
env:
8+
AUTHORIZED_USERS: '["thesuperzapper", "ederign", "andyatmiami", "paulomvr", "jenny_s51", "harshad16"]'
9+
10+
permissions:
11+
issues: write
12+
13+
jobs:
14+
validate-issue:
15+
if: |
16+
(github.event.action == 'labeled' && github.event.label.name == 'planning') ||
17+
(github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'planning'))
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Log trigger
21+
uses: actions/github-script@v7
22+
with:
23+
script: |
24+
console.log(`Action triggered by: ${context.eventName} event with action: ${context.payload.action}`);
25+
if (context.payload.action === 'labeled') {
26+
console.log(`Label added: ${context.payload.label.name}`);
27+
} else if (context.payload.action === 'opened') {
28+
console.log(`Issue opened with labels: ${context.payload.issue.labels.map(l => l.name).join(', ')}`);
29+
}
30+
31+
- name: Handle labeled action
32+
if: github.event.action == 'labeled'
33+
uses: actions/github-script@v7
34+
with:
35+
script: |
36+
const AUTHORIZED_USERS = JSON.parse(process.env.AUTHORIZED_USERS);
37+
const actor = context.actor;
38+
const issueNumber = context.issue.number;
39+
40+
// First check user authorization
41+
if (!AUTHORIZED_USERS.includes(actor)) {
42+
// Remove the planning label
43+
await github.rest.issues.removeLabel({
44+
owner: context.repo.owner,
45+
repo: context.repo.repo,
46+
issue_number: issueNumber,
47+
name: 'planning'
48+
});
49+
50+
// Add a comment explaining why the label was removed
51+
await github.rest.issues.createComment({
52+
owner: context.repo.owner,
53+
repo: context.repo.repo,
54+
issue_number: issueNumber,
55+
body: `@${actor} You are not authorized to add planning labels. Only authorized users can add planning labels to issues.`
56+
});
57+
58+
core.setFailed(`User ${actor} is not authorized to add planning labels`);
59+
}
60+
61+
console.log(`User ${actor} is authorized to add planning labels`);
62+
63+
// Then check planning label requirements
64+
const { data: issue } = await github.rest.issues.get({
65+
owner: context.repo.owner,
66+
repo: context.repo.repo,
67+
issue_number: issueNumber
68+
});
69+
70+
const currentLabels = issue.labels.map(label => label.name);
71+
const planningLabels = ['epic', 'feature', 'task', 'bug'];
72+
const presentPlanningLabels = currentLabels.filter(label => planningLabels.includes(label));
73+
74+
if (presentPlanningLabels.length !== 1) {
75+
// Remove the planning label
76+
await github.rest.issues.removeLabel({
77+
owner: context.repo.owner,
78+
repo: context.repo.repo,
79+
issue_number: issueNumber,
80+
name: 'planning'
81+
});
82+
83+
// Add a comment explaining why the label was removed
84+
await github.rest.issues.createComment({
85+
owner: context.repo.owner,
86+
repo: context.repo.repo,
87+
issue_number: issueNumber,
88+
body: `@${actor} The planning label requires exactly one of the following labels to be present: ${planningLabels.join(', ')}. Please add one of these labels before adding the planning label.`
89+
});
90+
91+
core.setFailed(`Planning label requires exactly one of: ${planningLabels.join(', ')}`);
92+
}
93+
94+
console.log(`Issue has valid planning label combination: planning + ${presentPlanningLabels[0]}`);
95+
96+
- name: Handle opened action
97+
if: github.event.action == 'opened'
98+
uses: actions/github-script@v7
99+
with:
100+
script: |
101+
const AUTHORIZED_USERS = JSON.parse(process.env.AUTHORIZED_USERS);
102+
const actor = context.actor;
103+
const issueNumber = context.issue.number;
104+
105+
if (!AUTHORIZED_USERS.includes(actor)) {
106+
// Add a comment explaining why the issue will be closed
107+
await github.rest.issues.createComment({
108+
owner: context.repo.owner,
109+
repo: context.repo.repo,
110+
issue_number: issueNumber,
111+
body: `@${actor} You are not authorized to create planning issues. Only authorized users can create planning issues.`
112+
});
113+
114+
// Close the issue
115+
await github.rest.issues.update({
116+
owner: context.repo.owner,
117+
repo: context.repo.repo,
118+
issue_number: issueNumber,
119+
state: 'closed'
120+
});
121+
122+
core.setFailed(`User ${actor} is not authorized to create planning issues`);
123+
}
124+
125+
console.log(`User ${actor} is authorized to create planning issues`);

0 commit comments

Comments
 (0)