Skip to content

Commit d92f42e

Browse files
authored
Merge pull request #1513 from OneSignal/actions/set_response_time
Adding a new github action that allows us to measure issue response time
2 parents 389999f + d9dd257 commit d92f42e

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

.github/os_probot_metadata.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Based on probot-metadata - https://github.com/probot/metadata
3+
*/
4+
const regex = /\n\n<!-- probot = (.*) -->/
5+
6+
const { Octokit } = require("@octokit/action")
7+
8+
const octokit = new Octokit()
9+
10+
module.exports = (context, issue = null) => {
11+
console.log(context)
12+
const prefix = "onesignal-probot"
13+
14+
if (!issue) issue = context.payload.issue
15+
16+
return {
17+
async get (key = null) {
18+
let body = issue.body
19+
20+
if (!body) {
21+
body = (await octokit.issues.get(issue)).data.body || ''
22+
}
23+
24+
const match = body.match(regex)
25+
26+
if (match) {
27+
const data = JSON.parse(match[1])[prefix]
28+
return key ? data && data[key] : data
29+
}
30+
},
31+
32+
async set (key, value) {
33+
let body = issue.body
34+
let data = {}
35+
36+
if (!body) body = (await octokit.issues.get(issue)).data.body || ''
37+
38+
body = body.replace(regex, (_, json) => {
39+
data = JSON.parse(json)
40+
return ''
41+
})
42+
43+
if (!data[prefix]) data[prefix] = {}
44+
45+
if (typeof key === 'object') {
46+
Object.assign(data[prefix], key)
47+
} else {
48+
data[prefix][key] = value
49+
}
50+
51+
body = `${body}\n\n<!-- probot = ${JSON.stringify(data)} -->`
52+
53+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/")
54+
const issue_number = context.payload.issue.number
55+
return octokit.issues.update({ owner, repo, issue_number, body })
56+
}
57+
}
58+
}

.github/set_response_times.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
function calcResponseTimeForIssueCreatedAt(createdAt) {
2+
const issueOpenedDate = new Date(createdAt);
3+
const issueTriagedDate = new Date();
4+
const businessDaysResponseTime = calcBusinessDaysBetweenDates(issueOpenedDate, issueTriagedDate);
5+
return businessDaysResponseTime;
6+
}
7+
8+
function calcBusinessDaysBetweenDates(openedDate, triagedDate) {
9+
let differenceInWeeks, responseTime;
10+
if (triagedDate < openedDate)
11+
return -1; // error code if dates transposed
12+
let openedDay = openedDate.getDay(); // day of week
13+
let triagedDay = triagedDate.getDay();
14+
openedDay = (openedDay == 0) ? 7 : openedDay; // change Sunday from 0 to 7
15+
triagedDay = (triagedDay == 0) ? 7 : triagedDay;
16+
openedDay = (openedDay > 5) ? 5 : openedDay; // only count weekdays
17+
triagedDay = (triagedDay > 5) ? 5 : triagedDay;
18+
// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
19+
differenceInWeeks = Math.floor((triagedDate.getTime() - openedDate.getTime()) / 604800000);
20+
if (openedDay < triagedDay) { //Equal to makes it reduce 5 days
21+
responseTime = (differenceInWeeks * 5) + (triagedDay - openedDay);
22+
}
23+
else if (openedDay == triagedDay) {
24+
responseTime = differenceInWeeks * 5;
25+
}
26+
else {
27+
responseTime = ((differenceInWeeks + 1) * 5) - (openedDay - triagedDay);
28+
}
29+
return (responseTime);
30+
}
31+
32+
module.exports = async(context, osmetadata) => {
33+
const foundResponseTime = await osmetadata(context).get('response_time_in_business_days');
34+
if (foundResponseTime) {
35+
const foundString = "already found response time in business days: " + foundResponseTime
36+
console.log(foundString);
37+
return foundString;
38+
}
39+
if (context.payload.comment && context.payload.comment.author_association != "MEMBER" && context.payload.comment.author_association != "OWNER" && context.payload.comment.author_association != "CONTRIBUTOR") {
40+
return;
41+
}
42+
const businessDaysResponseTime = calcResponseTimeForIssueCreatedAt(context.payload.issue.created_at);
43+
console.log("response time in business days: " + businessDaysResponseTime);
44+
const result = osmetadata(context, context.payload.issue).set('response_time_in_business_days', businessDaysResponseTime)
45+
console.log("osmetadata update result: " + result);
46+
return "set response time in business days: " + businessDaysResponseTime;
47+
}
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Set Response Time
2+
on:
3+
issue_comment:
4+
types:
5+
- created
6+
issues:
7+
types:
8+
- closed
9+
jobs:
10+
calculate:
11+
name: set reponse time for the issue
12+
if: github.event.issue.pull_request == null
13+
runs-on: ubuntu-latest
14+
permissions:
15+
issues: write
16+
steps:
17+
- uses: actions/checkout@v3
18+
with:
19+
token: ${{ secrets.GITHUB_TOKEN }}
20+
- run: npm install @octokit/action
21+
- uses: actions/github-script@v6
22+
id: set-time
23+
with:
24+
result-encoding: string
25+
script: |
26+
const os_probot_metadata = require('./.github/os_probot_metadata.js')
27+
const set_response_time = require('./.github/set_response_times.js')
28+
return await set_response_time(context, os_probot_metadata)
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
- name: Get result
32+
run: echo "${{steps.set-time.outputs.result}}" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)