@@ -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 ,
@@ -561,6 +563,85 @@ export class GithubHelper {
561563 ) ;
562564 return comments ;
563565 }
566+
567+ /**
568+ *
569+ * @param discussions
570+ * @returns Comments ready for requestImportIssue()
571+ */
572+ async processDiscussionsIntoComments (
573+ discussions : GitLabDiscussion [ ]
574+ ) : Promise < CommentImport [ ] > {
575+ if ( ! discussions || ! discussions . length ) {
576+ console . log ( `\t...no comments available, nothing to migrate.` ) ;
577+ return [ ] ;
578+ }
579+
580+ let comments : CommentImport [ ] = [ ] ;
581+
582+ // sort notes in ascending order of when they were created (by id)
583+ discussions = discussions . sort ( ( a , b ) => Number . parseInt ( a . id ) - Number . parseInt ( b . id ) ) ;
584+
585+ let nrOfMigratedNotes = 0 ;
586+ let nrOfSkippedNotes = 0 ;
587+ for ( let discussion of discussions ) {
588+ let discussionComments = [ ] ;
589+
590+ for ( let note of discussion . notes ) {
591+ if ( this . checkIfNoteCanBeSkipped ( note . body ) ) {
592+ nrOfSkippedNotes ++ ;
593+ continue ;
594+ }
595+
596+ let username = note . author . username as string ;
597+ this . users . add ( username ) ;
598+ let userIsPoster =
599+ ( settings . usermap &&
600+ settings . usermap [ username ] ===
601+ settings . github . token_owner ) ||
602+ username === settings . github . token_owner ;
603+
604+ // only add line ref for first note of discussion
605+ const add_line_ref = discussion . notes . indexOf ( note ) === 0 ;
606+
607+ discussionComments . push ( {
608+ created_at : note . created_at ,
609+ body : await this . convertIssuesAndComments (
610+ note . body ,
611+ note ,
612+ ! userIsPoster || ! note . body ,
613+ add_line_ref ,
614+ ) ,
615+ } ) ;
616+
617+ nrOfMigratedNotes ++ ;
618+ }
619+
620+ // Combine notes for discussion into one comment
621+ if ( discussionComments . length == 1 ) {
622+ comments . push ( discussionComments [ 0 ] ) ;
623+ }
624+ else if ( discussionComments . length > 1 ) {
625+ let combinedBody = '**Discussion in GitLab:**\n\n' ;
626+ let first_created_at = discussionComments [ 0 ] . created_at ;
627+
628+ combinedBody += discussionComments . map ( comment => comment . body ) . join ( '\n\n' ) ;
629+
630+ comments . push ( {
631+ created_at : first_created_at ,
632+ body : combinedBody ,
633+ } ) ;
634+ }
635+ }
636+
637+ console . log (
638+ `\t...Done creating discussion comments (migrated ${ nrOfMigratedNotes } comments, skipped ${
639+ nrOfSkippedNotes
640+ } comments)`
641+ ) ;
642+ return comments ;
643+ }
644+
564645 /**
565646 * Calls the preview API for issue importing
566647 *
@@ -691,7 +772,7 @@ export class GithubHelper {
691772 * Return false when it got skipped, otherwise true.
692773 */
693774 async processNote (
694- note : GitLabNote ,
775+ note : GitLabNote | GitLabDiscussionNote ,
695776 githubIssue : Pick < GitHubIssue | GitHubPullRequest , 'number' >
696777 ) {
697778 if ( this . checkIfNoteCanBeSkipped ( note . body ) ) return false ;
@@ -966,10 +1047,10 @@ export class GithubHelper {
9661047 '\t...this is a placeholder for a deleted GitLab merge request, no comments are created.'
9671048 ) ;
9681049 } else {
969- let notes = await this . gitlabHelper . getAllMergeRequestNotes (
1050+ let discussions = await this . gitlabHelper . getAllMergeRequestDiscussions (
9701051 mergeRequest . iid
9711052 ) ;
972- comments = await this . processNotesIntoComments ( notes ) ;
1053+ comments = await this . processDiscussionsIntoComments ( discussions ) ;
9731054 }
9741055
9751056 return this . requestImportIssue ( props , comments ) ;
@@ -1010,30 +1091,72 @@ export class GithubHelper {
10101091 return Promise . resolve ( ) ;
10111092 }
10121093
1013- let notes = await this . gitlabHelper . getAllMergeRequestNotes (
1094+ let discussions = await this . gitlabHelper . getAllMergeRequestDiscussions (
10141095 mergeRequest . iid
10151096 ) ;
10161097
10171098 // if there are no notes, then there is nothing to do!
1018- if ( notes . length === 0 ) {
1099+ if ( discussions . length === 0 ) {
10191100 console . log (
10201101 `\t...no pull request comments available, nothing to migrate.`
10211102 ) ;
10221103 return ;
10231104 }
10241105
10251106 // Sort notes in ascending order of when they were created (by id)
1026- notes = notes . sort ( ( a , b ) => a . id - b . id ) ;
1107+ discussions = discussions . sort ( ( a , b ) => a . notes [ 0 ] . id - b . notes [ 0 ] . id ) ;
10271108
10281109 let nrOfMigratedNotes = 0 ;
1029- for ( let note of notes ) {
1030- const gotMigrated = await this . processNote ( note , pullRequest ) ;
1031- if ( gotMigrated ) nrOfMigratedNotes ++ ;
1110+ let nrOfSkippedNotes = 0 ;
1111+ for ( let discussion of discussions ) {
1112+ if ( discussion . individual_note ) {
1113+ const gotMigrated = await this . processNote ( discussion . notes [ 0 ] , pullRequest ) ;
1114+ if ( gotMigrated ) {
1115+ nrOfMigratedNotes ++ ;
1116+ }
1117+ else {
1118+ nrOfSkippedNotes ++ ;
1119+ }
1120+ }
1121+ else {
1122+ // console.log('Processing discussion:');
1123+ let discussionBody = '**Discussion in GitLab:**\n\n' ;
1124+
1125+ for ( let note of discussion . notes ) {
1126+ if ( this . checkIfNoteCanBeSkipped ( note . body ) ) {
1127+ nrOfSkippedNotes ++ ;
1128+ continue ;
1129+ }
1130+
1131+ const add_line_ref = discussion . notes . indexOf ( note ) === 0 ;
1132+ let bodyConverted = await this . convertIssuesAndComments ( note . body , note , true , add_line_ref ) ;
1133+ discussionBody += bodyConverted ;
1134+ discussionBody += '\n\n' ;
1135+ nrOfMigratedNotes ++ ;
1136+ }
1137+
1138+ await utils . sleep ( this . delayInMs ) ;
1139+
1140+ if ( ! settings . dryRun ) {
1141+ await this . githubApi . issues
1142+ . createComment ( {
1143+ owner : this . githubOwner ,
1144+ repo : this . githubRepo ,
1145+ issue_number : pullRequest . number ,
1146+ body : discussionBody ,
1147+ } )
1148+ . catch ( x => {
1149+ console . error ( 'could not create GitHub issue comment!' ) ;
1150+ console . error ( x ) ;
1151+ process . exit ( 1 ) ;
1152+ } ) ;
1153+ }
1154+ }
10321155 }
10331156
10341157 console . log (
10351158 `\t...Done creating pull request comments (migrated ${ nrOfMigratedNotes } pull request comments, skipped ${
1036- notes . length - nrOfMigratedNotes
1159+ nrOfSkippedNotes
10371160 } pull request comments)`
10381161 ) ;
10391162 }
@@ -1159,8 +1282,9 @@ export class GithubHelper {
11591282 */
11601283 async convertIssuesAndComments (
11611284 str : string ,
1162- item : GitLabIssue | GitLabMergeRequest | GitLabNote | MilestoneImport ,
1163- add_line : boolean = true
1285+ item : GitLabIssue | GitLabMergeRequest | GitLabNote | MilestoneImport | GitLabDiscussionNote ,
1286+ add_line : boolean = true ,
1287+ add_line_ref : boolean = true ,
11641288 ) : Promise < string > {
11651289 // A note on implementation:
11661290 // We don't convert project names once at the beginning because otherwise
@@ -1176,7 +1300,7 @@ export class GithubHelper {
11761300 settings . projectmap !== null &&
11771301 Object . keys ( settings . projectmap ) . length > 0 ;
11781302
1179- if ( add_line ) str = GithubHelper . addMigrationLine ( str , item , repoLink ) ;
1303+ if ( add_line ) str = GithubHelper . addMigrationLine ( str , item , repoLink , add_line_ref ) ;
11801304 let reString = '' ;
11811305
11821306 // Store usernames found in the text
@@ -1348,7 +1472,7 @@ export class GithubHelper {
13481472 * Adds a line of text at the beginning of a comment that indicates who, when
13491473 * and from GitLab.
13501474 */
1351- static addMigrationLine ( str : string , item : any , repoLink : string ) : string {
1475+ static addMigrationLine ( str : string , item : any , repoLink : string , add_line_ref : boolean = true ) : string {
13521476 if ( ! item || ! item . author || ! item . author . username || ! item . created_at ) {
13531477 return str ;
13541478 }
@@ -1368,11 +1492,12 @@ export class GithubHelper {
13681492 dateformatOptions
13691493 ) ;
13701494
1371- const attribution = `In GitLab by @${ item . author . username } on ${ formattedDate } ` ;
1495+ const attribution = `*** In GitLab by @${ item . author . username } on ${ formattedDate } :*** ` ;
13721496 const lineRef =
1373- item && item . position
1497+ item && item . position && add_line_ref
13741498 ? GithubHelper . createLineRef ( item . position , repoLink )
13751499 : '' ;
1500+
13761501 const summary = attribution + ( lineRef ? `\n\n${ lineRef } ` : '' ) ;
13771502
13781503 return `${ summary } \n\n${ str } ` ;
@@ -1392,7 +1517,7 @@ export class GithubHelper {
13921517 return '' ;
13931518 }
13941519 const base_sha = position . base_sha ;
1395- const head_sha = position . head_sha ;
1520+ let head_sha = position . head_sha ;
13961521 var path = '' ;
13971522 var line = '' ;
13981523 var slug = '' ;
@@ -1416,7 +1541,22 @@ export class GithubHelper {
14161541 }
14171542 // Mention the file and line number. If we can't get this for some reason then use the commit id instead.
14181543 const ref = path && line ? `${ path } line ${ line } ` : `${ head_sha } ` ;
1419- return `Commented on [${ ref } ](${ repoLink } /compare/${ base_sha } ..${ head_sha } ${ slug } )\n\n` ;
1544+ let lineRef = `Commented on [${ ref } ](${ repoLink } /compare/${ base_sha } ..${ head_sha } ${ slug } )\n\n` ;
1545+
1546+ if ( position . line_range . start . type === 'new' ) {
1547+ const startLine = position . line_range . start . new_line ;
1548+ const endLine = position . line_range . end . new_line ;
1549+ const lineRange = ( startLine !== endLine ) ? `L${ startLine } -L${ endLine } ` : `L${ startLine } ` ;
1550+ lineRef += `${ repoLink } /blob/${ head_sha } /${ path } #${ lineRange } \n\n` ;
1551+ }
1552+ else {
1553+ const startLine = position . line_range . start . old_line ;
1554+ const endLine = position . line_range . end . old_line ;
1555+ const lineRange = ( startLine !== endLine ) ? `L${ startLine } -L${ endLine } ` : `L${ startLine } ` ;
1556+ lineRef += `${ repoLink } /blob/${ head_sha } /${ path } #${ lineRange } \n\n` ;
1557+ }
1558+
1559+ return lineRef ;
14201560 }
14211561
14221562 /**
0 commit comments