@@ -4,6 +4,8 @@ import * as utils from './utils';
44import { Octokit as GitHubApi , RestEndpointMethodTypes } from '@octokit/rest' ;
55import { Endpoints } from '@octokit/types' ;
66import {
7+ GitLabDiscussion ,
8+ GitLabDiscussionNote ,
79 GitlabHelper ,
810 GitLabIssue ,
911 GitLabMergeRequest ,
@@ -555,6 +557,85 @@ export class GithubHelper {
555557 ) ;
556558 return comments ;
557559 }
560+
561+ /**
562+ *
563+ * @param discussions
564+ * @returns Comments ready for requestImportIssue()
565+ */
566+ async processDiscussionsIntoComments (
567+ discussions : GitLabDiscussion [ ]
568+ ) : Promise < CommentImport [ ] > {
569+ if ( ! discussions || ! discussions . length ) {
570+ console . log ( `\t...no comments available, nothing to migrate.` ) ;
571+ return [ ] ;
572+ }
573+
574+ let comments : CommentImport [ ] = [ ] ;
575+
576+ // sort notes in ascending order of when they were created (by id)
577+ discussions = discussions . sort ( ( a , b ) => Number . parseInt ( a . id ) - Number . parseInt ( b . id ) ) ;
578+
579+ let nrOfMigratedNotes = 0 ;
580+ let nrOfSkippedNotes = 0 ;
581+ for ( let discussion of discussions ) {
582+ let discussionComments = [ ] ;
583+
584+ for ( let note of discussion . notes ) {
585+ if ( this . checkIfNoteCanBeSkipped ( note . body ) ) {
586+ nrOfSkippedNotes ++ ;
587+ continue ;
588+ }
589+
590+ let username = note . author . username as string ;
591+ this . users . add ( username ) ;
592+ let userIsPoster =
593+ ( settings . usermap &&
594+ settings . usermap [ username ] ===
595+ settings . github . token_owner ) ||
596+ username === settings . github . token_owner ;
597+
598+ // only add line ref for first note of discussion
599+ const add_line_ref = discussion . notes . indexOf ( note ) === 0 ;
600+
601+ discussionComments . push ( {
602+ created_at : note . created_at ,
603+ body : await this . convertIssuesAndComments (
604+ note . body ,
605+ note ,
606+ ! userIsPoster || ! note . body ,
607+ add_line_ref ,
608+ ) ,
609+ } ) ;
610+
611+ nrOfMigratedNotes ++ ;
612+ }
613+
614+ // Combine notes for discussion into one comment
615+ if ( discussionComments . length == 1 ) {
616+ comments . push ( discussionComments [ 0 ] ) ;
617+ }
618+ else if ( discussionComments . length > 1 ) {
619+ let combinedBody = '**Discussion in GitLab:**\n\n' ;
620+ let first_created_at = discussionComments [ 0 ] . created_at ;
621+
622+ combinedBody += discussionComments . map ( comment => comment . body ) . join ( '\n\n' ) ;
623+
624+ comments . push ( {
625+ created_at : first_created_at ,
626+ body : combinedBody ,
627+ } ) ;
628+ }
629+ }
630+
631+ console . log (
632+ `\t...Done creating discussion comments (migrated ${ nrOfMigratedNotes } comments, skipped ${
633+ nrOfSkippedNotes
634+ } comments)`
635+ ) ;
636+ return comments ;
637+ }
638+
558639 /**
559640 * Calls the preview API for issue importing
560641 *
@@ -685,7 +766,7 @@ export class GithubHelper {
685766 * Return false when it got skipped, otherwise true.
686767 */
687768 async processNote (
688- note : GitLabNote ,
769+ note : GitLabNote | GitLabDiscussionNote ,
689770 githubIssue : Pick < GitHubIssue | GitHubPullRequest , 'number' >
690771 ) {
691772 if ( this . checkIfNoteCanBeSkipped ( note . body ) ) return false ;
@@ -960,10 +1041,10 @@ export class GithubHelper {
9601041 '\t...this is a placeholder for a deleted GitLab merge request, no comments are created.'
9611042 ) ;
9621043 } else {
963- let notes = await this . gitlabHelper . getAllMergeRequestNotes (
1044+ let discussions = await this . gitlabHelper . getAllMergeRequestDiscussions (
9641045 mergeRequest . iid
9651046 ) ;
966- comments = await this . processNotesIntoComments ( notes ) ;
1047+ comments = await this . processDiscussionsIntoComments ( discussions ) ;
9671048 }
9681049
9691050 return this . requestImportIssue ( props , comments ) ;
@@ -1004,30 +1085,72 @@ export class GithubHelper {
10041085 return Promise . resolve ( ) ;
10051086 }
10061087
1007- let notes = await this . gitlabHelper . getAllMergeRequestNotes (
1088+ let discussions = await this . gitlabHelper . getAllMergeRequestDiscussions (
10081089 mergeRequest . iid
10091090 ) ;
10101091
10111092 // if there are no notes, then there is nothing to do!
1012- if ( notes . length === 0 ) {
1093+ if ( discussions . length === 0 ) {
10131094 console . log (
10141095 `\t...no pull request comments available, nothing to migrate.`
10151096 ) ;
10161097 return ;
10171098 }
10181099
10191100 // Sort notes in ascending order of when they were created (by id)
1020- notes = notes . sort ( ( a , b ) => a . id - b . id ) ;
1101+ discussions = discussions . sort ( ( a , b ) => a . notes [ 0 ] . id - b . notes [ 0 ] . id ) ;
10211102
10221103 let nrOfMigratedNotes = 0 ;
1023- for ( let note of notes ) {
1024- const gotMigrated = await this . processNote ( note , pullRequest ) ;
1025- if ( gotMigrated ) nrOfMigratedNotes ++ ;
1104+ let nrOfSkippedNotes = 0 ;
1105+ for ( let discussion of discussions ) {
1106+ if ( discussion . individual_note ) {
1107+ const gotMigrated = await this . processNote ( discussion . notes [ 0 ] , pullRequest ) ;
1108+ if ( gotMigrated ) {
1109+ nrOfMigratedNotes ++ ;
1110+ }
1111+ else {
1112+ nrOfSkippedNotes ++ ;
1113+ }
1114+ }
1115+ else {
1116+ // console.log('Processing discussion:');
1117+ let discussionBody = '**Discussion in GitLab:**\n\n' ;
1118+
1119+ for ( let note of discussion . notes ) {
1120+ if ( this . checkIfNoteCanBeSkipped ( note . body ) ) {
1121+ nrOfSkippedNotes ++ ;
1122+ continue ;
1123+ }
1124+
1125+ const add_line_ref = discussion . notes . indexOf ( note ) === 0 ;
1126+ let bodyConverted = await this . convertIssuesAndComments ( note . body , note , true , add_line_ref ) ;
1127+ discussionBody += bodyConverted ;
1128+ discussionBody += '\n\n' ;
1129+ nrOfMigratedNotes ++ ;
1130+ }
1131+
1132+ await utils . sleep ( this . delayInMs ) ;
1133+
1134+ if ( ! settings . dryRun ) {
1135+ await this . githubApi . issues
1136+ . createComment ( {
1137+ owner : this . githubOwner ,
1138+ repo : this . githubRepo ,
1139+ issue_number : pullRequest . number ,
1140+ body : discussionBody ,
1141+ } )
1142+ . catch ( x => {
1143+ console . error ( 'could not create GitHub issue comment!' ) ;
1144+ console . error ( x ) ;
1145+ process . exit ( 1 ) ;
1146+ } ) ;
1147+ }
1148+ }
10261149 }
10271150
10281151 console . log (
10291152 `\t...Done creating pull request comments (migrated ${ nrOfMigratedNotes } pull request comments, skipped ${
1030- notes . length - nrOfMigratedNotes
1153+ nrOfSkippedNotes
10311154 } pull request comments)`
10321155 ) ;
10331156 }
@@ -1153,8 +1276,9 @@ export class GithubHelper {
11531276 */
11541277 async convertIssuesAndComments (
11551278 str : string ,
1156- item : GitLabIssue | GitLabMergeRequest | GitLabNote | MilestoneImport ,
1157- add_line : boolean = true
1279+ item : GitLabIssue | GitLabMergeRequest | GitLabNote | MilestoneImport | GitLabDiscussionNote ,
1280+ add_line : boolean = true ,
1281+ add_line_ref : boolean = true ,
11581282 ) : Promise < string > {
11591283 // A note on implementation:
11601284 // We don't convert project names once at the beginning because otherwise
@@ -1170,7 +1294,7 @@ export class GithubHelper {
11701294 settings . projectmap !== null &&
11711295 Object . keys ( settings . projectmap ) . length > 0 ;
11721296
1173- if ( add_line ) str = GithubHelper . addMigrationLine ( str , item , repoLink ) ;
1297+ if ( add_line ) str = GithubHelper . addMigrationLine ( str , item , repoLink , add_line_ref ) ;
11741298 let reString = '' ;
11751299
11761300 // Store usernames found in the text
@@ -1342,7 +1466,7 @@ export class GithubHelper {
13421466 * Adds a line of text at the beginning of a comment that indicates who, when
13431467 * and from GitLab.
13441468 */
1345- static addMigrationLine ( str : string , item : any , repoLink : string ) : string {
1469+ static addMigrationLine ( str : string , item : any , repoLink : string , add_line_ref : boolean = true ) : string {
13461470 if ( ! item || ! item . author || ! item . author . username || ! item . created_at ) {
13471471 return str ;
13481472 }
@@ -1362,11 +1486,12 @@ export class GithubHelper {
13621486 dateformatOptions
13631487 ) ;
13641488
1365- const attribution = `In GitLab by @${ item . author . username } on ${ formattedDate } ` ;
1489+ const attribution = `*** In GitLab by @${ item . author . username } on ${ formattedDate } :*** ` ;
13661490 const lineRef =
1367- item && item . position
1491+ item && item . position && add_line_ref
13681492 ? GithubHelper . createLineRef ( item . position , repoLink )
13691493 : '' ;
1494+
13701495 const summary = attribution + ( lineRef ? `\n\n${ lineRef } ` : '' ) ;
13711496
13721497 return `${ summary } \n\n${ str } ` ;
@@ -1386,7 +1511,7 @@ export class GithubHelper {
13861511 return '' ;
13871512 }
13881513 const base_sha = position . base_sha ;
1389- const head_sha = position . head_sha ;
1514+ let head_sha = position . head_sha ;
13901515 var path = '' ;
13911516 var line = '' ;
13921517 var slug = '' ;
@@ -1410,7 +1535,22 @@ export class GithubHelper {
14101535 }
14111536 // Mention the file and line number. If we can't get this for some reason then use the commit id instead.
14121537 const ref = path && line ? `${ path } line ${ line } ` : `${ head_sha } ` ;
1413- return `Commented on [${ ref } ](${ repoLink } /compare/${ base_sha } ..${ head_sha } ${ slug } )\n\n` ;
1538+ let lineRef = `Commented on [${ ref } ](${ repoLink } /compare/${ base_sha } ..${ head_sha } ${ slug } )\n\n` ;
1539+
1540+ if ( position . line_range . start . type === 'new' ) {
1541+ const startLine = position . line_range . start . new_line ;
1542+ const endLine = position . line_range . end . new_line ;
1543+ const lineRange = ( startLine !== endLine ) ? `L${ startLine } -L${ endLine } ` : `L${ startLine } ` ;
1544+ lineRef += `${ repoLink } /blob/${ head_sha } /${ path } #${ lineRange } \n\n` ;
1545+ }
1546+ else {
1547+ const startLine = position . line_range . start . old_line ;
1548+ const endLine = position . line_range . end . old_line ;
1549+ const lineRange = ( startLine !== endLine ) ? `L${ startLine } -L${ endLine } ` : `L${ startLine } ` ;
1550+ lineRef += `${ repoLink } /blob/${ head_sha } /${ path } #${ lineRange } \n\n` ;
1551+ }
1552+
1553+ return lineRef ;
14141554 }
14151555
14161556 /**
0 commit comments