mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 06:56:24 +00:00
feat(github): update pr baseBranch (#22663)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
This commit is contained in:
parent
086b9a7527
commit
4665f1d602
6 changed files with 66 additions and 1 deletions
|
@ -2829,6 +2829,22 @@ describe('modules/platform/github/index', () => {
|
||||||
|
|
||||||
await expect(github.updatePr(pr)).toResolve();
|
await expect(github.updatePr(pr)).toResolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should update target branch', async () => {
|
||||||
|
const pr: UpdatePrConfig = {
|
||||||
|
number: 1234,
|
||||||
|
prTitle: 'The New Title',
|
||||||
|
prBody: 'Hello world again',
|
||||||
|
state: 'closed',
|
||||||
|
targetBranch: 'new_base',
|
||||||
|
};
|
||||||
|
const scope = httpMock.scope(githubApiHost);
|
||||||
|
initRepoMock(scope, 'some/repo');
|
||||||
|
await github.initRepo({ repository: 'some/repo' });
|
||||||
|
scope.patch('/repos/some/repo/pulls/1234').reply(200, pr);
|
||||||
|
|
||||||
|
await expect(github.updatePr(pr)).toResolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('mergePr(prNo)', () => {
|
describe('mergePr(prNo)', () => {
|
||||||
|
|
|
@ -1602,6 +1602,7 @@ export async function updatePr({
|
||||||
prTitle: title,
|
prTitle: title,
|
||||||
prBody: rawBody,
|
prBody: rawBody,
|
||||||
state,
|
state,
|
||||||
|
targetBranch,
|
||||||
}: UpdatePrConfig): Promise<void> {
|
}: UpdatePrConfig): Promise<void> {
|
||||||
logger.debug(`updatePr(${prNo}, ${title}, body)`);
|
logger.debug(`updatePr(${prNo}, ${title}, body)`);
|
||||||
const body = sanitize(rawBody);
|
const body = sanitize(rawBody);
|
||||||
|
@ -1609,6 +1610,9 @@ export async function updatePr({
|
||||||
if (body) {
|
if (body) {
|
||||||
patchBody.body = body;
|
patchBody.body = body;
|
||||||
}
|
}
|
||||||
|
if (targetBranch) {
|
||||||
|
patchBody.base = targetBranch;
|
||||||
|
}
|
||||||
if (state) {
|
if (state) {
|
||||||
patchBody.state = state;
|
patchBody.state = state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ export interface UpdatePrConfig {
|
||||||
prTitle: string;
|
prTitle: string;
|
||||||
prBody?: string;
|
prBody?: string;
|
||||||
state?: 'open' | 'closed';
|
state?: 'open' | 'closed';
|
||||||
|
targetBranch?: string;
|
||||||
}
|
}
|
||||||
export interface EnsureIssueConfig {
|
export interface EnsureIssueConfig {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
@ -65,6 +65,7 @@ describe('workers/repository/update/pr/index', () => {
|
||||||
title: prTitle,
|
title: prTitle,
|
||||||
bodyStruct,
|
bodyStruct,
|
||||||
state: 'open',
|
state: 'open',
|
||||||
|
targetBranch: 'base',
|
||||||
};
|
};
|
||||||
|
|
||||||
const config: BranchConfig = {
|
const config: BranchConfig = {
|
||||||
|
@ -304,6 +305,32 @@ describe('workers/repository/update/pr/index', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('updates PR target branch if base branch changed in config', async () => {
|
||||||
|
platform.getBranchPr.mockResolvedValueOnce(pr);
|
||||||
|
|
||||||
|
const res = await ensurePr({ ...config, baseBranch: 'new_base' }); // user changed base branch in config
|
||||||
|
|
||||||
|
expect(platform.updatePr).toHaveBeenCalled();
|
||||||
|
expect(platform.createPr).not.toHaveBeenCalled();
|
||||||
|
expect(prCache.setPrCache).toHaveBeenCalled();
|
||||||
|
expect(logger.logger.info).toHaveBeenCalledWith(
|
||||||
|
{ pr: pr.number, prTitle },
|
||||||
|
`PR updated`
|
||||||
|
);
|
||||||
|
expect(logger.logger.debug).toHaveBeenCalledWith(
|
||||||
|
{
|
||||||
|
branchName: 'renovate-branch',
|
||||||
|
oldBaseBranch: 'base',
|
||||||
|
newBaseBranch: 'new_base',
|
||||||
|
},
|
||||||
|
'PR base branch has changed'
|
||||||
|
);
|
||||||
|
expect(res).toEqual({
|
||||||
|
type: 'with-pr',
|
||||||
|
pr: { ...pr, targetBranch: 'new_base' }, // updated target branch of pr
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('ignores reviewable content ', async () => {
|
it('ignores reviewable content ', async () => {
|
||||||
// See: https://reviewable.io/
|
// See: https://reviewable.io/
|
||||||
|
|
||||||
|
@ -892,6 +919,7 @@ describe('workers/repository/update/pr/index', () => {
|
||||||
title: prTitle,
|
title: prTitle,
|
||||||
bodyStruct,
|
bodyStruct,
|
||||||
state: 'open',
|
state: 'open',
|
||||||
|
targetBranch: 'base',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(logger.logger.debug).toHaveBeenCalledWith(
|
expect(logger.logger.debug).toHaveBeenCalledWith(
|
||||||
|
|
|
@ -342,6 +342,7 @@ export async function ensurePr(
|
||||||
const newPrTitle = stripEmojis(prTitle);
|
const newPrTitle = stripEmojis(prTitle);
|
||||||
const newPrBodyHash = hashBody(prBody);
|
const newPrBodyHash = hashBody(prBody);
|
||||||
if (
|
if (
|
||||||
|
existingPr?.targetBranch === config.baseBranch &&
|
||||||
existingPrTitle === newPrTitle &&
|
existingPrTitle === newPrTitle &&
|
||||||
existingPrBodyHash === newPrBodyHash
|
existingPrBodyHash === newPrBodyHash
|
||||||
) {
|
) {
|
||||||
|
@ -353,6 +354,16 @@ export async function ensurePr(
|
||||||
return { type: 'with-pr', pr: existingPr };
|
return { type: 'with-pr', pr: existingPr };
|
||||||
}
|
}
|
||||||
// PR must need updating
|
// PR must need updating
|
||||||
|
if (existingPr?.targetBranch !== config.baseBranch) {
|
||||||
|
logger.debug(
|
||||||
|
{
|
||||||
|
branchName,
|
||||||
|
oldBaseBranch: existingPr?.targetBranch,
|
||||||
|
newBaseBranch: config.baseBranch,
|
||||||
|
},
|
||||||
|
'PR base branch has changed'
|
||||||
|
);
|
||||||
|
}
|
||||||
if (existingPrTitle !== newPrTitle) {
|
if (existingPrTitle !== newPrTitle) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
{
|
{
|
||||||
|
@ -370,6 +381,7 @@ export async function ensurePr(
|
||||||
'PR body changed'
|
'PR body changed'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GlobalConfig.get('dryRun')) {
|
if (GlobalConfig.get('dryRun')) {
|
||||||
logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);
|
logger.info(`DRY-RUN: Would update PR #${existingPr.number}`);
|
||||||
return { type: 'with-pr', pr: existingPr };
|
return { type: 'with-pr', pr: existingPr };
|
||||||
|
@ -379,6 +391,7 @@ export async function ensurePr(
|
||||||
prTitle,
|
prTitle,
|
||||||
prBody,
|
prBody,
|
||||||
platformOptions: getPlatformPrOptions(config),
|
platformOptions: getPlatformPrOptions(config),
|
||||||
|
targetBranch: config.baseBranch,
|
||||||
});
|
});
|
||||||
logger.info({ pr: existingPr.number, prTitle }, `PR updated`);
|
logger.info({ pr: existingPr.number, prTitle }, `PR updated`);
|
||||||
setPrCache(branchName, prBodyFingerprint, true);
|
setPrCache(branchName, prBodyFingerprint, true);
|
||||||
|
@ -389,6 +402,7 @@ export async function ensurePr(
|
||||||
...existingPr,
|
...existingPr,
|
||||||
bodyStruct: getPrBodyStruct(prBody),
|
bodyStruct: getPrBodyStruct(prBody),
|
||||||
title: prTitle,
|
title: prTitle,
|
||||||
|
targetBranch: config.baseBranch,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -412,7 +426,7 @@ export async function ensurePr(
|
||||||
}
|
}
|
||||||
pr = await platform.createPr({
|
pr = await platform.createPr({
|
||||||
sourceBranch: branchName,
|
sourceBranch: branchName,
|
||||||
targetBranch: config.baseBranch ?? '',
|
targetBranch: config.baseBranch,
|
||||||
prTitle,
|
prTitle,
|
||||||
prBody,
|
prBody,
|
||||||
labels: prepareLabels(config),
|
labels: prepareLabels(config),
|
||||||
|
|
|
@ -24,6 +24,7 @@ export interface FilteredBranchUpgradeConfig {
|
||||||
export interface PrBodyFingerprintConfig {
|
export interface PrBodyFingerprintConfig {
|
||||||
// BranchConfig - filtered
|
// BranchConfig - filtered
|
||||||
automerge?: boolean;
|
automerge?: boolean;
|
||||||
|
baseBranch?: string;
|
||||||
automergeSchedule?: string[];
|
automergeSchedule?: string[];
|
||||||
hasReleaseNotes?: boolean;
|
hasReleaseNotes?: boolean;
|
||||||
isPin?: boolean;
|
isPin?: boolean;
|
||||||
|
@ -63,6 +64,7 @@ export function generatePrBodyFingerprintConfig(
|
||||||
return {
|
return {
|
||||||
automerge: config.automerge,
|
automerge: config.automerge,
|
||||||
automergeSchedule: config.automergeSchedule,
|
automergeSchedule: config.automergeSchedule,
|
||||||
|
baseBranch: config.baseBranch,
|
||||||
filteredUpgrades,
|
filteredUpgrades,
|
||||||
hasReleaseNotes: config.hasReleaseNotes,
|
hasReleaseNotes: config.hasReleaseNotes,
|
||||||
isPin: config.isPin,
|
isPin: config.isPin,
|
||||||
|
|
Loading…
Reference in a new issue