Skip to content

Add support for placeholder merge requests #239

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,18 @@ Set to `true` (default) to enable using the [GitHub preview API for importing is

### usePlaceholderIssuesForMissingIssues

NOTE: This setting requires `usePlaceholderIssuesForMissingMergeRequests` to be set to `false` (default).

If this is set to `true` (default) then the migration process will automatically create empty dummy issues for every 'missing' GitLab issue (if you deleted a GitLab issue for example). Those issues will be closed on Github and they ensure that the issue ids stay the same on both GitLab and Github.

### usePlaceholderIssuesForMissingMergeRequests

NOTE: GitLab has distinct numbers for issues and merge requests whereas GitHub treats pull requests as issues.
Only use this setting if your GitLab repository does not have issues or you do not intend on migrating them.
This setting therefore requires `usePlaceholderIssuesForMissingIssues` to be set to `false`.

If this is set to `true` then the migration process will automatically create empty dummy issues for every 'missing' GitLab merge request (if you deleted a GitLab merge request for example). Those issues will be closed on Github and they ensure that the issue ids stay the same on both GitLab and Github.

#### usePlaceholderMilestonesForMissingMilestones

If this is set to `true` (default) then the migration process will automatically create empty dummy milestones for every 'missing' GitLab milestone (if you deleted a GitLab milestone for example). Those milestones will be closed on Github and they ensure that the milestone ids stay the same on both GitLab and Github.
Expand Down
1 change: 1 addition & 0 deletions sample_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default {
useIssueImportAPI: true,
usePlaceholderMilestonesForMissingMilestones: true,
usePlaceholderIssuesForMissingIssues: true,
usePlaceholderIssuesForMissingMergeRequests: false,
useReplacementIssuesForCreationFails: true,
useIssuesForAllMergeRequests: false,
filterByLabel: undefined,
Expand Down
9 changes: 9 additions & 0 deletions src/githubHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,15 @@ export class GithubHelper {
async createPullRequestAndComments(
mergeRequest: GitLabMergeRequest
): Promise<void> {
// Use the issue creation for placeholder issues
if (mergeRequest.isPlaceholder) {
let issue = mergeRequest as unknown;
await this.createIssueAndComments(issue as GitLabIssue);
console.log(`Created placeholder issue for placeholder merge request #${mergeRequest.iid}`);

return;
}

let pullRequestData = await this.createPullRequest(mergeRequest);

// createPullRequest() returns an issue number if a PR could not be created and
Expand Down
50 changes: 46 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SimpleLabel,
SimpleMilestone,
} from './githubHelper';
import { GitlabHelper, GitLabIssue, GitLabMilestone } from './gitlabHelper';
import { GitlabHelper, GitLabIssue, GitLabMergeRequest, GitLabMilestone } from './gitlabHelper';
import settings from '../settings';

import { Octokit as GitHubApi } from '@octokit/rest';
Expand Down Expand Up @@ -156,6 +156,23 @@ function createPlaceholderIssue(expectedIdx: number): Partial<GitLabIssue> {
};
}

/**
* Creates dummy data for a placeholder issue
*
* @param expectedIdx Number of the GitLab issue
* @returns Data for the issue
*/
function createPlaceholderMergeRequest(expectedIdx: number): Partial<GitLabMergeRequest> {
return {
iid: expectedIdx,
title: `[PLACEHOLDER] - for merge request #${expectedIdx}`,
description:
'This is to ensure that merge request numbers in GitLab and GitHub are the same',
state: 'closed',
isPlaceholder: true,
};
}

// ----------------------------------------------------------------------------

/**
Expand Down Expand Up @@ -549,6 +566,25 @@ async function transferMergeRequests() {
// Issues are sometimes created from Gitlab merge requests. Avoid creating duplicates.
let githubIssues = await githubHelper.getAllGithubIssues();

if (settings.usePlaceholderIssuesForMissingMergeRequests) {
for (let i = 0; i < mergeRequests.length; i++) {
// GitLab issue internal Id (iid)
let expectedIdx = i + 1;

// is there a gap in the GitLab merge requests?
// Create placeholder issues so that new GitHub issues will have the same
// issue number as in GitLab. If a placeholder is used it is because there
// was a gap in GitLab merge requests -- likely caused by a deleted GitLab merge request.
if (mergeRequests[i].iid !== expectedIdx) {
mergeRequests.splice(i, 0, createPlaceholderMergeRequest(expectedIdx) as GitLabMergeRequest); // HACK: remove type coercion
counters.nrOfPlaceholderIssues++;
console.log(
`Added placeholder issue for GitLab merge request #${expectedIdx}.`
);
}
}
}

console.log(
'Transferring ' + mergeRequests.length.toString() + ' merge requests'
);
Expand All @@ -568,11 +604,17 @@ async function transferMergeRequests() {
let githubIssue = githubIssues.find(
// allow for issues titled "Original Issue Name - [merged|closed]"
i => {
// regex needs escaping in case merge request title contains special characters
const regex = new RegExp(escapeRegExp(mr.title.trim()) + ' - \\[(merged|closed)\\]');
return regex.test(i.title.trim()) && i.body.includes(mr.web_url);
if (!mr.isPlaceholder) {
// regex needs escaping in case merge request title contains special characters
const regex = new RegExp(escapeRegExp(mr.title.trim()) + ' - \\[(merged|closed)\\]');
return regex.test(i.title.trim()) && i.body.includes(mr.web_url);
}
else {
return i.title.trim() === mr.title.trim();
}
}
);

if (!githubRequest && !githubIssue) {
if (settings.skipMergeRequestStates.includes(mr.state)) {
console.log(
Expand Down
1 change: 1 addition & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default interface Settings {
useIssueImportAPI: boolean;
usePlaceholderMilestonesForMissingMilestones: boolean;
usePlaceholderIssuesForMissingIssues: boolean;
usePlaceholderIssuesForMissingMergeRequests: boolean;
useReplacementIssuesForCreationFails: boolean;
useIssuesForAllMergeRequests: boolean;
filterByLabel?: string;
Expand Down