diff --git a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap index 5a3567ff52045f9d71fd439ffb2e31044c17d48c..3d6b461911c5e15b1a3341a2cf6e9f82e40abef9 100644 --- a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap +++ b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap @@ -912,7 +912,7 @@ Array [ ] `; -exports[`platform/bitbucket/index getJsonFile() ignores branchOrTag 1`] = ` +exports[`platform/bitbucket/index getJsonFile() returns file content 1`] = ` Array [ Object { "headers": Object { @@ -938,7 +938,7 @@ Array [ ] `; -exports[`platform/bitbucket/index getJsonFile() returns file content 1`] = ` +exports[`platform/bitbucket/index getJsonFile() returns file content from branch or tag 1`] = ` Array [ Object { "headers": Object { @@ -959,7 +959,44 @@ Array [ "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", }, "method": "GET", - "url": "https://api.bitbucket.org/2.0/repositories/some/repo/src/HEAD/file.json", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/src/dev/file.json", + }, +] +`; + +exports[`platform/bitbucket/index getJsonFile() returns file content from branch with a slash in its name 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/feat/123-test", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate, br", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/src/1234567890/file.json", }, ] `; diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts index 05cc557e711eeb516c77aea701005f396fb787c1..2027b0fdcc6be1a4df46977f6c35aa1f0ec5035b 100644 --- a/lib/platform/bitbucket/index.spec.ts +++ b/lib/platform/bitbucket/index.spec.ts @@ -966,17 +966,35 @@ describe('platform/bitbucket/index', () => { expect(httpMock.getTrace()).toMatchSnapshot(); }); - it('ignores branchOrTag', async () => { + it('returns file content from branch or tag', async () => { const data = { foo: 'bar' }; const scope = await initRepoMock(); scope - .get('/2.0/repositories/some/repo/src/HEAD/file.json') + .get('/2.0/repositories/some/repo/src/dev/file.json') .reply(200, JSON.stringify(data)); const res = await bitbucket.getJsonFile('file.json', 'some/repo', 'dev'); expect(res).toEqual(data); expect(httpMock.getTrace()).toMatchSnapshot(); }); + it('returns file content from branch with a slash in its name', async () => { + const data = { foo: 'bar' }; + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/feat/123-test') + .reply(200, JSON.stringify({ target: { hash: '1234567890' } })); + scope + .get('/2.0/repositories/some/repo/src/1234567890/file.json') + .reply(200, JSON.stringify(data)); + const res = await bitbucket.getJsonFile( + 'file.json', + 'some/repo', + 'feat/123-test' + ); + expect(res).toEqual(data); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('throws on malformed JSON', async () => { const scope = await initRepoMock(); scope diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts index 31b36a17ff5d94390e8a0d9f11f0a5bc5b276871..1b9803120d8c79b4a6c1e4da6e4c9dbc8b37861d 100644 --- a/lib/platform/bitbucket/index.ts +++ b/lib/platform/bitbucket/index.ts @@ -48,6 +48,8 @@ let config: utils.Config = {} as any; const defaults = { endpoint: BITBUCKET_PROD_ENDPOINT }; +const pathSeparator = '/'; + let renovateUserUuid: string; export async function initPlatform({ @@ -116,7 +118,17 @@ export async function getRawFile( // See: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/src/%7Bcommit%7D/%7Bpath%7D const repo = repoName ?? config.repository; const path = fileName; - const url = `/2.0/repositories/${repo}/src/HEAD/${path}`; + + let finalBranchOrTag = branchOrTag; + if (branchOrTag?.includes(pathSeparator)) { + // Branch name contans slash, so we have to replace branch name with SHA1 of the head commit; otherwise the API will not work. + finalBranchOrTag = await getBranchCommit(branchOrTag); + } + + const url = + `/2.0/repositories/${repo}/src/` + + (finalBranchOrTag || `HEAD`) + + `/${path}`; const res = await bitbucketHttp.get(url); return res.body; }