Skip to content

Commit b8328e4

Browse files
Merge pull request #210 from shubham1172/shubham1172/enhance-dapr-bot
Enhance Dapr Bot
2 parents c0aa52d + f8ffe77 commit b8328e4

File tree

4 files changed

+267
-16
lines changed

4 files changed

+267
-16
lines changed

.github/scripts/dapr_bot.js

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
// list of owner who can control dapr-bot workflow.
2+
// TODO: Read owners from OWNERS file.
3+
const owners = [
4+
"yaron2",
5+
"youngbupark",
6+
"Haishi2016",
7+
"lukekim",
8+
"amanbha",
9+
"msfussell",
10+
"shalabhms",
11+
"LMWF",
12+
"artursouza",
13+
"vinayada1",
14+
"mukundansundar",
15+
"wcs1only",
16+
"orizohar",
17+
"pruthvidhodda",
18+
"mchmarny",
19+
"tcnghia",
20+
"berndverst",
21+
"halspang",
22+
"tanvigour",
23+
"dmitsh",
24+
"pkedy",
25+
"CodeMonkeyLeet",
26+
"XavierGeerinck",
27+
"amulyavarote",
28+
"shubham1172"
29+
];
30+
31+
/**
32+
* Execute fn if label exists on an issue.
33+
* @param {*} github GitHub object reference
34+
* @param {*} issue GitHub issue reference
35+
* @param {*} label label name
36+
* @param {*} fn async function
37+
*/
38+
async function executeIfIssueHasLabel(github, issue, label, fn) {
39+
const response = await github.issues.listLabelsOnIssue({
40+
issue_number: issue.number,
41+
owner: issue.owner,
42+
repo: issue.repo,
43+
});
44+
45+
const labelNames = response.data.map((i) => i.name);
46+
if (labelNames.indexOf(label) > -1) {
47+
await fn();
48+
}
49+
}
50+
51+
/**
52+
* Assign an issue to assignee.
53+
* @param {*} github GitHub object reference
54+
* @param {*} context GitHub action context
55+
* @param {boolean} isPullRequest is the workflow triggered by a pull request?
56+
*/
57+
async function executeAssign(github, context, isPullRequest) {
58+
const issue = context.issue;
59+
60+
if (isPullRequest) {
61+
console.log("[executeAssign] pull requests unsupported, skipping command execution.");
62+
return;
63+
} else if (issue.assignees && issue.assignees.length !== 0) {
64+
console.log("[executeAssign] issue already has assignees, skipping command execution.");
65+
return;
66+
}
67+
68+
await github.issues.addAssignees({
69+
owner: issue.owner,
70+
repo: issue.repo,
71+
issue_number: issue.number,
72+
assignees: [context.actor],
73+
});
74+
}
75+
76+
/**
77+
* Add a label to the issue indicating that it needs the author's feedback.
78+
* @param {*} github GitHub object reference
79+
* @param {*} context GitHub action context
80+
* @param {boolean} isPullRequest is the workflow triggered by a pull request?
81+
* @returns
82+
*/
83+
async function executePingAuthor(github, context, isPullRequest) {
84+
const issue = context.issue;
85+
86+
if (isPullRequest) {
87+
console.log("[executePingAuthor] pull requests unsupported, skipping command execution.");
88+
return;
89+
} else if (owners.indexOf(context.actor) < 0) {
90+
console.log("[executePingAuthor] user does not have privilege, skipping command execution.");
91+
return;
92+
}
93+
94+
// if there is a 'needs-team-attention' label, remove it.
95+
await executeIfIssueHasLabel(github, issue, 'needs-team-attention', async () => {
96+
await github.issues.removeLabel({
97+
issue_number: issue.number,
98+
owner: issue.owner,
99+
repo: issue.repo,
100+
name: 'needs-team-attention'
101+
});
102+
});
103+
104+
// Add new label
105+
await github.issues.addLabels({
106+
issue_number: issue.number,
107+
owner: issue.owner,
108+
repo: issue.repo,
109+
labels: ['needs-author-feedback']
110+
});
111+
}
112+
113+
/**
114+
* Trigger e2e tests for pull request
115+
* @param {*} github GitHub object reference
116+
* @param {*} context GitHub action context
117+
* @param {boolean} isPullRequest is the workflow triggered by a pull request?
118+
*/
119+
async function executeEndToEndTests(github, context, isPullRequest) {
120+
const issue = context.issue;
121+
122+
if (!isPullRequest) {
123+
console.log("[executeEndToEndTests] issues unsupported, skipping command execution.");
124+
return;
125+
} else if (owners.indexOf(context.actor) < 0) {
126+
console.log("[executeEndToEndTests] user does not have privilege, skipping command execution.");
127+
return;
128+
}
129+
130+
// Get pull request
131+
const pull = await github.pulls.get({
132+
owner: issue.owner,
133+
repo: issue.repo,
134+
pull_number: issue.number
135+
});
136+
137+
if (pull && pull.data) {
138+
// Get commit id and repo from pull head
139+
const clientPayload = {
140+
pull_head_ref: pull.data.head.sha,
141+
pull_head_repo: pull.data.head.repo.full_name,
142+
command: "ok-to-e2e-test",
143+
issue: issue,
144+
};
145+
146+
// Fire repository_dispatch event to trigger e2e test
147+
await github.repos.createDispatchEvent({
148+
owner: issue.owner,
149+
repo: issue.repo,
150+
event_type: "e2e-test",
151+
client_payload: clientPayload,
152+
});
153+
154+
console.log(`[executeEndToEndTests] triggered E2E tests for ${JSON.stringify(clientPayload)}.`);
155+
}
156+
}
157+
158+
159+
export default async ({ github, context }) => {
160+
const payload = context.payload;
161+
const issue = context.issue;
162+
const isFromPulls = !!payload.issue.pull_request;
163+
const commentBody = payload.comment.body;
164+
165+
if (!commentBody) {
166+
console.log("[main] comment body not found, exiting.");
167+
return;
168+
}
169+
170+
// the author of this issue is interacting with it
171+
if (!isFromPulls && context.actor == issue.owner) {
172+
// if there is a 'needs-author-feedback' label,
173+
// replace it with 'needs-team-attention' label.
174+
await executeIfIssueHasLabel(github, issue, 'needs-author-feedback', async () => {
175+
await github.issues.removeLabel({
176+
issue_number: issue.number,
177+
owner: issue.owner,
178+
repo: issue.repo,
179+
name: 'needs-author-feedback'
180+
});
181+
await github.issues.addLabels({
182+
issue_number: issue.number,
183+
owner: issue.owner,
184+
repo: issue.repo,
185+
labels: ['needs-team-attention']
186+
});
187+
});
188+
}
189+
190+
switch (commentBody) {
191+
case "/assign":
192+
executeAssign(github, context, isFromPulls);
193+
break;
194+
case "/ping-author":
195+
executePingAuthor(github, context, isFromPulls);
196+
break;
197+
case "/ok-to-e2e-test":
198+
executeEndToEndTests(github, context, isFromPulls);
199+
break;
200+
default:
201+
console.log(`[main] command ${commentBody} not found, exiting.`);
202+
break;
203+
}
204+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#
2+
# Copyright 2022 The Dapr Authors
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
14+
name: dapr-bot-schedule
15+
16+
on:
17+
schedule:
18+
- cron: '*/10 * * * *'
19+
workflow_dispatch:
20+
jobs:
21+
prune_stale:
22+
name: Prune Stale
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Prune Stale
26+
uses: actions/[email protected]
27+
with:
28+
repo-token: ${{ secrets.DAPR_BOT_TOKEN }}
29+
days-before-issue-stale: 60
30+
days-before-pr-stale: 30
31+
days-before-close: 7
32+
stale-issue-message: >
33+
This issue has been automatically marked as stale because it has not had activity in the
34+
last 60 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue, help wanted or triaged/resolved) or other activity
35+
occurs. Thank you for your contributions.
36+
close-issue-message: >
37+
This issue has been automatically closed because it has not had activity in the
38+
last 67 days. If this issue is still valid, please ping a maintainer and ask them to label it as pinned, good first issue, help wanted or triaged/resolved.
39+
Thank you for your contributions.
40+
stale-pr-message: >
41+
This pull request has been automatically marked as stale because it has not had
42+
activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please
43+
feel free to give a status update now, ping for review, or re-open when it's ready.
44+
Thank you for your contributions!
45+
close-pr-message: >
46+
This pull request has been automatically closed because it has not had
47+
activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready.
48+
Thank you for your contributions!
49+
stale-issue-label: 'stale'
50+
exempt-issue-labels: 'pinned,good first issue,help wanted,triaged/resolved,triaged/unresolved'
51+
stale-pr-label: 'stale'
52+
exempt-pr-labels: 'pinned'
53+
operations-per-run: 500
54+
ascending: true

