Skip to content

Commit

Permalink
feat(gitlab): use forked_from_project for Merge Requests target project
Browse files Browse the repository at this point in the history
Appian specific patch to always use the upstream (forked_from_project) when
dealing with Merge Requests or Issues.

This ensures that Renovate follows the standard development workflow where
branches are created against the "dev" fork and then Merge Requests
are opened against the forked (or "prod") fork.

In addition, we want the Dependency Dashboard created against the "prod"
fork, so any calls to the Issues API goes to the "prod" fork.
  • Loading branch information
valdisrigdon authored and rohithrrao committed May 10, 2024
1 parent 376a2a5 commit 572ed21
Show file tree
Hide file tree
Showing 8 changed files with 660 additions and 648 deletions.
1,217 changes: 609 additions & 608 deletions .github/workflows/build.yml

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/github",
{
Expand All @@ -14,7 +13,6 @@
]
}
],
"@semantic-release/npm",
[
"@semantic-release/exec",
{
Expand Down Expand Up @@ -91,8 +89,7 @@
},
"tagFormat": "${version}",
"branches": [
{
"name": "main"
}
{ "name": "main" },
{ "name": "gitlab-forked-from-project" }
]
}
2 changes: 2 additions & 0 deletions lib/modules/platform/gitlab/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ exports[`modules/platform/gitlab/index initRepo should fall back respecting when
"defaultBranch": "master",
"ignorePrAuthor": undefined,
"mergeMethod": "merge",
"mergeRequestRepository": "some%2Frepo%2Fproject",
"repository": "some%2Frepo%2Fproject",
"url": "http://oauth2:123test@mycompany.com/gitlab/some/repo/project.git",
},
Expand All @@ -247,6 +248,7 @@ exports[`modules/platform/gitlab/index initRepo should use ssh_url_to_repo if gi
"defaultBranch": "master",
"ignorePrAuthor": undefined,
"mergeMethod": "merge",
"mergeRequestRepository": "some%2Frepo%2Fproject",
"repository": "some%2Frepo%2Fproject",
"url": "ssh://git@gitlab.com/some%2Frepo%2Fproject.git",
},
Expand Down
66 changes: 38 additions & 28 deletions lib/modules/platform/gitlab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ let config: {
cloneSubmodules: boolean | undefined;
ignorePrAuthor: boolean | undefined;
squash: boolean;
mergeRequestRepository: string;
} = {} as any;

