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(reconfigure/pr): find reconfigure pr separately #25954

Merged
merged 27 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d580e54
fix: find reconfigure pr
RahulGautamSingh Nov 24, 2023
cc7779d
Merge branch 'main' into fix-25754
RahulGautamSingh Nov 24, 2023
0da567f
fix formatting
RahulGautamSingh Nov 24, 2023
3e761c0
fix tests
RahulGautamSingh Nov 24, 2023
1016afa
support bitbucket & bitbucket-server
RahulGautamSingh Nov 24, 2023
c949d77
revert change for bitbucket-server
RahulGautamSingh Nov 25, 2023
e97da88
add logic for bitbutcket-server
RahulGautamSingh Nov 27, 2023
4be29f9
Apply Suggestions
RahulGautamSingh Nov 27, 2023
e4453f9
update snap
RahulGautamSingh Nov 30, 2023
a544ad8
update tests
RahulGautamSingh Nov 30, 2023
246b3e2
fix coverage
RahulGautamSingh Nov 30, 2023
78139b4
fix branch coverage
RahulGautamSingh Nov 30, 2023
d11ede5
apply suggestions
RahulGautamSingh Dec 3, 2023
6032954
refactor logs
RahulGautamSingh Dec 3, 2023
0f18e3b
fix tests
RahulGautamSingh Dec 3, 2023
008a9c1
apply changes as per suggestion
RahulGautamSingh Dec 5, 2023
e03a276
fix tests
RahulGautamSingh Dec 5, 2023
cdbc4a6
remove obsolete snap
RahulGautamSingh Dec 5, 2023
7101da5
remove extra open pr filters
RahulGautamSingh Dec 7, 2023
ee0ea50
gitea: remove isReconfigurePr() logic
RahulGautamSingh Dec 7, 2023
976f696
type: captailize Pr -> PR
RahulGautamSingh Dec 14, 2023
84448d4
apply suggestions
RahulGautamSingh Dec 14, 2023
f0eb04b
remove extra log statement
RahulGautamSingh Dec 14, 2023
98fca6b
Apply suggestions from code review
RahulGautamSingh Dec 16, 2023
af0e0f8
Merge branch 'main' into fix-25754
RahulGautamSingh Dec 16, 2023
1dbc888
Apply Suggestions
RahulGautamSingh Dec 27, 2023
a9ff017
inline regex matching
RahulGautamSingh Dec 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions lib/modules/platform/bitbucket-server/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,50 @@ describe('modules/platform/bitbucket-server/index', () => {
}),
).toBeNull();
});

it('finds pr from other authors', async () => {
const scope = await initRepo();
scope
.get(
`${urlPath}/rest/api/1.0/projects/SOME/repos/repo/pull-requests?state=OPEN&direction=outgoing&at=refs/heads/branch&limit=1`,
)
.reply(200, {
isLastPage: true,
values: [prMock(url, 'SOME', 'repo')],
});
expect(
await bitbucket.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
}),
).toMatchObject({
number: 5,
sourceBranch: 'userName1/pullRequest5',
targetBranch: 'master',
title: 'title',
state: 'open',
});
});

it('returns null if no pr found - (includeOtherAuthors)', async () => {
const scope = await initRepo();
scope
.get(
`${urlPath}/rest/api/1.0/projects/SOME/repos/repo/pull-requests?state=OPEN&direction=outgoing&at=refs/heads/branch&limit=1`,
)
.reply(200, {
isLastPage: true,
values: [],
});

const pr = await bitbucket.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
});
expect(pr).toBeNull();
});
});

describe('createPr()', () => {
Expand Down
26 changes: 26 additions & 0 deletions lib/modules/platform/bitbucket-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,34 @@ export async function findPr({
prTitle,
state = 'all',
refreshCache,
includeOtherAuthors,
}: FindPRConfig): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, "${prTitle!}", "${state}")`);

if (includeOtherAuthors) {
// PR might have been created by anyone, so don't use the cached Renovate PR list
const searchParams: Record<string, string> = {
state: 'OPEN',
};
searchParams['direction'] = 'outgoing';
searchParams['at'] = `refs/heads/${branchName}`;

const query = getQueryString(searchParams);
const prs = await utils.accumulateValues(
viceice marked this conversation as resolved.
Show resolved Hide resolved
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests?${query}`,
'get',
{},
1, // only fetch the latest pr
);

