From c44cf412de245d6ccc39b32d4da37c6ac3fcf08b Mon Sep 17 00:00:00 2001 From: David Zemon Date: Tue, 4 Oct 2022 11:14:04 -0500 Subject: [PATCH] fix: [#13560] Pull commit hash for branch names by branch query Using the commits API was unstable and broke for branches with a '/'. Using the branches API works for any branch and is documented in the Atlassian API docs: https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp209 Signed-off-by: David Zemon --- .changeset/great-numbers-reply.md | 5 ++ .../reading/BitbucketServerUrlReader.test.ts | 46 ++++++++++++++++--- .../src/reading/BitbucketServerUrlReader.ts | 42 ++++++++--------- 3 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 .changeset/great-numbers-reply.md diff --git a/.changeset/great-numbers-reply.md b/.changeset/great-numbers-reply.md new file mode 100644 index 0000000000..b72b05debf --- /dev/null +++ b/.changeset/great-numbers-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Fix BitBucket server integration diff --git a/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts b/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts index f308b4d33d..15f1c0d4be 100644 --- a/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts +++ b/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts @@ -83,11 +83,23 @@ describe('BitbucketServerUrlReader', () => { ), ), rest.get( - 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/commits/*', + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/branches', (_, res, ctx) => res( ctx.status(200), - ctx.json({ id: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st' }), + ctx.json({ + size: 2, + values: [ + { + displayId: 'some-branch-that-should-be-ignored', + latestCommit: 'bogus hash', + }, + { + displayId: 'some-branch', + latestCommit: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st', + }, + ], + }), ), ), ); @@ -130,12 +142,22 @@ describe('BitbucketServerUrlReader', () => { ), ), rest.get( - 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/commits/*', + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/branches', (_, res, ctx) => res( ctx.status(200), ctx.json({ - values: [{ id: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st' }], + size: 2, + values: [ + { + displayId: 'some-branch-that-should-be-ignored', + latestCommit: 'bogus hash', + }, + { + displayId: 'some-branch', + latestCommit: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st', + }, + ], }), ), ), @@ -179,11 +201,23 @@ describe('BitbucketServerUrlReader', () => { ), ), rest.get( - 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/commits/*', + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/branches', (_, res, ctx) => res( ctx.status(200), - ctx.json({ id: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st' }), + ctx.json({ + size: 2, + values: [ + { + displayId: 'master-of-none', + latestCommit: 'bogus hash', + }, + { + displayId: 'master', + latestCommit: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st', + }, + ], + }), ), ), ); diff --git a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts index e9a229a1ff..98f95b88cb 100644 --- a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts @@ -188,38 +188,36 @@ export class BitbucketServerUrlReader implements UrlReader { private async getLastCommitShortHash(url: string): Promise { const { name: repoName, owner: project, ref: branch } = parseGitUrl(url); - // Bitbucket Server https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp224 - const commitApiUrl = `${this.integration.config.apiBaseUrl}/projects/${project}/repos/${repoName}/commits/${branch}`; + const branchListUrl = `${ + this.integration.config.apiBaseUrl + }/projects/${project}/repos/${repoName}/branches?filterText=${encodeURIComponent( + branch, + )}`; - const commitResponse = await fetch( - commitApiUrl, + const branchListResponse = await fetch( + branchListUrl, getBitbucketServerRequestOptions(this.integration.config), ); - if (!commitResponse.ok) { - const message = `Failed to retrieve commits from ${commitApiUrl}, ${commitResponse.status} ${commitResponse.statusText}`; - if (commitResponse.status === 404) { + if (!branchListResponse.ok) { + const message = `Failed to retrieve branch list from ${branchListUrl}, ${branchListResponse.status} ${branchListResponse.statusText}`; + if (branchListResponse.status === 404) { throw new NotFoundError(message); } throw new Error(message); } - const commits = await commitResponse.json(); + const branchMatches = await branchListResponse.json(); - // Handles case when a branch is provided in the URL - if (commits && commits.id) { - return commits.id.substring(0, 12); + if (branchMatches && branchMatches.size > 0) { + const exactBranchMatch = branchMatches.values.filter( + (branchDetails: { displayId: string }) => + branchDetails.displayId === branch, + )[0]; + return exactBranchMatch.latestCommit.substring(0, 12); } - // Handles case when no branch is provided in the URL - if ( - commits && - commits.values && - commits.values.length > 0 && - commits.values[0].id - ) { - return commits.values[0].id.substring(0, 12); - } - - throw new Error(`Failed to read response from ${commitApiUrl}`); + throw new Error( + `Failed to find branch "${branch}" in property "displayId" of response to ${branchListUrl}`, + ); } }