const defaults = {
Expand Down Expand Up @@ -323,7 +324,6 @@ export async function initRepo({
);
throw new Error(REPOSITORY_ARCHIVED);
}

if (res.body.mirror && includeMirrors !== true) {
logger.debug(
'Repository is a mirror - throwing error to abort renovation',
Expand Down Expand Up @@ -359,6 +359,8 @@ export async function initRepo({
}
logger.debug(`${repository} default branch = ${config.defaultBranch}`);
delete config.prList;
config.mergeRequestRepository =
res.body.forked_from_project?.id ?? config.repository;
logger.debug('Enabling Git FS');
const url = getRepoUrl(repository, gitUrl, res);
await git.initRepo({
Expand Down Expand Up @@ -555,7 +557,7 @@ async function fetchPrList(): Promise<Pr[]> {
searchParams.scope = 'created_by_me';
}
const query = getQueryString(searchParams);
const urlString = `projects/${config.repository}/merge_requests?${query}`;
const urlString = `projects/${config.mergeRequestRepository}/merge_requests?${query}`;
try {
const res = await gitlabApi.getJson<
{
Expand Down Expand Up @@ -593,7 +595,7 @@ export async function getPrList(): Promise<Pr[]> {

async function ignoreApprovals(pr: number): Promise<void> {
try {
const url = `projects/${config.repository}/merge_requests/${pr}/approval_rules`;
const url = `projects/${config.mergeRequestRepository}/merge_requests/${pr}/approval_rules`;
const { body: rules } = await gitlabApi.getJson<
{
name: string;
Expand Down Expand Up @@ -684,7 +686,7 @@ async function tryPrAutomerge(
pipeline: {
status: string;
};
}>(`projects/${config.repository}/merge_requests/${pr}`, {
}>(`projects/${config.mergeRequestRepository}/merge_requests/${pr}`, {
memCache: false,
});
// detailed_merge_status is available with Gitlab >=15.6.0
Expand Down Expand Up @@ -713,7 +715,7 @@ async function tryPrAutomerge(
for (let attempt = 1; attempt <= retryTimes; attempt += 1) {
try {
await gitlabApi.putJson(
`projects/${config.repository}/merge_requests/${pr}/merge`,
`projects/${config.mergeRequestRepository}/merge_requests/${pr}/merge`,
{
body: {
should_remove_source_branch: true,
Expand All @@ -739,7 +741,7 @@ async function tryPrAutomerge(
async function approvePr(pr: number): Promise<void> {
try {
await gitlabApi.postJson(
`projects/${config.repository}/merge_requests/${pr}/approve`,
`projects/${config.mergeRequestRepository}/merge_requests/${pr}/approve`,
);
} catch (err) {
logger.warn({ err }, 'GitLab: Error approving merge request');
Expand All @@ -761,6 +763,9 @@ export async function createPr({
}
const description = sanitize(rawDescription);
logger.debug(`Creating Merge Request: ${title}`);
// the creation is always against the repository with the branch
// but if the target_project_id is forked_from_project, then the Merge
// Request will end up in that repository
const res = await gitlabApi.postJson<Pr & { iid: number }>(
`projects/${config.repository}/merge_requests`,
{
Expand All @@ -772,6 +777,7 @@ export async function createPr({
description,
labels: (labels ?? []).join(','),
squash: config.squash,
target_project_id: config.mergeRequestRepository,
},
},
);
Expand All @@ -794,7 +800,7 @@ export async function createPr({

export async function getPr(iid: number): Promise<GitlabPr> {
logger.debug(`getPr(${iid})`);
const mr = await getMR(config.repository, iid);
const mr = await getMR(config.mergeRequestRepository, iid);

// Harmonize fields with GitHub
const pr: GitlabPr = {
Expand Down Expand Up @@ -852,7 +858,7 @@ export async function updatePr({
}

await gitlabApi.putJson(
`projects/${config.repository}/merge_requests/${iid}`,
`projects/${config.mergeRequestRepository}/merge_requests/${iid}`,
{ body },
);

Expand All @@ -873,7 +879,7 @@ export async function reattemptPlatformAutomerge({
export async function mergePr({ id }: MergePRConfig): Promise<boolean> {
try {
await gitlabApi.putJson(
`projects/${config.repository}/merge_requests/${id}/merge`,
`projects/${config.mergeRequestRepository}/merge_requests/${id}/merge`,
{
body: {
should_remove_source_branch: true,
Expand Down Expand Up @@ -1010,11 +1016,12 @@ export async function setBranchStatus({
state: renovateState,
url: targetUrl,
}: BranchStatusConfig): Promise<void> {
const branchSourceProject = config.repository;
// First, get the branch commit SHA
const branchSha = git.getBranchCommit(branchName);
// Now, check the statuses for that commit
// TODO: types (#22198)
const url = `projects/${config.repository}/statuses/${branchSha!}`;
const url = `projects/${branchSourceProject}/statuses/${branchSha!}`;
let state = 'success';
if (renovateState === 'yellow') {
state = 'pending';
Expand Down Expand Up @@ -1076,7 +1083,7 @@ export async function getIssueList(): Promise<GitlabIssue[]> {
});
const res = await gitlabApi.getJson<
{ iid: number; title: string; labels: string[] }[]
>(`projects/${config.repository}/issues?${query}`, {
>(`projects/${config.mergeRequestRepository}/issues?${query}`, {
memCache: false,
paginate: true,
});
Expand All @@ -1101,7 +1108,7 @@ export async function getIssue(
try {
const issueBody = (
await gitlabApi.getJson<{ description: string }>(
`projects/${config.repository}/issues/${number}`,
`projects/${config.mergeRequestRepository}/issues/${number}`,
{ memCache: useCache },
)
).body.description;
Expand Down Expand Up @@ -1148,13 +1155,13 @@ export async function ensureIssue({
if (issue) {
const existingDescription = (
await gitlabApi.getJson<{ description: string }>(
`projects/${config.repository}/issues/${issue.iid}`,
`projects/${config.mergeRequestRepository}/issues/${issue.iid}`,
)
).body.description;
if (issue.title !== title || existingDescription !== description) {
logger.debug('Updating issue');
await gitlabApi.putJson(
`projects/${config.repository}/issues/${issue.iid}`,
`projects/${config.mergeRequestRepository}/issues/${issue.iid}`,
{
body: {
title,
Expand All @@ -1167,14 +1174,17 @@ export async function ensureIssue({
return 'updated';
}
} else {
await gitlabApi.postJson(`projects/${config.repository}/issues`, {
body: {
title,
description,
labels: (labels ?? []).join(','),
confidential: confidential ?? false,
await gitlabApi.postJson(
`projects/${config.mergeRequestRepository}/issues`,
{
body: {
title,
description,
labels: (labels ?? []).join(','),
confidential: confidential ?? false,
},
},
});
);
logger.info('Issue created');
// delete issueList so that it will be refetched as necessary
delete config.issueList;
Expand All @@ -1197,7 +1207,7 @@ export async function ensureIssueClosing(title: string): Promise<void> {
if (issue.title === title) {
logger.debug({ issue }, 'Closing issue');
await gitlabApi.putJson(
`projects/${config.repository}/issues/${issue.iid}`,
`projects/${config.mergeRequestRepository}/issues/${issue.iid}`,
{
body: { state_event: 'close' },
},
Expand Down Expand Up @@ -1282,7 +1292,7 @@ export async function addReviewers(
newReviewerIDs = [...new Set(newReviewerIDs)];

try {
await updateMR(config.repository, iid, {
await updateMR(config.mergeRequestRepository, iid, {
reviewer_ids: [...existingReviewerIDs, ...newReviewerIDs],
});
} catch (err) {
Expand All @@ -1301,7 +1311,7 @@ export async function deleteLabel(
.filter((l: string) => l !== label)
.join(',');
await gitlabApi.putJson(
`projects/${config.repository}/merge_requests/${issueNo}`,
`projects/${config.mergeRequestRepository}/merge_requests/${issueNo}`,
{
body: { labels },
},
Expand All @@ -1314,7 +1324,7 @@ export async function deleteLabel(
async function getComments(issueNo: number): Promise<GitlabComment[]> {
// GET projects/:owner/:repo/merge_requests/:number/notes
logger.debug(`Getting comments for #${issueNo}`);
const url = `projects/${config.repository}/merge_requests/${issueNo}/notes`;
const url = `projects/${config.mergeRequestRepository}/merge_requests/${issueNo}/notes`;
const comments = (
await gitlabApi.getJson<GitlabComment[]>(url, { paginate: true })
).body;
Expand All @@ -1325,7 +1335,7 @@ async function getComments(issueNo: number): Promise<GitlabComment[]> {
async function addComment(issueNo: number, body: string): Promise<void> {
// POST projects/:owner/:repo/merge_requests/:number/notes
await gitlabApi.postJson(
`projects/${config.repository}/merge_requests/${issueNo}/notes`,
`projects/${config.mergeRequestRepository}/merge_requests/${issueNo}/notes`,
{
body: { body },
},
Expand All @@ -1339,7 +1349,7 @@ async function editComment(
): Promise<void> {
// PUT projects/:owner/:repo/merge_requests/:number/notes/:id
await gitlabApi.putJson(
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`,
`projects/${config.mergeRequestRepository}/merge_requests/${issueNo}/notes/${commentId}`,
{
body: { body },
},
Expand All @@ -1352,7 +1362,7 @@ async function deleteComment(
): Promise<void> {
// DELETE projects/:owner/:repo/merge_requests/:number/notes/:id
await gitlabApi.deleteJson(
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`,
`projects/${config.mergeRequestRepository}/merge_requests/${issueNo}/notes/${commentId}`,
);
}

Expand Down
4 changes: 3 additions & 1 deletion lib/modules/platform/gitlab/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ export interface RepoResponse {
empty_repo: boolean;
ssh_url_to_repo: string;
http_url_to_repo: string;
forked_from_project: boolean;
repository_access_level: 'disabled' | 'private' | 'enabled';
merge_requests_access_level: 'disabled' | 'private' | 'enabled';
merge_method: MergeMethod;
path_with_namespace: string;
squash_option?: 'never' | 'always' | 'default_on' | 'default_off';
forked_from_project?: {
id: string;
};
}

// See https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/types/user_status_type.rb
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"repository": {
"type": "git",
"url": "https://github.com/renovatebot/renovate.git"
"url": "https://github.com/appian/renovate.git"
},
"keywords": [
"automated",
Expand Down
2 changes: 1 addition & 1 deletion tools/docker/bake.hcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
variable "OWNER" {
default = "renovatebot"
default = "appian"
}
variable "FILE" {
default = "renovate"
Expand Down
8 changes: 4 additions & 4 deletions tools/publish-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ void (async () => {

if (meta?.['push-slim']?.['containerimage.digest']) {
sign(
`ghcr.io/renovatebot/renovate@${meta['push-slim']['containerimage.digest']}`,
`ghcr.io/appian/renovate@${meta['push-slim']['containerimage.digest']}`,
opts,
);
sign(
`renovate/renovate@${meta['push-slim']['containerimage.digest']}`,
`appian/renovate@${meta['push-slim']['containerimage.digest']}`,
opts,
);
} else {
Expand All @@ -39,11 +39,11 @@ void (async () => {

if (meta?.['push-full']?.['containerimage.digest']) {
sign(
`ghcr.io/renovatebot/renovate@${meta['push-full']['containerimage.digest']}`,
`ghcr.io/appian/renovate@${meta['push-full']['containerimage.digest']}`,
opts,
);
sign(
`renovate/renovate@${meta['push-full']['containerimage.digest']}`,
`appian/renovate@${meta['push-full']['containerimage.digest']}`,
opts,
);
} else {
Expand Down

0 comments on commit 572ed21

Please sign in to comment.