Skip to content

Commit

Permalink
refactor(bitbucket-server): Switch to new http wrapper (#6393)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov committed Jun 1, 2020
1 parent dcbef85 commit b4b6618
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 73 deletions.
40 changes: 0 additions & 40 deletions lib/platform/bitbucket-server/bb-got-wrapper.ts

This file was deleted.

80 changes: 50 additions & 30 deletions lib/platform/bitbucket-server/index.ts
Expand Up @@ -11,6 +11,11 @@ import { PR_STATE_ALL, PR_STATE_OPEN } from '../../constants/pull-requests';
import { logger } from '../../logger';
import { BranchStatus } from '../../types';
import * as hostRules from '../../util/host-rules';
import { HttpResponse } from '../../util/http';
import {
BitbucketServerHttp,
setBaseUrl,
} from '../../util/http/bitbucket-server';
import { sanitize } from '../../util/sanitize';
import { ensureTrailingSlash } from '../../util/url';
import {
Expand All @@ -22,7 +27,6 @@ import {
EnsureIssueConfig,
EnsureIssueResult,
FindPRConfig,
GotResponse,
Issue,
PlatformConfig,
Pr,
Expand All @@ -32,7 +36,6 @@ import {
} from '../common';
import GitStorage, { StatusResult } from '../git/storage';
import { smartTruncate } from '../utils/pr-body';
import { api } from './bb-got-wrapper';
import { BbbsRestPr, BbsConfig, BbsPr, BbsRestUserRef } from './types';
import * as utils from './utils';
import { PartialDeep } from 'type-fest';
Expand All @@ -48,6 +51,8 @@ import { PartialDeep } from 'type-fest';

let config: BbsConfig = {} as any;

const bitbucketServerHttp = new BitbucketServerHttp();

const defaults: any = {
hostType: PLATFORM_TYPE_BITBUCKET_SERVER,
};
Expand All @@ -74,7 +79,7 @@ export function initPlatform({
}
// TODO: Add a connection check that endpoint/username/password combination are valid
defaults.endpoint = ensureTrailingSlash(endpoint);
api.setBaseUrl(defaults.endpoint);
setBaseUrl(defaults.endpoint);
const platformConfig: PlatformConfig = {
endpoint: defaults.endpoint,
};
Expand Down Expand Up @@ -141,7 +146,7 @@ export async function initRepo({

let renovateConfig: RenovateConfig;
try {
const { body } = await api.get<FileData>(
const { body } = await bitbucketServerHttp.getJson<FileData>(
`./rest/api/1.0/projects/${projectKey}/repos/${repositorySlug}/browse/renovate.json?limit=20000`
);
if (!body.isLastPage) {
Expand Down Expand Up @@ -190,14 +195,17 @@ export async function initRepo({

try {
const info = (
await api.get(
await bitbucketServerHttp.getJson<{
project: { key: string };
parent: string;
}>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`
)
).body;
config.owner = info.project.key;
logger.debug(`${repository} owner = ${config.owner}`);
config.defaultBranch = (
await api.get(
await bitbucketServerHttp.getJson<{ displayId: string }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/branches/default`
)
).body.displayId;
Expand All @@ -222,7 +230,9 @@ export async function getRepoForceRebase(): Promise<boolean> {
logger.debug(`getRepoForceRebase()`);

// https://docs.atlassian.com/bitbucket-server/rest/7.0.1/bitbucket-rest.html#idp342
const res = await api.get(
const res = await bitbucketServerHttp.getJson<{
mergeConfig: { defaultStrategy: { id: string } };
}>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/settings/pull-requests`
);

Expand All @@ -233,7 +243,7 @@ export async function getRepoForceRebase(): Promise<boolean> {
return Boolean(
res.body.mergeConfig &&
res.body.mergeConfig.defaultStrategy &&
res.body.mergeConfig.defaultStrategy.id.indexOf('ff-only') >= 0
res.body.mergeConfig.defaultStrategy.id.includes('ff-only')
);
}

Expand Down Expand Up @@ -281,32 +291,36 @@ export async function getPr(
return null;
}

const res = await api.get(
const res = await bitbucketServerHttp.getJson<BbbsRestPr>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,
{ useCache: !refreshCache }
);

const pr: BbsPr = {
displayNumber: `Pull Request #${res.body.id}`,
...utils.prInfo(res.body),
reviewers: res.body.reviewers.map(
(r: { user: { name: string } }) => r.user.name
),
reviewers: res.body.reviewers.map((r) => r.user.name),
isModified: false,
};

pr.version = updatePrVersion(pr.number, pr.version);

if (pr.state === PR_STATE_OPEN) {
const mergeRes = await api.get(
const mergeRes = await bitbucketServerHttp.getJson<{
conflicted: string;
canMerge: string;
}>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge`,
{ useCache: !refreshCache }
);
pr.isConflicted = !!mergeRes.body.conflicted;
pr.canMerge = !!mergeRes.body.canMerge;

const prCommits = (
await api.get(
await bitbucketServerHttp.getJson<{
totalCount: number;
values: { author: { emailAddress: string } }[];
}>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/commits?withCounts=true`,
{ useCache: !refreshCache }
)
Expand Down Expand Up @@ -474,7 +488,7 @@ export async function deleteBranch(
// getBranchPr
const pr = await getBranchPr(branchName);
if (pr) {
const { body } = await api.post<{ version: number }>(
const { body } = await bitbucketServerHttp.postJson<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${pr.number}/decline?version=${pr.version}`
);

Expand Down Expand Up @@ -507,9 +521,12 @@ async function getStatus(
const branchCommit = await config.storage.getBranchCommit(branchName);

return (
await api.get(`./rest/build-status/1.0/commits/stats/${branchCommit}`, {
useCache,
})
await bitbucketServerHttp.getJson<utils.BitbucketCommitStatus>(
`./rest/build-status/1.0/commits/stats/${branchCommit}`,
{
useCache,
}
)
).body;
}

Expand Down Expand Up @@ -633,7 +650,10 @@ export async function setBranchStatus({
break;
}

await api.post(`./rest/build-status/1.0/commits/${branchCommit}`, { body });
await bitbucketServerHttp.postJson(
`./rest/build-status/1.0/commits/${branchCommit}`,
{ body }
);

// update status cache
await getStatus(branchName, false);
Expand Down Expand Up @@ -711,7 +731,7 @@ export async function addReviewers(

const reviewersSet = new Set([...pr.reviewers, ...reviewers]);

await api.put(
await bitbucketServerHttp.putJson(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,
{
body: {
Expand Down Expand Up @@ -765,7 +785,7 @@ async function getComments(prNo: number): Promise<Comment[]> {

async function addComment(prNo: number, text: string): Promise<void> {
// POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments
await api.post(
await bitbucketServerHttp.postJson(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments`,
{
body: { text },
Expand All @@ -779,7 +799,7 @@ async function getCommentVersion(
): Promise<number> {
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
const { version } = (
await api.get(
await bitbucketServerHttp.getJson<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`
)
).body;
Expand All @@ -795,7 +815,7 @@ async function editComment(
const version = await getCommentVersion(prNo, commentId);

// PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
await api.put(
await bitbucketServerHttp.putJson(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`,
{
body: { text, version },
Expand All @@ -807,7 +827,7 @@ async function deleteComment(prNo: number, commentId: number): Promise<void> {
const version = await getCommentVersion(prNo, commentId);

// DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
await api.delete(
await bitbucketServerHttp.deleteJson(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}?version=${version}`
);
}
Expand Down Expand Up @@ -916,13 +936,13 @@ export async function createPr({
if (config.bbUseDefaultReviewers) {
logger.debug(`fetching default reviewers`);
const { id } = (
await api.get<{ id: number }>(
await bitbucketServerHttp.getJson<{ id: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`
)
).body;

const defReviewers = (
await api.get<{ name: string }[]>(
await bitbucketServerHttp.getJson<{ name: string }[]>(
`./rest/default-reviewers/1.0/projects/${config.projectKey}/repos/${
config.repositorySlug
}/reviewers?sourceRefId=refs/heads/${escapeHash(
Expand All @@ -947,9 +967,9 @@ export async function createPr({
},
reviewers,
};
let prInfoRes: GotResponse<BbbsRestPr>;
let prInfoRes: HttpResponse<BbbsRestPr>;
try {
prInfoRes = await api.post<BbbsRestPr>(
prInfoRes = await bitbucketServerHttp.postJson<BbbsRestPr>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,
{ body }
);
Expand Down Expand Up @@ -1000,7 +1020,7 @@ export async function updatePr(
throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });
}

const { body } = await api.put<{ version: number }>(
const { body } = await bitbucketServerHttp.putJson<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,
{
body: {
Expand Down Expand Up @@ -1037,7 +1057,7 @@ export async function mergePr(
if (!pr) {
throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });
}
const { body } = await api.post<{ version: number }>(
const { body } = await bitbucketServerHttp.postJson<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}`
);
updatePrVersion(prNo, body.version);
Expand Down
35 changes: 32 additions & 3 deletions lib/platform/bitbucket-server/utils.ts
Expand Up @@ -5,9 +5,12 @@ import {
PR_STATE_MERGED,
PR_STATE_OPEN,
} from '../../constants/pull-requests';
import { api } from './bb-got-wrapper';
import { HttpResponse } from '../../util/http';
import { BitbucketServerHttp } from '../../util/http/bitbucket-server';
import { BbbsRestPr, BbsPr } from './types';

const bitbucketServerHttp = new BitbucketServerHttp();

// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp250
const prStateMapping: any = {
MERGED: PR_STATE_MERGED,
Expand Down Expand Up @@ -38,6 +41,29 @@ const addMaxLength = (inputUrl: string, limit = 100): string => {
return maxedUrl;
};

async function callApi<T>(
apiUrl: string,
method: string,
options?: any
): Promise<HttpResponse<T>> {
/* istanbul ignore next */
switch (method.toLowerCase()) {
case 'post':
return bitbucketServerHttp.postJson<T>(apiUrl, options);
case 'put':
return bitbucketServerHttp.putJson<T>(apiUrl, options);
case 'patch':
return bitbucketServerHttp.patchJson<T>(apiUrl, options);
case 'head':
return bitbucketServerHttp.headJson<T>(apiUrl, options);
case 'delete':
return bitbucketServerHttp.deleteJson<T>(apiUrl, options);
case 'get':
default:
return bitbucketServerHttp.getJson<T>(apiUrl, options);
}
}

export async function accumulateValues<T = any>(
reqUrl: string,
method = 'get',
Expand All @@ -46,11 +72,14 @@ export async function accumulateValues<T = any>(
): Promise<T[]> {
let accumulator: T[] = [];
let nextUrl = addMaxLength(reqUrl, limit);
const lowerCaseMethod = method.toLocaleLowerCase();

while (typeof nextUrl !== 'undefined') {
// TODO: fix typing
const { body } = await (api as any)[lowerCaseMethod](nextUrl, options);
const { body } = await callApi<{
values: T[];
isLastPage: boolean;
nextPageStart: string;
}>(nextUrl, method, options);
accumulator = [...accumulator, ...body.values];
if (body.isLastPage !== false) {
break;
Expand Down
30 changes: 30 additions & 0 deletions lib/util/http/bitbucket-server.ts
@@ -0,0 +1,30 @@
import URL from 'url';
import { PLATFORM_TYPE_BITBUCKET_SERVER } from '../../constants/platforms';
import { Http, HttpOptions, HttpResponse, InternalHttpOptions } from '.';

let baseUrl: string;
export const setBaseUrl = (url: string): void => {
baseUrl = url;
};

export class BitbucketServerHttp extends Http {
constructor(options?: HttpOptions) {
super(PLATFORM_TYPE_BITBUCKET_SERVER, options);
}

protected async request<T>(
path: string,
options?: InternalHttpOptions
): Promise<HttpResponse<T> | null> {
const url = URL.resolve(baseUrl, path);
const opts = {
baseUrl,
...options,
};
opts.headers = {
...opts.headers,
'X-Atlassian-Token': 'no-check',
};
return super.request<T>(url, opts);
}
}

0 comments on commit b4b6618

Please sign in to comment.