-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
170 lines (144 loc) · 4.84 KB
/
index.js
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
const Queue = require('bee-queue')
const Sentry = require('@sentry/node')
const analytics = require('./src/analytics')
const threadLabeled = require('./src/thread/labeled')
const threadOpened = require('./src/thread/opened')
const pullLabeled = require('./src/pull/labeled')
const pullMerged = require('./src/pull/merged')
const pullSynchronized = require('./src/pull/synchronized')
const threadClosed = require('./src/thread/closed')
const commentDeleted = require('./src/comment/deleted')
const commentCreated = require('./src/comment/created')
const installationCreated = require('./src/installation/created')
const installationAdded = require('./src/installation/added')
const { CLOSE, MERGE, COMMENT, LOCK, OPEN } = require('./src/constants')
const verifyPaymentPlan = require('./src/verify-payment-plan')
// Probot will also send errors to Sentry DNS: https://probot.github.io/docs/configuration/
Sentry.init({ dsn: process.env.SENTRY_DSN })
module.exports = async ({ app, getRouter }) => {
const router = getRouter('/')
router.get('/health', (req, res) => res.send('OK'))
if (process.env.NODE_ENV !== 'test') {
process.on('uncaughtException', (e) => {
app.log.error(e)
})
process.on('unhandledRejection', (e) => {
app.log.error(e)
})
}
const queue = new Queue('issues', {
removeOnSuccess: true,
removeOnFailure: true,
activateDelayedJobs: true,
redis: {
db: 0,
url: process.env.REDIS_URL,
},
})
queue.process(async (job) => {
analytics.track(() => ({
userId: job.data.installation_id,
event: `Processing job`,
properties: job.data,
}))
try {
switch (job.data.action) {
case MERGE:
return await pullLabeled.process(app)(job)
case LOCK:
return await threadClosed.process(app)(job)
case COMMENT:
case CLOSE:
case OPEN:
default:
return await threadLabeled.process(app)(job)
}
} catch (error) {
if (process.env.NODE_ENV !== 'test') {
app.log(error, job)
}
throw error
}
})
queue.on('succeeded', (job, result) => {
app.log.debug(`Job ${job.id} succeeded with result: ${JSON.stringify(result, null, 2)}`)
})
queue.on('failed', (job, err) => {
if (err.message === 'Retry job') {
return
}
app.log.error(
`Job ${job.id} with data ${JSON.stringify(job.data, null, 2)} failed with error ${
err.message
}`
)
Sentry.configureScope((scope) => {
if (job.data.owner) {
scope.setUser({ ...job.data, username: job.data.owner })
}
Sentry.captureException(err)
})
})
function wrapPaymentCheck(fn) {
return async (context) => {
if (await verifyPaymentPlan(app, context)) {
fn(context)
}
}
}
function wrapSentry(fn) {
return async (context) => {
try {
return await fn(context)
} catch (error) {
Sentry.configureScope((scope) => {
scope.setUser({
id: context.payload.installation.id,
username: context.payload.installation.account.login,
})
Sentry.captureException(error)
})
app.log.error(error)
}
}
}
// Listeners
app.on(
// All pull requests are issues in GitHub REST V3
['issues.labeled', 'issues.unlabeled', 'pull_request.labeled', 'pull_request.unlabeled'],
wrapPaymentCheck(threadLabeled(queue))
)
app.on(['issues.opened', 'pull_request.opened'], wrapPaymentCheck(threadOpened(queue)))
app.on(
[
'pull_request.labeled',
'pull_request.unlabeled',
'pull_request.synchronize',
'pull_request_review.submitted',
// `pull_request.edited`
],
wrapPaymentCheck(pullLabeled(queue))
)
// TODO rerun pull labeled job on `check_suite.completed`
app.on(['issue_comment.created', 'issue_comment.edited'], wrapPaymentCheck(commentCreated()))
app.on('pull_request.closed', wrapPaymentCheck(pullMerged.deleteBranch()))
app.on('pull_request.closed', wrapPaymentCheck(pullMerged.createTag()))
app.on(['pull_request.opened', 'pull_request.synchronize'], wrapPaymentCheck(pullSynchronized()))
// Kill job when issue/pull is closed
app.on(['issues.closed', 'pull_request.closed'], threadClosed(queue))
app.on('issue_comment.deleted', commentDeleted(queue))
app.on(['installation.created'], installationCreated(app))
app.on(
['installation_repositories.added', 'installation.created'],
wrapSentry(installationAdded(app))
)
// TODO 'marketplace_purchase.purchased'
// TODO use status updates to retrigger merge jobs
// robot.on('status', c => console.log(c.payload))
// For more information on building apps:
// https://probot.github.io/docs/
// To get your app running against GitHub, see:
// https://probot.github.io/docs/development/
app.queue = queue
app.analytics = analytics
}