if (!prs.length) {
logger.debug(`No PR found for branch ${branchName}`);
return null;
}

return utils.prInfo(prs[0]);
}

const prList = await getPrList(refreshCache);
const pr = prList.find(isRelevantPr(branchName, prTitle, state));
if (pr) {
Expand Down
40 changes: 40 additions & 0 deletions lib/modules/platform/bitbucket/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,46 @@ describe('modules/platform/bitbucket/index', () => {
});
expect(pr?.number).toBe(5);
});

it('finds pr from other authors', async () => {
const scope = await initRepoMock();
scope
.get(
'/2.0/repositories/some/repo/pullrequests?q=source.branch.name="branch"&state=open',
)
.reply(200, { values: [pr] });
expect(
await bitbucket.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
}),
).toMatchObject({
number: 5,
sourceBranch: 'branch',
targetBranch: 'master',
title: 'title',
state: 'open',
});
});

it('returns null if no open pr exists - (includeOtherAuthors)', async () => {
const scope = await initRepoMock();
scope
.get(
'/2.0/repositories/some/repo/pullrequests?q=source.branch.name="branch"&state=open',
)
.reply(200, {
values: [],
});

const pr = await bitbucket.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
});
expect(pr).toBeNull();
});
});

describe('createPr()', () => {
Expand Down
18 changes: 18 additions & 0 deletions lib/modules/platform/bitbucket/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,26 @@ export async function findPr({
branchName,
prTitle,
state = 'all',
includeOtherAuthors,
}: FindPRConfig): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);

if (includeOtherAuthors) {
// PR might have been created by anyone, so don't use the cached Renovate PR list
const prs = (
await bitbucketHttp.getJson<PagedResult<PrResponse>>(
`/2.0/repositories/${config.repository}/pullrequests?q=source.branch.name="${branchName}"&state=open`,
)
).body.values;

if (prs.length === 0) {
logger.debug(`No PR found for branch ${branchName}`);
return null;
}

return utils.prInfo(prs[0]);
}

const prList = await getPrList();
const pr = prList.find(
(p) =>
Expand Down
14 changes: 13 additions & 1 deletion lib/modules/platform/gitea/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { BranchStatus } from '../../../types';
import { parseJson } from '../../../util/common';
import * as git from '../../../util/git';
import { setBaseUrl } from '../../../util/http/gitea';
import { regEx } from '../../../util/regex';
import { sanitize } from '../../../util/sanitize';
import { ensureTrailingSlash } from '../../../util/url';
import { getPrBodyStruct, hashBody } from '../pr-body';
Expand Down Expand Up @@ -70,6 +71,7 @@ interface GiteaRepoConfig {
export const id = 'gitea';

const DRAFT_PREFIX = 'WIP: ';
const reconfigurePrRegex = regEx(/reconfigure$/g);

const defaults = {
hostType: 'gitea',
Expand All @@ -81,6 +83,10 @@ let config: GiteaRepoConfig = {} as any;
let botUserID: number;
let botUserName: string;

function isReconfigurePr(branchName: string): boolean {
return reconfigurePrRegex.test(branchName);
}

RahulGautamSingh marked this conversation as resolved.
Show resolved Hide resolved
function toRenovateIssue(data: Issue): Issue {
return {
number: data.number,
Expand Down Expand Up @@ -109,7 +115,12 @@ function toRenovatePR(data: PR): Pr | null {
}

const createdBy = data.user?.username;
if (createdBy && botUserName && createdBy !== botUserName) {
if (
createdBy &&
botUserName &&
!isReconfigurePr(data.head.label) &&
createdBy !== botUserName
) {
return null;
}

Expand Down Expand Up @@ -493,6 +504,7 @@ const platform: Platform = {
branchName,
prTitle: title,
state = 'all',
includeOtherAuthors,
}: FindPRConfig): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${title!}, ${state})`);
const prList = await platform.getPrList();
Expand Down
45 changes: 45 additions & 0 deletions lib/modules/platform/github/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2428,6 +2428,51 @@ describe('modules/platform/github/index', () => {
res = await github.findPr({ branchName: 'branch-b' });
expect(res).toBeNull();
});

it('finds pr from other authors', async () => {
const scope = httpMock.scope(githubApiHost);
initRepoMock(scope, 'some/repo');
scope
.get('/repos/some/repo/pulls?head=some/repo:branch&state=open')
.reply(200, [
{
number: 1,
head: { ref: 'branch-a', repo: { full_name: 'some/repo' } },
title: 'branch a pr',
state: 'open',
},
]);
await github.initRepo({ repository: 'some/repo' });
expect(
await github.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
}),
).toMatchObject({
number: 1,
sourceBranch: 'branch-a',
sourceRepo: 'some/repo',
state: 'open',
title: 'branch a pr',
updated_at: undefined,
});
});

it('returns null if no pr found - (includeOtherAuthors)', async () => {
const scope = httpMock.scope(githubApiHost);
initRepoMock(scope, 'some/repo');
scope
.get('/repos/some/repo/pulls?head=some/repo:branch&state=open')
.reply(200, []);
await github.initRepo({ repository: 'some/repo' });
const pr = await github.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
});
expect(pr).toBeNull();
});
});

describe('createPr()', () => {
Expand Down
18 changes: 18 additions & 0 deletions lib/modules/platform/github/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -798,8 +798,26 @@ export async function findPr({
branchName,
prTitle,
state = 'all',
includeOtherAuthors,
}: FindPRConfig): Promise<GhPr | null> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);

if (includeOtherAuthors) {
const repo = config.parentRepo ?? config.repository;
// PR might have been created by anyone, so don't use the cached Renovate PR list
const response = await githubApi.getJson<GhRestPr[]>(
`repos/${repo}/pulls?head=${repo}:${branchName}&state=open`,
);

const { body: prList } = response;
if (!prList.length) {
logger.debug(`No PR found for branch ${branchName}`);
return null;
}

return coerceRestPr(prList[0]);
}

const prList = await getPrList();
const pr = prList.find((p) => {
if (p.sourceBranch !== branchName) {
Expand Down
43 changes: 43 additions & 0 deletions lib/modules/platform/gitlab/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,49 @@ describe('modules/platform/gitlab/index', () => {
});
expect(res).toBeDefined();
});

it('finds pr from other authors', async () => {
httpMock
.scope(gitlabApiHost)
.get(
'/api/v4/projects/undefined/merge_requests?source_branch=branch&state=opened',
)
.reply(200, [
{
iid: 1,
source_branch: 'branch',
title: 'branch a pr',
state: 'opened',
},
]);
expect(
await gitlab.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
}),
).toMatchObject({
number: 1,
sourceBranch: 'branch',
state: 'open',
title: 'branch a pr',
});
});

it('returns null if no pr found - (includeOtherAuthors)', async () => {
httpMock
.scope(gitlabApiHost)
.get(
'/api/v4/projects/undefined/merge_requests?source_branch=branch&state=opened',
)
.reply(200, []);
const pr = await gitlab.findPr({
branchName: 'branch',
state: 'open',
includeOtherAuthors: true,
});
expect(pr).toBeNull();
});
});

async function initPlatform(gitlabVersion: string) {
Expand Down
28 changes: 28 additions & 0 deletions lib/modules/platform/gitlab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -863,8 +863,36 @@ export async function findPr({
branchName,
prTitle,
state = 'all',
includeOtherAuthors,
}: FindPRConfig): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${prTitle!}, ${state})`);

if (includeOtherAuthors) {
// PR might have been created by anyone, so don't use the cached Renovate MR list
const response = await gitlabApi.getJson<GitLabMergeRequest[]>(
`projects/${config.repository}/merge_requests?source_branch=${branchName}&state=opened`,
);

const { body: mrList } = response;
if (!mrList.length) {
logger.debug(`No MR found for branch ${branchName}`);
return null;
}

// return the latest merge request
const mr = mrList[0];

// only pass necessary info
const pr: GitlabPr = {
sourceBranch: mr.source_branch,
number: mr.iid,
state: 'open',
title: mr.title,
};

return massagePr(pr);
}

const prList = await getPrList();
return (
prList.find(
Expand Down
1 change: 1 addition & 0 deletions lib/modules/platform/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export interface FindPRConfig {
state?: 'open' | 'closed' | '!open' | 'all';
refreshCache?: boolean;
targetBranch?: string | null;
includeOtherAuthors?: boolean;
}
export interface MergePRConfig {
branchName?: string;
Expand Down