@@ -22,43 +22,67 @@ class BitBucketCloud {
22
22
23
23
async commentCreate ( opts = { } ) {
24
24
const { projectPath } = this ;
25
- const { commitSha, report } = opts ;
26
-
27
- // Make a comment in the commit
28
- const commitEndpoint = `/repositories/${ projectPath } /commit/${ commitSha } /comments/` ;
29
- const commitBody = JSON . stringify ( { content : { raw : report } } ) ;
30
- const commitOutput = await this . request ( {
31
- endpoint : commitEndpoint ,
32
- method : 'POST' ,
33
- body : commitBody
34
- } ) ;
25
+ const { commitSha, report, update, watermark } = opts ;
35
26
36
27
// Check for a corresponding PR. If it exists, also put the comment there.
37
- const getPrEndpt = `/repositories/${ projectPath } /commit/${ commitSha } /pullrequests` ;
38
- const { values : prs } = await this . request ( { endpoint : getPrEndpt } ) ;
28
+ let prs ;
29
+ try {
30
+ const getPrEndpoint = `/repositories/${ projectPath } /commit/${ commitSha } /pullrequests` ;
31
+ prs = await this . paginatedRequest ( { endpoint : getPrEndpoint } ) ;
32
+ } catch ( err ) {
33
+ if ( err . message === 'Not Found Resource not found' )
34
+ err . message =
35
+ "Click 'Go to pull request' on any commit details page to enable this API" ;
36
+ throw err ;
37
+ }
39
38
40
39
if ( prs && prs . length ) {
41
40
for ( const pr of prs ) {
42
- try {
43
- // Append a watermark to the report with a link to the commit
44
- const commitLink = commitSha . substr ( 0 , 7 ) ;
45
- const longReport = `${ commitLink } \n${ report } ` ;
46
- const prBody = JSON . stringify ( { content : { raw : longReport } } ) ;
47
-
48
- // Write a comment on the PR
49
- const prEndpoint = `/repositories/${ projectPath } /pullrequests/${ pr . id } /comments` ;
50
- await this . request ( {
51
- endpoint : prEndpoint ,
52
- method : 'POST' ,
53
- body : prBody
54
- } ) ;
55
- } catch ( err ) {
56
- console . debug ( err . message ) ;
57
- }
41
+ // Append a watermark to the report with a link to the commit
42
+ const commitLink = commitSha . substr ( 0 , 7 ) ;
43
+ const longReport = `${ commitLink } \n\n${ report } ` ;
44
+ const prBody = JSON . stringify ( { content : { raw : longReport } } ) ;
45
+
46
+ // Write a comment on the PR
47
+ const prEndpoint = `/repositories/${ projectPath } /pullrequests/${ pr . id } /comments/` ;
48
+ const existingPr = (
49
+ await this . paginatedRequest ( { endpoint : prEndpoint , method : 'GET' } )
50
+ )
51
+ . filter ( ( comment ) => {
52
+ const { content : { raw = '' } = { } } = comment ;
53
+ return raw . endsWith ( watermark ) ;
54
+ } )
55
+ . sort ( ( first , second ) => first . id < second . id )
56
+ . pop ( ) ;
57
+ await this . request ( {
58
+ endpoint : prEndpoint + ( update && existingPr ? existingPr . id : '' ) ,
59
+ method : update && existingPr ? 'PUT' : 'POST' ,
60
+ body : prBody
61
+ } ) ;
58
62
}
59
63
}
60
64
61
- return commitOutput ;
65
+ const commitEndpoint = `/repositories/${ projectPath } /commit/${ commitSha } /comments/` ;
66
+
67
+ const existingCommmit = (
68
+ await this . paginatedRequest ( { endpoint : commitEndpoint , method : 'GET' } )
69
+ )
70
+ . filter ( ( comment ) => {
71
+ const { content : { raw = '' } = { } } = comment ;
72
+ return raw . endsWith ( watermark ) ;
73
+ } )
74
+ . sort ( ( first , second ) => first . id < second . id )
75
+ . pop ( ) ;
76
+
77
+ return (
78
+ await this . request ( {
79
+ endpoint :
80
+ commitEndpoint +
81
+ ( update && existingCommmit ? existingCommmit . id : '' ) ,
82
+ method : update && existingCommmit ? 'PUT' : 'POST' ,
83
+ body : JSON . stringify ( { content : { raw : report } } )
84
+ } )
85
+ ) . links . html . href ;
62
86
}
63
87
64
88
async checkCreate ( ) {
@@ -150,15 +174,18 @@ class BitBucketCloud {
150
174
151
175
async request ( opts = { } ) {
152
176
const { token, api } = this ;
153
- const { endpoint, method = 'GET' , body } = opts ;
154
-
155
- if ( ! endpoint ) throw new Error ( 'BitBucket Cloud API endpoint not found' ) ;
177
+ const { url , endpoint, method = 'GET' , body } = opts ;
178
+ if ( ! ( url || endpoint ) )
179
+ throw new Error ( 'BitBucket Cloud API endpoint not found' ) ;
156
180
const headers = {
157
181
'Content-Type' : 'application/json' ,
158
182
Authorization : 'Basic ' + `${ token } `
159
183
} ;
160
- const url = `${ api } ${ endpoint } ` ;
161
- const response = await fetch ( url , { method, headers, body } ) ;
184
+ const response = await fetch ( url || `${ api } ${ endpoint } ` , {
185
+ method,
186
+ headers,
187
+ body
188
+ } ) ;
162
189
163
190
if ( response . status > 300 ) {
164
191
const {
@@ -170,6 +197,22 @@ class BitBucketCloud {
170
197
return await response . json ( ) ;
171
198
}
172
199
200
+ async paginatedRequest ( opts = { } ) {
201
+ const { method = 'GET' , body } = opts ;
202
+ const { next, values } = await this . request ( opts ) ;
203
+
204
+ if ( next ) {
205
+ const nextValues = await this . paginatedRequest ( {
206
+ url : next ,
207
+ method,
208
+ body
209
+ } ) ;
210
+ values . push ( ...nextValues ) ;
211
+ }
212
+
213
+ return values ;
214
+ }
215
+
173
216
get sha ( ) {
174
217
return BITBUCKET_COMMIT ;
175
218
}
0 commit comments