.github/workflows/dapr-bot.yml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,11 @@ jobs:
2222
name: bot-processor
2323
runs-on: ubuntu-latest
2424
steps:
25+
- uses: actions/checkout@v2 # to make the JS script available for the next step
2526
- name: Comment analyzer
26-
uses: actions/github-script@v1
27+
uses: actions/github-script@v4
2728
with:
2829
github-token: ${{secrets.DAPR_BOT_TOKEN}}
2930
script: |
30-
const payload = context.payload;
31-
const issue = context.issue;
32-
const isFromPulls = !!payload.issue.pull_request;
33-
const commentBody = payload.comment.body;
34-
if (!isFromPulls && commentBody && commentBody.indexOf("/assign") == 0) {
35-
if (!issue.assignees || issue.assignees.length === 0) {
36-
await github.issues.addAssignees({
37-
owner: issue.owner,
38-
repo: issue.repo,
39-
issue_number: issue.number,
40-
assignees: [context.actor],
41-
})
42-
}
43-
return;
44-
}
31+
const script = require('./.github/scripts/dapr_bot.js')
32+
await script({github, context})

.github/workflows/test-e2e.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ on:
2424
branches:
2525
- master
2626
- release-*
27+
# Manual trigger
28+
workflow_dispatch:
29+
# Dispatch on external events
30+
repository_dispatch:
31+
types: [e2e-test]
2732

2833
jobs:
2934
test-e2e:

0 commit comments

Comments
 (0)