diff --git a/lib/modules/platform/azure/__snapshots__/index.spec.ts.snap b/lib/modules/platform/azure/__snapshots__/index.spec.ts.snap index 3be9ce9411245c..2ca73528d8f0b9 100644 --- a/lib/modules/platform/azure/__snapshots__/index.spec.ts.snap +++ b/lib/modules/platform/azure/__snapshots__/index.spec.ts.snap @@ -30,10 +30,10 @@ exports[`modules/platform/azure/index createPr() should create and return a PR o } `; -exports[`modules/platform/azure/index createPr() should create and return a PR object with auto-complete set 1`] = ` +exports[`modules/platform/azure/index createPr() when usePlatformAutomerge is set should create and return a PR object with auto-complete set 1`] = ` { "autoCompleteSetBy": { - "id": 123, + "id": "123", }, "bodyStruct": { "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", @@ -45,7 +45,7 @@ exports[`modules/platform/azure/index createPr() should create and return a PR o }, "createdAt": undefined, "createdBy": { - "id": 123, + "id": "123", }, "number": 456, "pullRequestId": 456, diff --git a/lib/modules/platform/azure/index.spec.ts b/lib/modules/platform/azure/index.spec.ts index 29493cd2421217..440bc9d1df7d82 100644 --- a/lib/modules/platform/azure/index.spec.ts +++ b/lib/modules/platform/azure/index.spec.ts @@ -730,47 +730,127 @@ describe('modules/platform/azure/index', () => { expect(pr).toMatchSnapshot(); }); - it('should create and return a PR object with auto-complete set', async () => { - await initRepo({ repository: 'some/repo' }); - const prResult = { - pullRequestId: 456, - title: 'The Title', - createdBy: { - id: 123, - }, - }; - const prUpdateResult = { - ...prResult, - autoCompleteSetBy: { - id: prResult.createdBy.id, - }, - completionOptions: { - squashMerge: true, - deleteSourceBranch: true, - mergeCommitMessage: 'The Title', - }, - }; - const updateFn = jest - .fn(() => prUpdateResult) - .mockName('updatePullRequest'); - azureApi.gitApi.mockImplementationOnce( - () => - ({ - createPullRequest: jest.fn(() => prResult), - createPullRequestLabel: jest.fn(() => ({})), + describe('when usePlatformAutomerge is set', () => { + it('should create and return a PR object with auto-complete set', async () => { + await initRepo({ repository: 'some/repo' }); + const prResult = { + pullRequestId: 456, + title: 'The Title', + createdBy: { + id: '123', + }, + }; + const prUpdateResult = { + ...prResult, + autoCompleteSetBy: { + id: prResult.createdBy.id, + }, + completionOptions: { + squashMerge: true, + deleteSourceBranch: true, + mergeCommitMessage: 'The Title', + }, + }; + const updateFn = jest.fn().mockResolvedValue(prUpdateResult); + azureApi.gitApi.mockResolvedValueOnce( + partial({ + createPullRequest: jest.fn().mockResolvedValue(prResult), + createPullRequestLabel: jest.fn().mockResolvedValue({}), updatePullRequest: updateFn, - } as any) - ); - const pr = await azure.createPr({ - sourceBranch: 'some-branch', - targetBranch: 'dev', - prTitle: 'The Title', - prBody: 'Hello world', - labels: ['deps', 'renovate'], - platformOptions: { usePlatformAutomerge: true }, + }) + ); + const pr = await azure.createPr({ + sourceBranch: 'some-branch', + targetBranch: 'dev', + prTitle: 'The Title', + prBody: 'Hello world', + labels: ['deps', 'renovate'], + platformOptions: { usePlatformAutomerge: true }, + }); + expect(updateFn).toHaveBeenCalled(); + expect(pr).toMatchSnapshot(); + }); + + it('should only call getMergeMethod once per run', async () => { + await initRepo({ repository: 'some/repo' }); + const prResult = [ + { + pullRequestId: 456, + title: 'The Title', + createdBy: { + id: '123', + }, + }, + { + pullRequestId: 457, + title: 'The Second Title', + createdBy: { + id: '123', + }, + }, + ]; + const prUpdateResults = [ + { + ...prResult[0], + autoCompleteSetBy: { + id: prResult[0].createdBy.id, + }, + completionOptions: { + squashMerge: true, + deleteSourceBranch: true, + mergeCommitMessage: 'The Title', + }, + }, + { + ...prResult[1], + autoCompleteSetBy: { + id: prResult[1].createdBy.id, + }, + completionOptions: { + squashMerge: true, + deleteSourceBranch: true, + mergeCommitMessage: 'The Second Title', + }, + }, + ]; + const updateFn = jest.fn(() => + Promise.resolve(prUpdateResults.shift()!) + ); + + azureHelper.getMergeMethod.mockResolvedValueOnce( + GitPullRequestMergeStrategy.Squash + ); + + azureApi.gitApi.mockResolvedValue( + partial({ + createPullRequest: jest.fn(() => + Promise.resolve(prResult.shift()!) + ), + createPullRequestLabel: jest.fn().mockResolvedValue({}), + updatePullRequest: updateFn, + }) + ); + await azure.createPr({ + sourceBranch: 'some-branch', + targetBranch: 'dev', + prTitle: 'The Title', + prBody: 'Hello world', + labels: ['deps', 'renovate'], + platformOptions: { usePlatformAutomerge: true }, + }); + + await azure.createPr({ + sourceBranch: 'some-other-branch', + targetBranch: 'dev', + prTitle: 'The Second Title', + prBody: 'Hello world', + labels: ['deps', 'renovate'], + platformOptions: { usePlatformAutomerge: true }, + }); + + expect(updateFn).toHaveBeenCalledTimes(2); + expect(azureHelper.getMergeMethod).toHaveBeenCalledTimes(1); }); - expect(updateFn).toHaveBeenCalled(); - expect(pr).toMatchSnapshot(); }); it('should create and return an approved PR object', async () => { diff --git a/lib/modules/platform/azure/index.ts b/lib/modules/platform/azure/index.ts index a3e0f0d6dbdf19..37091f45a63692 100644 --- a/lib/modules/platform/azure/index.ts +++ b/lib/modules/platform/azure/index.ts @@ -48,7 +48,6 @@ import { getBranchNameWithoutRefsheadsPrefix, getGitStatusContextCombinedName, getGitStatusContextFromCombinedName, - getProjectAndRepo, getRenovatePRFormat, getRepoByName, getStorageExtraCloneOpts, @@ -57,7 +56,6 @@ import { interface Config { repoForceRebase: boolean; - defaultMergeMethod: GitPullRequestMergeStrategy; mergeMethods: Record; owner: string; repoId: string; @@ -202,14 +200,6 @@ export async function initRepo({ const defaultBranch = repo.defaultBranch.replace('refs/heads/', ''); config.defaultBranch = defaultBranch; logger.debug(`${repository} default branch = ${defaultBranch}`); - const names = getProjectAndRepo(repository); - config.defaultMergeMethod = await azureHelper.getMergeMethod( - // TODO #7154 - repo.id!, - names.project, - null, - defaultBranch - ); config.mergeMethods = {}; config.repoForceRebase = false; @@ -427,6 +417,20 @@ export async function getBranchStatus( return 'green'; } +async function getMergeStrategy( + targetRefName: string +): Promise { + return ( + config.mergeMethods[targetRefName] ?? + (config.mergeMethods[targetRefName] = await azureHelper.getMergeMethod( + config.repoId, + config.project, + targetRefName, + config.defaultBranch + )) + ); +} + export async function createPr({ sourceBranch, targetBranch, @@ -457,6 +461,7 @@ export async function createPr({ config.repoId ); if (platformOptions?.usePlatformAutomerge) { + const mergeStrategy = await getMergeStrategy(pr.targetRefName!); pr = await azureApiGit.updatePullRequest( { autoCompleteSetBy: { @@ -464,7 +469,7 @@ export async function createPr({ id: pr.createdBy!.id, }, completionOptions: { - mergeStrategy: config.defaultMergeMethod, + mergeStrategy, deleteSourceBranch: true, mergeCommitMessage: title, }, @@ -700,21 +705,12 @@ export async function mergePr({ let pr = await azureApiGit.getPullRequestById(pullRequestId, config.project); - // TODO #7154 - const mergeMethod = - config.mergeMethods[pr.targetRefName!] ?? - (config.mergeMethods[pr.targetRefName!] = await azureHelper.getMergeMethod( - config.repoId, - config.project, - pr.targetRefName, - config.defaultBranch - )); - + const mergeStrategy = await getMergeStrategy(pr.targetRefName!); const objToUpdate: GitPullRequest = { status: PullRequestStatus.Completed, lastMergeSourceCommit: pr.lastMergeSourceCommit, completionOptions: { - mergeStrategy: mergeMethod, + mergeStrategy, deleteSourceBranch: true, mergeCommitMessage: pr.title, }, @@ -727,8 +723,8 @@ export async function mergePr({ // TODO: types (#7154) // eslint-disable-next-line @typescript-eslint/restrict-template-expressions pr.lastMergeSourceCommit?.commitId - } using mergeStrategy ${mergeMethod} (${ - GitPullRequestMergeStrategy[mergeMethod] + } using mergeStrategy ${mergeStrategy} (${ + GitPullRequestMergeStrategy[mergeStrategy] })` );