Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(azure): use target branch to select platform automerge strategy #22439

6 changes: 3 additions & 3 deletions lib/modules/platform/azure/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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",
viceice marked this conversation as resolved.
Show resolved Hide resolved
},
"bodyStruct": {
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand All @@ -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,
Expand Down
161 changes: 122 additions & 39 deletions lib/modules/platform/azure/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,47 +730,130 @@ 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)
.mockName('updatePullRequest');
JamieMagee marked this conversation as resolved.
Show resolved Hide resolved
azureApi.gitApi.mockResolvedValueOnce(
partial<IGitApi>({
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()!))
.mockName('updatePullRequest');
JamieMagee marked this conversation as resolved.
Show resolved Hide resolved

azureHelper.getMergeMethod.mockResolvedValueOnce(
GitPullRequestMergeStrategy.Squash
);

azureApi.gitApi.mockResolvedValue(
partial<IGitApi>({
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 () => {
Expand Down
44 changes: 20 additions & 24 deletions lib/modules/platform/azure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
getBranchNameWithoutRefsheadsPrefix,
getGitStatusContextCombinedName,
getGitStatusContextFromCombinedName,
getProjectAndRepo,
getRenovatePRFormat,
getRepoByName,
getStorageExtraCloneOpts,
Expand All @@ -57,7 +56,6 @@ import {

interface Config {
repoForceRebase: boolean;
defaultMergeMethod: GitPullRequestMergeStrategy;
mergeMethods: Record<string, GitPullRequestMergeStrategy>;
owner: string;
repoId: string;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -427,6 +417,20 @@ export async function getBranchStatus(
return 'green';
}

async function getMergeStrategy(
targetRefName: string
): Promise<GitPullRequestMergeStrategy> {
return (
config.mergeMethods[targetRefName] ??
(config.mergeMethods[targetRefName] = await azureHelper.getMergeMethod(
config.repoId,
config.project,
targetRefName,
config.defaultBranch
viceice marked this conversation as resolved.
Show resolved Hide resolved
))
);
}

export async function createPr({
sourceBranch,
targetBranch,
Expand Down Expand Up @@ -457,14 +461,15 @@ export async function createPr({
config.repoId
);
if (platformOptions?.usePlatformAutomerge) {
const mergeStrategy = await getMergeStrategy(pr.targetRefName!);
pr = await azureApiGit.updatePullRequest(
{
autoCompleteSetBy: {
// TODO #7154
id: pr.createdBy!.id,
},
completionOptions: {
mergeStrategy: config.defaultMergeMethod,
mergeStrategy,
deleteSourceBranch: true,
mergeCommitMessage: title,
},
Expand Down Expand Up @@ -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,
},
Expand All @@ -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]
})`
);

Expand Down