Skip to content

Commit 9eca5c0

Browse files
authored
Merge pull request #232 from mschoettle/add-issue-information
Add information about assignees, reviewers, and approvers to body
2 parents 5b8750d + 83a7567 commit 9eca5c0

File tree

6 files changed

+109
-24
lines changed

6 files changed

+109
-24
lines changed

README.md

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Leave it null for the first run of the script. Then the script will show you whi
8686

8787
#### gitlab.listArchivedProjects
8888

89-
When listing projects on the first run (projectID = null), include archived ones too. The default is *true*.
89+
When listing projects on the first run (projectID = null), include archived ones too. The default is `true`.
9090

9191
#### gitlab.sessionCookie
9292

@@ -108,25 +108,25 @@ Under which organisation or user will the new project be hosted
108108

109109
#### github.ownerIsOrg
110110

111-
A boolean indicator (default is *false*) to specify that the owner of this repo is an Organisation.
111+
A boolean indicator (default is `false`) to specify that the owner of this repo is an Organisation.
112112

113113
#### github.token
114114

115115
Go to [Settings / Developer settings / Personal access tokens](https://github.com/settings/tokens). Generate a new token with `repo` scope and copy that into the `settings.ts`
116116

117117
#### github.token_owner
118118

119-
Set to the user name of the user whose token is used (see above). This is required to determine whether the user running the migration is also the creator of comments and issues. If this is the case and `useIssueCreationAPI` is true (see below), the extra line specifying who created a comment or issue will not be added.
119+
Set to the user name of the user whose token is used (see above). This is required to determine whether the user running the migration is also the creator of comments and issues. If this is the case and `useIssueCreationAPI` is `true` (see below), the extra line specifying who created a comment or issue will not be added.
120120

121121
#### github.repo
122122

123123
What is the name of the new repo
124124

125125
#### github.recreateRepo
126126

127-
If true (default is false), we will try to delete the destination github repository if present, and (re)create it. The github token must be granted `delete_repo` scope. The newly created repository will be made private by default.
127+
If `true` (default is `false`), we will try to delete the destination github repository if present, and (re)create it. The github token must be granted `delete_repo` scope. The newly created repository will be made private by default.
128128

129-
If you've set `github.recreateRepo` to true and the repo belongs to an Organisation, the `github.ownerIsOrg` flag **must** be set as true.
129+
If you've set `github.recreateRepo` to `true` and the repo belongs to an Organisation, the `github.ownerIsOrg` flag **must** be set as `true`.
130130

131131
This is useful when debugging this tool or a specific migration. You will always be prompted for confirmation.
132132

@@ -160,63 +160,67 @@ When one renames the project while transfering so that the projects don't loose
160160

161161
#### conversion.useLowerCaseLabels
162162

163-
If this is set to true (default) then labels from GitLab will be converted to lowercase in GitHub.
163+
If this is set to `true` (default) then labels from GitLab will be converted to lowercase in GitHub.
164+
165+
#### conversion.addIssueInformation
166+
167+
If this is set to `true` (default) then issues and pull requests will get information about assignees (both), reviewers and approvers (PR only) added to their description.
164168

165169
### transfer
166170

167171
#### transfer.milestones
168172

169-
If this is set to true (default) then the migration process will transfer milestones.
173+
If this is set to `true` (default) then the migration process will transfer milestones.
170174

171175
#### transfer.labels
172176

173-
If this is set to true (default) then the migration process will transfer labels.
177+
If this is set to `true` (default) then the migration process will transfer labels.
174178

175179
#### transfer.issues
176180

177-
If this is set to true (default) then the migration process will transfer issues.
181+
If this is set to `true` (default) then the migration process will transfer issues.
178182

179183
#### transfer.mergeRequests
180184

181-
If this is set to true (default) then the migration process will transfer merge requests.
185+
If this is set to `true` (default) then the migration process will transfer merge requests.
182186

183187
#### transfer.releases
184188

185-
If this is set to true (default) then the migration process will transfer releases.
189+
If this is set to `true` (default) then the migration process will transfer releases.
186190
Note that github api for releases is limited and hence this will only transfer the title and description of the releases
187191
and add them to github in chronological order, but it would not preserve the original release dates, nor transfer artefacts or assets.
188192

189193
### dryRun
190194

191-
As default it is set to false. Doesn't fire the requests to github api and only does the work on the gitlab side to test for wonky cases before using up api-calls
195+
As default it is set to `false`. Doesn't fire the requests to github api and only does the work on the gitlab side to test for wonky cases before using up api-calls
192196

193197
### exportUsers
194198

195-
If this is set to true (default is false) then a file called "users.txt" wil be created containing all
199+
If this is set to `true` (default is `false`) then a file called "users.txt" wil be created containing all
196200
usernames that contributed to the repository. You can use this with dryRun when you need to map users
197201
for the migration, but you do not know all the source usernames.
198202

199203
### useIssueImportAPI
200204

201-
Set to true (default) to enable using the [GitHub preview API for importing issues](https://gist.github.com/jonmagic/5282384165e0f86ef105). This allows setting the date for issues and comments instead of inserting an additional line in the body.
205+
Set to `true` (default) to enable using the [GitHub preview API for importing issues](https://gist.github.com/jonmagic/5282384165e0f86ef105). This allows setting the date for issues and comments instead of inserting an additional line in the body.
202206

203207
### usePlaceholderIssuesForMissingIssues
204208

205-
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.
209+
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.
206210

207211
#### usePlaceholderMilestonesForMissingMilestones
208212

209-
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.
213+
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.
210214

211215
#### useReplacementIssuesForCreationFails
212216

213-
If this is set to true (default) then the migration process will automatically create so called "replacement-issues" for every issue where the migration fails. This replacement issue will be exactly the same, but the original description will be lost. In the future, the description of the replacement issue will also contain a link to the original issue on GitLab. This way, users who still have access to the GitLab repository can still view its content. However, this is still an open task. (TODO)
217+
If this is set to `true` (default) then the migration process will automatically create so called "replacement-issues" for every issue where the migration fails. This replacement issue will be exactly the same, but the original description will be lost. In the future, the description of the replacement issue will also contain a link to the original issue on GitLab. This way, users who still have access to the GitLab repository can still view its content. However, this is still an open task. (TODO)
214218

215219
It would of course be better to find the cause for migration fails, so that no replacement issues would be needed. Finding the cause together with a retry-mechanism would be optimal, and will maybe come in the future - currently the replacement-issue-mechanism helps to keep things in order.
216220

217221
### useIssuesForAllMergeRequests
218222

219-
If this is set to true (default is false) then all merge requests will be migrated as GitHub issues (rather than pull requests). This can be
223+
If this is set to `true` (default is `false`) then all merge requests will be migrated as GitHub issues (rather than pull requests). This can be
220224
used to sidestep the problem where pull requests are rejected by GitHub if the feature branch no longer exists or has been merged.
221225

222226
### filterByLabel
@@ -238,7 +242,7 @@ Suggested values:
238242

239243
### mergeRequests
240244

241-
Object consisting of `logfile` and `log`. If `log` is set to true, then the merge requests are logged in the specified file and not migrated. Conversely, if `log` is set to false, then the merge requests are migrated to GitHub and not logged. If the source or target branches linked to the merge request have been deleted, the merge request cannot be migrated to a pull request; instead, an issue with a custom "gitlab merge request" tag is created with the full comment history of the merge request.
245+
Object consisting of `logfile` and `log`. If `log` is set to `true`, then the merge requests are logged in the specified file and not migrated. Conversely, if `log` is set to `false`, then the merge requests are migrated to GitHub and not logged. If the source or target branches linked to the merge request have been deleted, the merge request cannot be migrated to a pull request; instead, an issue with a custom "gitlab merge request" tag is created with the full comment history of the merge request.
242246

243247
### usermap
244248

sample_settings.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default {
2222
accessKeyId: '{{accessKeyId}}',
2323
secretAccessKey: '{{secretAccessKey}}',
2424
bucket: 'my-gitlab-bucket',
25-
region: null,
25+
region: 'us-west-1',
2626
},
2727
usermap: {
2828
'username.gitlab.1': 'username.github.1',
@@ -34,6 +34,7 @@ export default {
3434
},
3535
conversion: {
3636
useLowerCaseLabels: true,
37+
addIssueInformation: true,
3738
},
3839
transfer: {
3940
description: true,

src/githubHelper.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ export class GithubHelper {
346346
let bodyConverted = await this.convertIssuesAndComments(
347347
issue.description ?? '',
348348
issue,
349-
!this.userIsCreator(issue.author) || !issue.description
349+
!this.userIsCreator(issue.author) || !issue.description,
350+
true,
351+
true,
350352
);
351353

352354
let props: RestEndpointMethodTypes['issues']['create']['parameters'] = {
@@ -460,7 +462,9 @@ export class GithubHelper {
460462
: await this.convertIssuesAndComments(
461463
issue.description ?? '',
462464
issue,
463-
!this.userIsCreator(issue.author) || !issue.description
465+
!this.userIsCreator(issue.author) || !issue.description,
466+
true,
467+
true,
464468
);
465469

466470
let props: IssueImport = {
@@ -985,7 +989,10 @@ export class GithubHelper {
985989
if (canCreate) {
986990
let bodyConverted = await this.convertIssuesAndComments(
987991
mergeRequest.description,
988-
mergeRequest
992+
mergeRequest,
993+
true,
994+
true,
995+
true,
989996
);
990997

991998
// GitHub API Documentation to create a pull request: https://developer.github.com/v3/pulls/#create-a-pull-request
@@ -1027,7 +1034,9 @@ export class GithubHelper {
10271034
let bodyConverted = await this.convertIssuesAndComments(
10281035
mergeStr + mergeRequest.description,
10291036
mergeRequest,
1030-
!this.userIsCreator(mergeRequest.author) || !settings.useIssueImportAPI
1037+
!this.userIsCreator(mergeRequest.author) || !settings.useIssueImportAPI,
1038+
true,
1039+
true,
10311040
);
10321041

10331042
if (settings.useIssueImportAPI) {
@@ -1284,12 +1293,15 @@ export class GithubHelper {
12841293
* @param str Body of the GitLab note
12851294
* @param item GitLab item to which the note belongs
12861295
* @param add_line Set to true to add the line with author and creation date
1296+
* @param add_line_ref Set to true to add the line ref to the comment
1297+
* @param add_issue_information Set to true to add assignees, reviewers, and approvers
12871298
*/
12881299
async convertIssuesAndComments(
12891300
str: string,
12901301
item: GitLabIssue | GitLabMergeRequest | GitLabNote | MilestoneImport | GitLabDiscussionNote,
12911302
add_line: boolean = true,
12921303
add_line_ref: boolean = true,
1304+
add_issue_information: boolean = false,
12931305
): Promise<string> {
12941306
// A note on implementation:
12951307
// We don't convert project names once at the beginning because otherwise
@@ -1464,6 +1476,11 @@ export class GithubHelper {
14641476
this.gitlabHelper
14651477
);
14661478

1479+
if (add_issue_information && settings.conversion.addIssueInformation) {
1480+
let issue = item as GitLabIssue;
1481+
str = await this.addIssueInformation(issue, str)
1482+
}
1483+
14671484
if ('web_url' in item) {
14681485
str += '\n\n*Migrated from GitLab: ' + item.web_url + '*';
14691486
}
@@ -1564,6 +1581,26 @@ export class GithubHelper {
15641581
return lineRef;
15651582
}
15661583

1584+
async addIssueInformation(issue: GitLabIssue | GitLabMergeRequest, description: string): Promise<string> {
1585+
let bodyConverted = description;
1586+
1587+
let assignees = issue.assignees.map(a => a.username) as string[];
1588+
bodyConverted += utils.organizationUsersString(assignees, "Assignees");
1589+
1590+
// check whether issue is of type GitLabMergeRequest
1591+
if (issue.reviewers) {
1592+
let mergeRequest = issue as GitLabMergeRequest;
1593+
1594+
let mrReviewers = mergeRequest.reviewers.map(a => a.username) as string[];
1595+
bodyConverted += utils.organizationUsersString(mrReviewers, 'Reviewers');
1596+
1597+
let approvals = await this.gitlabHelper.getMergeRequestApprovals(mergeRequest.iid);
1598+
bodyConverted += utils.organizationUsersString(approvals, 'Approved by');
1599+
}
1600+
1601+
return bodyConverted;
1602+
}
1603+
15671604
/**
15681605
* Meh...
15691606
* @param milestoneMap

src/gitlabHelper.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,28 @@ export class GitlabHelper {
151151
return this.allBranches as any[];
152152
}
153153

154+
async getMergeRequestApprovals(pullRequestIid: number): Promise<string[]> {
155+
try {
156+
let approvals = await this.gitlabApi.MergeRequestApprovals.showConfiguration(
157+
this.gitlabProjectId,
158+
{
159+
mergerequestIId: pullRequestIid,
160+
},
161+
);
162+
163+
if (approvals.rules[0]) {
164+
return approvals.rules[0].approved_by.map(user => user.username);
165+
}
166+
167+
console.log(`No approvals found for GitLab merge request !${pullRequestIid}.`)
168+
} catch (err) {
169+
console.error(
170+
`Could not fetch approvals for GitLab merge request !${pullRequestIid}: ${err}`
171+
);
172+
}
173+
return [];
174+
}
175+
154176
/**
155177
* Gets all notes for a given merge request.
156178
*/

src/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default interface Settings {
1111
};
1212
conversion: {
1313
useLowerCaseLabels: boolean;
14+
addIssueInformation: boolean;
1415
};
1516
transfer: {
1617
description: boolean;

src/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { S3Settings } from './settings';
2+
import settings from '../settings';
23
import * as mime from 'mime-types';
34
import * as path from 'path';
45
import * as crypto from 'crypto';
@@ -97,3 +98,22 @@ export const migrateAttachments = async (
9798
({}, {}, {}, {}, offset, {}) => offsetToAttachment[offset]
9899
);
99100
};
101+
102+
export const organizationUsersString = (users: string[], prefix: string): string => {
103+
let organizationUsers = [];
104+
for (let assignee of users) {
105+
let githubUser = settings.usermap[assignee as string];
106+
if (githubUser) {
107+
githubUser = '@' + githubUser;
108+
} else {
109+
githubUser = assignee as string;
110+
}
111+
organizationUsers.push(githubUser);
112+
}
113+
114+
if (organizationUsers.length > 0) {
115+
return `\n\n**${prefix}:** ` + organizationUsers.join(', ');
116+
}
117+
118+
return '';
119+
}

0 commit comments

Comments
 (0)