Skip to content

Commit 2dd1fc7

Browse files
authored
feat(1961): Use screwdriver-request package (#79)
1 parent 99bbf82 commit 2dd1fc7

File tree

3 files changed

+248
-444
lines changed

3 files changed

+248
-444
lines changed

index.js

Lines changed: 72 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
'use strict';
44

5-
const Fusebox = require('circuit-fuses').breaker;
5+
const Breaker = require('circuit-fuses').breaker;
66
const Scm = require('screwdriver-scm-base');
77
const hoek = require('@hapi/hoek');
88
const joi = require('joi');
99
const Path = require('path');
1010
const Url = require('url');
11-
const request = require('request');
11+
const request = require('screwdriver-request');
1212
const schema = require('screwdriver-data-schema');
1313
const API_URL_V2 = 'https://api.bitbucket.org/2.0';
1414
const REPO_URL = `${API_URL_V2}/repositories`;
@@ -28,37 +28,6 @@ const STATE_MAP = {
2828
};
2929
const WEBHOOK_PAGE_SIZE = 30;
3030

31-
/**
32-
* Check the status code of the server's response.
33-
*
34-
* If there was an error encountered with the request, this will format a human-readable
35-
* error message.
36-
* @method checkResponseError
37-
* @param {HTTPResponse} response HTTP Response from `request` call
38-
* @param {Number} response.statusCode HTTP status code of the HTTP request
39-
* @param {String} [response.body.error.message] Error message from the server
40-
* @param {String} [response.body.error.detail.required] Error resolution message
41-
* @return {Promise} Resolves when no error encountered
42-
* Rejects when status code is non-200
43-
*/
44-
function checkResponseError(response) {
45-
if (response.statusCode >= 200 && response.statusCode < 300) {
46-
return;
47-
}
48-
49-
const errorMessage = hoek.reach(response, 'body.error.message', {
50-
default: `SCM service unavailable (${response.statusCode}).`
51-
});
52-
const errorReason = hoek.reach(response, 'body.error.detail', {
53-
default: JSON.stringify(response.body)
54-
});
55-
56-
const error = new Error(`${errorMessage} Reason "${errorReason}"`);
57-
58-
error.status = response.statusCode;
59-
throw error;
60-
}
61-
6231
/**
6332
* Get repo information
6433
* @method getRepoInfo
@@ -101,6 +70,33 @@ function getScmUriParts(scmUri) {
10170
}
10271

10372
class BitbucketScm extends Scm {
73+
/**
74+
* Bitbucket command to run
75+
* @method _gitlabCommand
76+
* @param {Object} options An object that tells what command & params to run
77+
* @param {Object} [options.json] Body for request to make
78+
* @param {String} options.method Bitbucket method. For example: get
79+
* @param {String} options.route Route for gitlab.request()
80+
* @param {String} options.token Bitbucket token used for authentication of requests
81+
* @param {Function} callback Callback function from gitlab API
82+
*/
83+
_bitbucketCommand(options, callback) {
84+
const config = options;
85+
86+
// Everything else goes into context
87+
config.context = {
88+
token: options.token
89+
};
90+
delete config.token;
91+
92+
request(config)
93+
.then(function cb() {
94+
// Use "function" (not "arrow function") for getting "arguments"
95+
callback(null, ...arguments);
96+
})
97+
.catch(err => callback(err));
98+
}
99+
104100
/**
105101
* Constructor for Scm
106102
* @method constructor
@@ -155,7 +151,13 @@ class BitbucketScm extends Scm {
155151
'Invalid config for Bitbucket'
156152
);
157153

158-
this.breaker = new Fusebox(request, this.config.fusebox);
154+
// eslint-disable-next-line no-underscore-dangle
155+
this.breaker = new Breaker(this._bitbucketCommand.bind(this), {
156+
// Do not retry when there is a 4XX error
157+
shouldRetry: err => err && err.status && !(err.status >= 400 && err.status < 500),
158+
retry: this.config.fusebox.retry,
159+
breaker: this.config.fusebox.breaker
160+
});
159161

160162
// TODO: set fixed value temporarily.
161163
// need to change if the other bitbucket host is supported.
@@ -202,16 +204,11 @@ class BitbucketScm extends Scm {
202204
async _findWebhook({ page, repoId, token: configToken, url }) {
203205
const token = await this._getToken();
204206
const response = await this.breaker.runCommand({
205-
json: true,
206207
method: 'GET',
207-
auth: {
208-
bearer: token
209-
},
210-
url: `${API_URL_V2}/repositories/${repoId}/hooks?pagelen=30&page=${page}`
208+
token,
209+
url: `${REPO_URL}/${repoId}/hooks?pagelen=30&page=${page}`
211210
});
212211

213-
checkResponseError(response);
214-
215212
const hooks = response.body;
216213
const result = hooks.values.find(webhook => webhook.url === url);
217214

@@ -244,7 +241,7 @@ class BitbucketScm extends Scm {
244241
*/
245242
_createWebhook({ hookInfo, repoId, token, url, actions }) {
246243
const params = {
247-
body: {
244+
json: {
248245
description: 'Screwdriver-CD build trigger',
249246
url,
250247
active: true,
@@ -259,20 +256,17 @@ class BitbucketScm extends Scm {
259256
]
260257
: actions
261258
},
262-
json: true,
263259
method: 'POST',
264-
auth: {
265-
bearer: token
266-
},
267-
url: `${API_URL_V2}/repositories/${repoId}/hooks`
260+
token,
261+
url: `${REPO_URL}/${repoId}/hooks`
268262
};
269263

270264
if (hookInfo) {
271265
params.url = `${params.url}/${hookInfo.uuid}`;
272266
params.method = 'PUT';
273267
}
274268

275-
return this.breaker.runCommand(params).then(checkResponseError);
269+
return this.breaker.runCommand(params);
276270
}
277271

278272
/**
@@ -330,10 +324,7 @@ class BitbucketScm extends Scm {
330324
const options = {
331325
url: branchUrl,
332326
method: 'GET',
333-
json: true,
334-
auth: {
335-
bearer: token
336-
}
327+
token
337328
};
338329

339330
if (hostname !== this.hostname) {
@@ -429,10 +420,7 @@ class BitbucketScm extends Scm {
429420
const options = {
430421
url: `${USER_URL}/${encodeURIComponent(username)}`,
431422
method: 'GET',
432-
json: true,
433-
auth: {
434-
bearer: token
435-
}
423+
token
436424
};
437425

438426
const response = await this.breaker.runCommand(options);
@@ -478,10 +466,7 @@ class BitbucketScm extends Scm {
478466
const options = {
479467
url: `${REPO_URL}/${repoId}`,
480468
method: 'GET',
481-
json: true,
482-
auth: {
483-
bearer: token
484-
}
469+
token
485470
};
486471

487472
const response = await this.breaker.runCommand(options);
@@ -514,10 +499,7 @@ class BitbucketScm extends Scm {
514499
const options = {
515500
url: `${REPO_URL}/${scm.repoId}/commit/${sha}`,
516501
method: 'GET',
517-
json: true,
518-
auth: {
519-
bearer: token
520-
}
502+
token
521503
};
522504

523505
const response = await this.breaker.runCommand(options);
@@ -558,15 +540,14 @@ class BitbucketScm extends Scm {
558540
const options = {
559541
url: branchUrl,
560542
method: 'GET',
561-
json: true,
562-
auth: {
563-
bearer: token
564-
}
543+
token
565544
};
566545

567546
const response = await this.breaker.runCommand(options);
568547

569-
checkResponseError(response);
548+
if (response.statusCode !== 200) {
549+
throw new Error(`STATUS CODE ${response.statusCode}: ${JSON.stringify(response.body)}`);
550+
}
570551

571552
return response.body.target.hash;
572553
}
@@ -579,7 +560,7 @@ class BitbucketScm extends Scm {
579560
* @param {String} config.type Can be 'pr' or 'repo'
580561
* @param {Object} config.webhookPayload The webhook payload received from the
581562
* SCM service.
582-
* @param {String} config.token Service token to authenticate with Github
563+
* @param {String} config.token Service token to authenticate with Bitbucket
583564
* @return {Promise} Resolves to the content of the file
584565
*/
585566
_getChangedFiles() {
@@ -600,15 +581,12 @@ class BitbucketScm extends Scm {
600581
const { branch: branchFromScmUri, repoId, rootDir } = getScmUriParts(scmUri);
601582
const branch = ref || branchFromScmUri;
602583
const fullPath = rootDir ? Path.join(rootDir, path) : path;
603-
const fileUrl = `${API_URL_V2}/repositories/${repoId}/src/${branch}/${fullPath}`;
584+
const fileUrl = `${REPO_URL}/${repoId}/src/${branch}/${fullPath}`;
604585
const token = await this._getToken();
605586
const options = {
606587
url: fileUrl,
607588
method: 'GET',
608-
json: true,
609-
auth: {
610-
bearer: token
611-
}
589+
token
612590
};
613591

614592
const response = await this.breaker.runCommand(options);
@@ -634,25 +612,17 @@ class BitbucketScm extends Scm {
634612
const token = await this._getToken();
635613

636614
// First, check to see if the repository exists
637-
await this.breaker
638-
.runCommand({
639-
url: `${API_URL_V2}/repositories/${owner}/${uuid}`,
640-
method: 'GET',
641-
json: true,
642-
auth: {
643-
bearer: token
644-
}
645-
})
646-
.then(checkResponseError);
615+
await this.breaker.runCommand({
616+
url: `${REPO_URL}/${owner}/${uuid}`,
617+
method: 'GET',
618+
token
619+
});
647620

648621
const getPerm = async desiredAccess => {
649622
const options = {
650-
url: `${API_URL_V2}/repositories/${owner}?q=uuid%3D%22${uuid}%22`,
623+
url: `${REPO_URL}/${owner}?q=uuid%3D%22${uuid}%22`,
651624
method: 'GET',
652-
json: true,
653-
auth: {
654-
bearer: token
655-
}
625+
token
656626
};
657627

658628
if (desiredAccess === 'admin') {
@@ -705,16 +675,13 @@ class BitbucketScm extends Scm {
705675
const options = {
706676
url: `${REPO_URL}/${scm.repoId}/commit/${sha}/statuses/build`,
707677
method: 'POST',
708-
json: true,
709-
body: {
678+
json: {
710679
url,
711680
state: STATE_MAP[buildStatus],
712681
key: sha,
713682
description: context
714683
},
715-
auth: {
716-
bearer: decodeURIComponent(token)
717-
}
684+
token: decodeURIComponent(token)
718685
};
719686

720687
return this.breaker.runCommand(options).then(response => {
@@ -891,16 +858,11 @@ class BitbucketScm extends Scm {
891858
const token = await this._getToken();
892859

893860
const response = await this.breaker.runCommand({
894-
url: `${API_URL_V2}/repositories/${repoId}/pullrequests`,
861+
url: `${REPO_URL}/${repoId}/pullrequests`,
895862
method: 'GET',
896-
json: true,
897-
auth: {
898-
bearer: token
899-
}
863+
token
900864
});
901865

902-
checkResponseError(response);
903-
904866
const prList = response.body.values;
905867

906868
return prList.map(pr => ({
@@ -923,16 +885,11 @@ class BitbucketScm extends Scm {
923885
const token = await this._getToken();
924886

925887
const response = await this.breaker.runCommand({
926-
url: `${API_URL_V2}/repositories/${repoId}/pullrequests/${prNum}`,
888+
url: `${REPO_URL}/${repoId}/pullrequests/${prNum}`,
927889
method: 'GET',
928-
json: true,
929-
auth: {
930-
bearer: token
931-
}
890+
token
932891
});
933892

934-
checkResponseError(response);
935-
936893
const pr = response.body;
937894

938895
return {
@@ -1001,14 +958,9 @@ class BitbucketScm extends Scm {
1001958
async _findBranches(config) {
1002959
const token = await this._getToken();
1003960
const response = await this.breaker.runCommand({
1004-
json: true,
1005961
method: 'GET',
1006-
auth: {
1007-
bearer: token
1008-
},
1009-
url:
1010-
`${API_URL_V2}/repositories/${config.repoId}` +
1011-
`/refs/branches?pagelen=${BRANCH_PAGE_SIZE}&page=${config.page}`
962+
token,
963+
url: `${REPO_URL}/${config.repoId}/refs/branches?pagelen=${BRANCH_PAGE_SIZE}&page=${config.page}`
1012964
});
1013965

1014966
let branches = hoek.reach(response, 'body.values');
@@ -1024,11 +976,11 @@ class BitbucketScm extends Scm {
1024976
}
1025977

1026978
/**
1027-
* Get branch list from the Github repository
979+
* Get branch list from the Bitbucket repository
1028980
* @async _getBranchList
1029981
* @param {Object} config
1030982
* @param {String} config.scmUri The SCM URI to get branch list
1031-
* @param {String} config.token Service token to authenticate with Github
983+
* @param {String} config.token Service token to authenticate with Bitbucket
1032984
* @return {Promise} Resolves when complete
1033985
*/
1034986
async _getBranchList({ scmUri, token }) {
@@ -1066,10 +1018,8 @@ class BitbucketScm extends Scm {
10661018
async _refreshToken() {
10671019
const params = {
10681020
method: 'POST',
1069-
auth: {
1070-
user: this.config.oauthClientId,
1071-
pass: this.config.oauthClientSecret
1072-
},
1021+
username: this.config.oauthClientId,
1022+
password: this.config.oauthClientSecret,
10731023
url: `https://${this.hostname}/site/oauth2/access_token`,
10741024
form: {}
10751025
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
"@hapi/hoek": "^9.2.0",
5151
"circuit-fuses": "^4.0.6",
5252
"joi": "^17.2.1",
53-
"request": "^2.88.2",
5453
"screwdriver-data-schema": "^21.6.1",
54+
"screwdriver-request": "^1.0.0",
5555
"screwdriver-scm-base": "^7.2.1"
5656
}
5757
}

0 commit comments

Comments
 (0)