1
- import { ACCEPTED , NO_CONTENT , BAD_REQUEST , UNSUPPORTED_MEDIA_TYPE } from 'http-status-codes' ;
1
+ import { ACCEPTED , BAD_REQUEST , NO_CONTENT , UNSUPPORTED_MEDIA_TYPE } from 'http-status-codes' ;
2
2
import boom from 'boom' ;
3
3
import openedByGreenkeeperBot from './greenkeeper' ;
4
4
import createActions from './github/actions' ;
5
5
import process from './process' ;
6
6
7
- function successfulStatusCouldBeForGreenkeeperPR ( event , state , branches , log ) {
8
- if ( 'status' !== event ) {
9
- log ( [ 'PR' ] , `event was \`${ event } \` instead of \`status\`` ) ;
7
+ function determineIfWebhookConfigIsCorrect ( hook , responseToolkit ) {
8
+ if ( 'json' !== hook . config . content_type ) {
9
+ return responseToolkit
10
+ . response ( 'please update your webhook configuration to send application/json' )
11
+ . code ( UNSUPPORTED_MEDIA_TYPE ) ;
12
+ }
13
+
14
+ return responseToolkit . response ( 'successfully configured the webhook for greenkeeper-keeper' ) . code ( NO_CONTENT ) ;
15
+ }
16
+
17
+ function branchIsNotMaster ( branchName , log ) {
18
+ if ( 'master' === branchName ) {
19
+ log ( [ 'PR' ] , `branch name \`${ branchName } \` should not be \`master\`` ) ;
10
20
return false ;
11
21
}
12
22
23
+ return true ;
24
+ }
25
+
26
+ function statusEventIsSuccessfulAndCouldBeForGreenkeeperPR ( state , branches , log ) {
13
27
if ( 'success' !== state ) {
14
28
log ( [ 'PR' ] , `state was \`${ state } \` instead of \`success\`` ) ;
15
29
return false ;
@@ -20,52 +34,105 @@ function successfulStatusCouldBeForGreenkeeperPR(event, state, branches, log) {
20
34
return false ;
21
35
}
22
36
23
- const branchName = branches [ 0 ] . name ;
24
- if ( 'master' === branchName ) {
25
- log ( [ 'PR' ] , `branch name \`${ branchName } \` should not be \`master\`` ) ;
37
+ return branchIsNotMaster ( branches [ 0 ] . name , log ) ;
38
+ }
39
+
40
+ function checkRunEventIsSuccessfulAndCouldBeForGreenkeeperPR ( checkRun , log ) {
41
+ const { status, conclusion, check_suite : checkSuite } = checkRun ;
42
+ const { head_branch : headBranch } = checkSuite ;
43
+
44
+ if ( 'completed' !== status ) {
45
+ log ( [ 'PR' ] , `check_run status was \`${ status } \` instead of \`completed\`` ) ;
26
46
return false ;
27
47
}
28
48
29
- return true ;
49
+ if ( 'success' !== conclusion ) {
50
+ log ( [ 'PR' ] , `check_run conclusion was \`${ conclusion } \` instead of \`success\`` ) ;
51
+ return false ;
52
+ }
53
+
54
+ return branchIsNotMaster ( headBranch , log ) ;
30
55
}
31
56
32
- export default async function ( request , responseToolkit , settings ) {
57
+ async function processStatusEvent ( payload , settings , request , responseToolkit , log ) {
33
58
const { state, repository, branches, sha} = request . payload ;
34
- const event = request . headers [ 'x-github-event' ] ;
35
-
36
- if ( 'ping' === event ) {
37
- if ( 'json' !== request . payload . hook . config . content_type ) {
38
- return responseToolkit
39
- . response ( 'please update your webhook configuration to send application/json' )
40
- . code ( UNSUPPORTED_MEDIA_TYPE ) ;
41
- }
42
59
43
- return responseToolkit . response ( 'successfully configured the webhook for greenkeeper-keeper' ) . code ( NO_CONTENT ) ;
44
- }
45
-
46
- if ( successfulStatusCouldBeForGreenkeeperPR ( event , state , branches , ( ...args ) => request . log ( ...args ) ) ) {
60
+ if ( statusEventIsSuccessfulAndCouldBeForGreenkeeperPR ( state , branches , log ) ) {
47
61
const { getPullRequestsForCommit, getPullRequest} = createActions ( settings . github ) ;
48
62
49
63
return getPullRequestsForCommit ( { ref : sha } )
50
64
. then ( async pullRequests => {
51
65
if ( ! pullRequests . length ) return responseToolkit . response ( 'no PRs for this commit' ) . code ( BAD_REQUEST ) ;
52
66
53
67
if ( 1 < pullRequests . length ) {
54
- return responseToolkit . response ( boom . internal ( 'too many PRs exist for this commit' ) ) ;
68
+ throw boom . internal ( 'too many PRs exist for this commit' ) ;
55
69
}
56
70
57
71
const senderUrl = pullRequests [ 0 ] . user . html_url ;
58
72
if ( openedByGreenkeeperBot ( senderUrl ) ) {
59
- process ( request , await getPullRequest ( repository , pullRequests [ 0 ] . number ) , settings ) ;
60
- return responseToolkit . response ( 'ok ' ) . code ( ACCEPTED ) ;
73
+ process ( await getPullRequest ( repository , pullRequests [ 0 ] . number ) , settings , log ) ;
74
+ return responseToolkit . response ( 'status event will be processed ' ) . code ( ACCEPTED ) ;
61
75
}
62
76
63
77
return responseToolkit . response ( `PR is not from greenkeeper, but from ${ senderUrl } ` ) . code ( BAD_REQUEST ) ;
64
78
} )
65
79
. catch ( e => boom . internal ( 'failed to fetch PRs' , e ) ) ;
66
80
}
67
81
68
- request . log ( [ 'PR' ] , 'skipping' ) ;
82
+ log ( [ 'PR' ] , 'skipping' ) ;
69
83
70
84
return responseToolkit . response ( 'skipping' ) . code ( BAD_REQUEST ) ;
71
85
}
86
+
87
+ async function processCheckRunEvent ( request , responseToolkit , settings , log ) {
88
+ const { repository, check_run : checkRun , sender} = request . payload ;
89
+
90
+ if ( checkRunEventIsSuccessfulAndCouldBeForGreenkeeperPR ( checkRun , log ) ) {
91
+ const { check_suite : { pull_requests : pullRequests } } = checkRun ;
92
+ const { getPullRequest} = createActions ( settings . github ) ;
93
+
94
+ if ( ! pullRequests . length ) return responseToolkit . response ( 'no PRs for this commit' ) . code ( BAD_REQUEST ) ;
95
+ if ( 1 < pullRequests . length ) return responseToolkit . response ( boom . internal ( 'too many PRs exist for this commit' ) ) ;
96
+
97
+ const senderUrl = sender . html_url ;
98
+ if ( ! openedByGreenkeeperBot ( senderUrl ) ) {
99
+ return responseToolkit . response ( `PR is not from greenkeeper, but from ${ senderUrl } ` ) . code ( BAD_REQUEST ) ;
100
+ }
101
+
102
+ let pullRequest ;
103
+ try {
104
+ pullRequest = await getPullRequest ( repository , pullRequests [ 0 ] . number ) ;
105
+ } catch ( err ) {
106
+ throw boom . internal ( 'failed to fetch PRs' , err ) ;
107
+ }
108
+
109
+ process ( pullRequest , settings , log ) ;
110
+ return responseToolkit . response ( 'check_run event will be processed' ) . code ( ACCEPTED ) ;
111
+ }
112
+
113
+ log ( [ 'PR' ] , 'skipping' ) ;
114
+
115
+ return responseToolkit . response ( 'skipping' ) . code ( BAD_REQUEST ) ;
116
+ }
117
+
118
+ export default async function ( request , responseToolkit , settings ) {
119
+ const { hook} = request . payload ;
120
+ const event = request . headers [ 'x-github-event' ] ;
121
+
122
+ function logger ( ...args ) {
123
+ request . log ( ...args ) ;
124
+ }
125
+
126
+ switch ( event ) {
127
+ case 'ping' :
128
+ return determineIfWebhookConfigIsCorrect ( hook , responseToolkit ) ;
129
+ case 'status' :
130
+ return processStatusEvent ( request . payload , settings , request , responseToolkit , logger ) ;
131
+ case 'check_run' :
132
+ return processCheckRunEvent ( request , responseToolkit , settings , logger ) ;
133
+ default :
134
+ return responseToolkit
135
+ . response ( `event was \`${ event } \` instead of \`status\` or \`check_run\`` )
136
+ . code ( BAD_REQUEST ) ;
137
+ }
138
+ }
0 commit comments