diff --git a/lib/platform/azure/index.spec.ts b/lib/platform/azure/index.spec.ts index 309699988013cb85bb223378cb6c1689fd7b4e34..76ba7745d9c2f9788ee20bee6a6fac8fb351016d 100644 --- a/lib/platform/azure/index.spec.ts +++ b/lib/platform/azure/index.spec.ts @@ -1080,7 +1080,10 @@ describe(getName(), () => { .fn() .mockReturnValue(GitPullRequestMergeStrategy.Squash); - const res = await azure.mergePr(pullRequestIdMock, branchNameMock); + const res = await azure.mergePr({ + branchName: branchNameMock, + id: pullRequestIdMock, + }); expect(updatePullRequestMock).toHaveBeenCalledWith( { @@ -1118,7 +1121,10 @@ describe(getName(), () => { .fn() .mockReturnValue(GitPullRequestMergeStrategy.Squash); - const res = await azure.mergePr(pullRequestIdMock, branchNameMock); + const res = await azure.mergePr({ + branchName: branchNameMock, + id: pullRequestIdMock, + }); expect(res).toBe(false); }); @@ -1138,8 +1144,14 @@ describe(getName(), () => { .fn() .mockReturnValue(GitPullRequestMergeStrategy.Squash); - await azure.mergePr(1234, 'test-branch-1'); - await azure.mergePr(5678, 'test-branch-2'); + await azure.mergePr({ + branchName: 'test-branch-1', + id: 1234, + }); + await azure.mergePr({ + branchName: 'test-branch-2', + id: 5678, + }); expect(azureHelper.getMergeMethod).toHaveBeenCalledTimes(1); }); @@ -1167,7 +1179,10 @@ describe(getName(), () => { .fn() .mockReturnValue(GitPullRequestMergeStrategy.Squash); - const res = await azure.mergePr(pullRequestIdMock, branchNameMock); + const res = await azure.mergePr({ + branchName: branchNameMock, + id: pullRequestIdMock, + }); expect(getPullRequestByIdMock).toHaveBeenCalledTimes(2); expect(res).toBe(true); @@ -1197,7 +1212,10 @@ describe(getName(), () => { .fn() .mockReturnValue(GitPullRequestMergeStrategy.Squash); - const res = await azure.mergePr(pullRequestIdMock, branchNameMock); + const res = await azure.mergePr({ + branchName: branchNameMock, + id: pullRequestIdMock, + }); expect(getPullRequestByIdMock).toHaveBeenCalledTimes( expectedNumRetries + 1 diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts index 6abee9274b30c640f0a2bef8a0833d096bd3bf27..27efa594855b81a7da9944541e26518cd1e14513 100644 --- a/lib/platform/azure/index.ts +++ b/lib/platform/azure/index.ts @@ -24,6 +24,7 @@ import type { EnsureIssueResult, FindPRConfig, Issue, + MergePRConfig, PlatformParams, PlatformResult, Pr, @@ -608,10 +609,10 @@ export async function setBranchStatus({ logger.trace(`Created commit status of ${state} on branch ${branchName}`); } -export async function mergePr( - pullRequestId: number, - branchName: string -): Promise<boolean> { +export async function mergePr({ + branchName, + id: pullRequestId, +}: MergePRConfig): Promise<boolean> { logger.debug(`mergePr(${pullRequestId}, ${branchName})`); const azureApiGit = await azureApi.gitApi(); diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts index cb747f2e034ac33a466376e314c04d29760c2d7d..2d39843c40ed034cdf874f9f6f49be1d9e4d71c0 100644 --- a/lib/platform/bitbucket-server/index.spec.ts +++ b/lib/platform/bitbucket-server/index.spec.ts @@ -1598,13 +1598,21 @@ describe(getName(), () => { ) .reply(200); - expect(await bitbucket.mergePr(5, 'branch')).toBe(true); + expect( + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + }) + ).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws not-found 1', async () => { await initRepo(); - const res = bitbucket.mergePr(null as any, 'branch'); + const res = bitbucket.mergePr({ + branchName: 'branch', + id: null as any, + }); await expect(res).rejects.toThrow(REPOSITORY_NOT_FOUND); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -1617,9 +1625,12 @@ describe(getName(), () => { ) .reply(404); - await expect(bitbucket.mergePr(4, 'branch')).rejects.toThrow( - REPOSITORY_NOT_FOUND - ); + await expect( + bitbucket.mergePr({ + branchName: 'branch', + id: 4, + }) + ).rejects.toThrow(REPOSITORY_NOT_FOUND); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -1639,9 +1650,12 @@ describe(getName(), () => { ) .reply(404); - await expect(bitbucket.mergePr(5, 'branch')).rejects.toThrow( - REPOSITORY_NOT_FOUND - ); + await expect( + bitbucket.mergePr({ + branchName: 'branch', + id: 5, + }) + ).rejects.toThrow(REPOSITORY_NOT_FOUND); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -1661,7 +1675,12 @@ describe(getName(), () => { ) .reply(409); - expect(await bitbucket.mergePr(5, 'branch')).toBeFalsy(); + expect( + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + }) + ).toBeFalsy(); expect(httpMock.getTrace()).toMatchSnapshot(); }); @@ -1681,7 +1700,12 @@ describe(getName(), () => { ) .reply(405); - await expect(bitbucket.mergePr(5, 'branch')).resolves.toBe(false); + await expect( + bitbucket.mergePr({ + branchName: 'branch', + id: 5, + }) + ).resolves.toBe(false); expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts index c79ba4b4e18c3c6059d9793a251d413482467b63..44bc93d61a6a4f32b52702c8de711391f6192e49 100644 --- a/lib/platform/bitbucket-server/index.ts +++ b/lib/platform/bitbucket-server/index.ts @@ -31,6 +31,7 @@ import type { EnsureIssueResult, FindPRConfig, Issue, + MergePRConfig, PlatformParams, PlatformResult, Pr, @@ -962,10 +963,10 @@ export async function updatePr({ } // https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp261 -export async function mergePr( - prNo: number, - branchName: string -): Promise<boolean> { +export async function mergePr({ + branchName, + id: prNo, +}: MergePRConfig): Promise<boolean> { logger.debug(`mergePr(${prNo}, ${branchName})`); // Used for "automerge" feature try { diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts index 1959e1f1fe328181cc309168bad22ec3823c4cf9..cad5cd8e664161534fadf850457a76b141c14599 100644 --- a/lib/platform/bitbucket/index.spec.ts +++ b/lib/platform/bitbucket/index.spec.ts @@ -815,40 +815,63 @@ describe(getName(), () => { it('posts Merge with optional merge strategy', async () => { const scope = await initRepoMock(); scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); - await bitbucket.mergePr(5, 'branch'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('posts Merge with auto', async () => { const scope = await initRepoMock(); scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); - await bitbucket.mergePr(5, 'branch', 'auto'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + strategy: 'auto', + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('posts Merge with merge-commit', async () => { const scope = await initRepoMock(); scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); - await bitbucket.mergePr(5, 'branch', 'merge-commit'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + strategy: 'merge-commit', + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('posts Merge with squash', async () => { const scope = await initRepoMock(); scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); - await bitbucket.mergePr(5, 'branch', 'squash'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + strategy: 'squash', + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('does not post Merge with rebase', async () => { - await bitbucket.mergePr(5, 'branch', 'rebase'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + strategy: 'rebase', + }); expect(httpMock.getTrace()).toEqual([]); }); it('posts Merge with fast-forward', async () => { const scope = await initRepoMock(); scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); - await bitbucket.mergePr(5, 'branch', 'fast-forward'); + await bitbucket.mergePr({ + branchName: 'branch', + id: 5, + strategy: 'fast-forward', + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts index 5699528b541d318fece09114a93edd32817c79cf..1639870df0d299b169c2bebb4523fdfc344cbd3c 100644 --- a/lib/platform/bitbucket/index.ts +++ b/lib/platform/bitbucket/index.ts @@ -1,7 +1,6 @@ import URL from 'url'; import is from '@sindresorhus/is'; import parseDiff from 'parse-diff'; -import type { MergeStrategy } from '../../config/types'; import { REPOSITORY_NOT_FOUND } from '../../constants/error-messages'; import { PLATFORM_TYPE_BITBUCKET } from '../../constants/platforms'; import { logger } from '../../logger'; @@ -19,6 +18,7 @@ import type { EnsureIssueResult, FindPRConfig, Issue, + MergePRConfig, PlatformParams, PlatformResult, Pr, @@ -747,11 +747,11 @@ export async function updatePr({ } } -export async function mergePr( - prNo: number, - branchName: string, - mergeStrategy: MergeStrategy -): Promise<boolean> { +export async function mergePr({ + branchName, + id: prNo, + strategy: mergeStrategy, +}: MergePRConfig): Promise<boolean> { logger.debug(`mergePr(${prNo}, ${branchName}, ${mergeStrategy})`); // Bitbucket Cloud does not support a rebase-alike; https://jira.atlassian.com/browse/BCLOUD-16610 diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts index 6a0ade67ca10f40b3d994ef1b05bf4ea60ac58cf..058aed3ef89b9999e701a59faf8497de583c9221 100644 --- a/lib/platform/gitea/index.spec.ts +++ b/lib/platform/gitea/index.spec.ts @@ -899,7 +899,12 @@ describe(getName(), () => { it('should return true when merging succeeds', async () => { await initFakeRepo(); - expect(await gitea.mergePr(1, 'some-branch')).toEqual(true); + expect( + await gitea.mergePr({ + branchName: 'some-branch', + id: 1, + }) + ).toEqual(true); expect(helper.mergePR).toHaveBeenCalledTimes(1); expect(helper.mergePR).toHaveBeenCalledWith( mockRepo.full_name, @@ -912,7 +917,12 @@ describe(getName(), () => { helper.mergePR.mockRejectedValueOnce(new Error()); await initFakeRepo(); - expect(await gitea.mergePr(1, 'some-branch')).toEqual(false); + expect( + await gitea.mergePr({ + branchName: 'some-branch', + id: 1, + }) + ).toEqual(false); }); }); diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts index ab669e05a6246dedc6ca536bdda9f224127e66a9..c7d831e6b007a71cf091153916c6c69d4b4def71 100644 --- a/lib/platform/gitea/index.ts +++ b/lib/platform/gitea/index.ts @@ -25,6 +25,7 @@ import type { EnsureIssueConfig, FindPRConfig, Issue, + MergePRConfig, Platform, PlatformParams, PlatformResult, @@ -563,12 +564,12 @@ const platform: Platform = { }); }, - async mergePr(number: number, branchName: string): Promise<boolean> { + async mergePr({ id }: MergePRConfig): Promise<boolean> { try { - await helper.mergePR(config.repository, number, config.mergeMethod); + await helper.mergePR(config.repository, id, config.mergeMethod); return true; } catch (err) { - logger.warn({ err, number }, 'Merging of PR failed'); + logger.warn({ err, id }, 'Merging of PR failed'); return false; } }, diff --git a/lib/platform/github/index.spec.ts b/lib/platform/github/index.spec.ts index f0e2e51b73cb25664ce4ea9c559f6a5a1a83c5b7..ab4fdc442e3903a106f43283cddf2e14f273a681 100644 --- a/lib/platform/github/index.spec.ts +++ b/lib/platform/github/index.spec.ts @@ -2040,7 +2040,12 @@ describe(getName(), () => { ref: 'someref', }, }; - expect(await github.mergePr(pr.number, '')).toBe(true); + expect( + await github.mergePr({ + branchName: '', + id: pr.number, + }) + ).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should handle merge error', async () => { @@ -2056,7 +2061,12 @@ describe(getName(), () => { ref: 'someref', }, }; - expect(await github.mergePr(pr.number, '')).toBe(false); + expect( + await github.mergePr({ + branchName: '', + id: pr.number, + }) + ).toBe(false); expect(httpMock.getTrace()).toMatchSnapshot(); }); }); @@ -2104,7 +2114,12 @@ describe(getName(), () => { ref: 'someref', }, }; - expect(await github.mergePr(pr.number, '')).toBe(true); + expect( + await github.mergePr({ + branchName: '', + id: pr.number, + }) + ).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should try squash after rebase', async () => { @@ -2120,7 +2135,10 @@ describe(getName(), () => { ref: 'someref', }, }; - await github.mergePr(pr.number, ''); + await github.mergePr({ + branchName: '', + id: pr.number, + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should try merge after squash', async () => { @@ -2140,7 +2158,12 @@ describe(getName(), () => { ref: 'someref', }, }; - expect(await github.mergePr(pr.number, '')).toBe(true); + expect( + await github.mergePr({ + branchName: '', + id: pr.number, + }) + ).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should give up', async () => { @@ -2162,7 +2185,12 @@ describe(getName(), () => { ref: 'someref', }, }; - expect(await github.mergePr(pr.number, '')).toBe(false); + expect( + await github.mergePr({ + branchName: '', + id: pr.number, + }) + ).toBe(false); expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts index 469e7b5493b64f4435c7abf95de52b50b5b7a048..20a5942b5df4dec9db75f8342e0e56215f25111f 100644 --- a/lib/platform/github/index.ts +++ b/lib/platform/github/index.ts @@ -34,6 +34,7 @@ import type { EnsureIssueResult, FindPRConfig, Issue, + MergePRConfig, PlatformResult, Pr, RepoParams, @@ -1477,10 +1478,10 @@ export async function updatePr({ } } -export async function mergePr( - prNo: number, - branchName: string -): Promise<boolean> { +export async function mergePr({ + branchName, + id: prNo, +}: MergePRConfig): Promise<boolean> { logger.debug(`mergePr(${prNo}, ${branchName})`); // istanbul ignore if if (config.prReviewsRequired) { diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts index b293bcf761db405dceedb3b0402e357ea89cd492..63c849fe3148aa50a68c57e220ca5c48e3c41203 100644 --- a/lib/platform/gitlab/index.spec.ts +++ b/lib/platform/gitlab/index.spec.ts @@ -1796,7 +1796,9 @@ describe(getName(), () => { .scope(gitlabApiHost) .put('/api/v4/projects/undefined/merge_requests/1/merge') .reply(200); - await gitlab.mergePr(1, undefined); + await gitlab.mergePr({ + id: 1, + }); expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index d8c1f89d929f865ec6d82a216aceb4d0ecd0cdc7..175c0a81b12db0c644adc6dba4819c89471b82c2 100644 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -31,6 +31,7 @@ import type { EnsureIssueConfig, FindPRConfig, Issue, + MergePRConfig, PlatformParams, PlatformPrOptions, PlatformResult, @@ -606,10 +607,10 @@ export async function updatePr({ await tryPrAutomerge(iid, platformOptions); } -export async function mergePr(iid: number): Promise<boolean> { +export async function mergePr({ id }: MergePRConfig): Promise<boolean> { try { await gitlabApi.putJson( - `projects/${config.repository}/merge_requests/${iid}/merge`, + `projects/${config.repository}/merge_requests/${id}/merge`, { body: { should_remove_source_branch: true, diff --git a/lib/platform/types.ts b/lib/platform/types.ts index 3a9cc08babf5bc220603244f1ca5154fe7b80589..020247e95576e8059837304c09b370d5d3df99e3 100644 --- a/lib/platform/types.ts +++ b/lib/platform/types.ts @@ -117,6 +117,11 @@ export interface FindPRConfig { state?: PrState.Open | PrState.Closed | PrState.NotOpen | PrState.All; refreshCache?: boolean; } +export interface MergePRConfig { + branchName?: string; + id: number; + strategy?: MergeStrategy; +} export interface EnsureCommentConfig { number: number; topic: string; @@ -154,11 +159,7 @@ export interface Platform { ): Promise<EnsureIssueResult | null>; massageMarkdown(prBody: string): string; updatePr(prConfig: UpdatePrConfig): Promise<void>; - mergePr( - number: number, - branchName: string, - mergeStrategy?: MergeStrategy - ): Promise<boolean>; + mergePr(config: MergePRConfig): Promise<boolean>; addReviewers(number: number, reviewers: string[]): Promise<void>; addAssignees(number: number, assignees: string[]): Promise<void>; createPr(prConfig: CreatePRConfig): Promise<Pr>; diff --git a/lib/workers/pr/automerge.ts b/lib/workers/pr/automerge.ts index b1c5af8fc132955afe248d1ed24c46cab62cac52..cb4f84764a0bb488eaff4601049d00e05a3919bc 100644 --- a/lib/workers/pr/automerge.ts +++ b/lib/workers/pr/automerge.ts @@ -109,7 +109,11 @@ export async function checkAutoMerge( }; } logger.debug(`Automerging #${pr.number} with strategy ${automergeStrategy}`); - const res = await platform.mergePr(pr.number, branchName, automergeStrategy); + const res = await platform.mergePr({ + branchName, + id: pr.number, + strategy: automergeStrategy, + }); if (res) { logger.info({ pr: pr.number, prTitle: pr.title }, 'PR automerged'); let branchRemoved = false;