@@ -8,13 +8,10 @@ import { ApolloQueryResult, DocumentNode, FetchResult, MutationOptions, NetworkS
88import LRUCache from 'lru-cache' ;
99import * as vscode from 'vscode' ;
1010import { AuthenticationError , AuthProvider , GitHubServerType , isSamlError } from '../common/authentication' ;
11- import { COPILOT_ACCOUNTS , IComment , IReviewThread } from '../common/comment' ;
1211import { Disposable , disposeAll } from '../common/lifecycle' ;
1312import Logger from '../common/logger' ;
1413import { GitHubRemote , parseRemote } from '../common/remote' ;
1514import { ITelemetry } from '../common/telemetry' ;
16- import * as Common from '../common/timelineEvent' ;
17- import { compareIgnoreCase , formatError } from '../common/utils' ;
1815import { PRCommentControllerRegistry } from '../view/pullRequestCommentControllerRegistry' ;
1916import { mergeQuerySchemaWithShared , OctokitCommon , Schema } from './common' ;
2017import { CredentialStore , GitHub } from './credentials' ;
@@ -43,7 +40,6 @@ import {
4340 RepoProjectsResponse ,
4441 RevertPullRequestResponse ,
4542 SuggestedActorsResponse ,
46- TimelineEventsResponse ,
4743 UserResponse ,
4844 ViewerPermissionResponse ,
4945} from './graphql' ;
@@ -70,20 +66,16 @@ import * as limitedSchema from './queriesLimited.gql';
7066import * as sharedSchema from './queriesShared.gql' ;
7167import {
7268 convertRESTPullRequestToRawPullRequest ,
73- eventTime ,
7469 getAvatarWithEnterpriseFallback ,
7570 getOverrideBranch ,
76- insertNewCommitsSinceReview ,
7771 isInCodespaces ,
7872 parseAccount ,
79- parseCombinedTimelineEvents ,
8073 parseGraphQLIssue ,
8174 parseGraphQLPullRequest ,
8275 parseGraphQLUser ,
8376 parseGraphQLViewerPermission ,
8477 parseMergeMethod ,
8578 parseMilestone ,
86- parseSelectRestTimelineEvents ,
8779 restPaginate ,
8880} from './utils' ;
8981
@@ -1516,229 +1508,6 @@ export class GitHubRepository extends Disposable {
15161508 return this . _credentialStore . isCurrentUser ( authProviderId , login ) ;
15171509 }
15181510
1519-
1520- /**
1521- * TODO: @alexr00 we should delete this https://github.com/microsoft/vscode-pull-request-github/issues/6965
1522- */
1523- async getCopilotTimelineEvents ( issueModel : IssueModel , skipMerge : boolean = false ) : Promise < Common . TimelineEvent [ ] > {
1524- if ( ! COPILOT_ACCOUNTS [ issueModel . author . login ] ) {
1525- return [ ] ;
1526- }
1527-
1528- Logger . debug ( `Fetch Copilot timeline events of issue #${ issueModel . number } - enter` , GitHubRepository . ID ) ;
1529-
1530- const { octokit, remote } = await this . ensure ( ) ;
1531- try {
1532- const timeline = await restPaginate < typeof octokit . api . issues . listEventsForTimeline , OctokitCommon . ListEventsForTimelineResponse > ( octokit . api . issues . listEventsForTimeline , {
1533- issue_number : issueModel . number ,
1534- owner : remote . owner ,
1535- repo : remote . repositoryName ,
1536- per_page : 100
1537- } ) ;
1538-
1539- const timelineEvents = parseSelectRestTimelineEvents ( issueModel , timeline ) ;
1540- if ( timelineEvents . length === 0 ) {
1541- return [ ] ;
1542- }
1543- if ( ! skipMerge ) {
1544- const oldLastEvent = issueModel . timelineEvents . length > 0 ? issueModel . timelineEvents [ issueModel . timelineEvents . length - 1 ] : undefined ;
1545- let allEvents : Common . TimelineEvent [ ] ;
1546- if ( ! oldLastEvent ) {
1547- allEvents = timelineEvents ;
1548- } else {
1549- const oldEventTime = ( eventTime ( oldLastEvent ) ?? 0 ) ;
1550- const newEvents = timelineEvents . filter ( event => ( eventTime ( event ) ?? 0 ) > oldEventTime ) ;
1551- allEvents = [ ...issueModel . timelineEvents , ...newEvents ] ;
1552- }
1553- const oldTimeline = issueModel . timelineEvents ;
1554- issueModel . timelineEvents = allEvents ;
1555- if ( oldLastEvent && ( allEvents . length !== oldTimeline . length ) ) {
1556- this . _onDidChangePullRequests . fire ( [ issueModel ] ) ;
1557- }
1558- }
1559- return timelineEvents ;
1560- } catch ( e ) {
1561- Logger . error ( `Error fetching Copilot timeline events of issue #${ issueModel . number } - ${ formatError ( e ) } ` , GitHubRepository . ID ) ;
1562- return [ ] ;
1563- }
1564- }
1565-
1566- async getIssueTimelineEvents ( issueModel : IssueModel ) : Promise < Common . TimelineEvent [ ] > {
1567- Logger . debug ( `Fetch timeline events of issue #${ issueModel . number } - enter` , GitHubRepository . ID ) ;
1568- const { query, remote, schema } = await this . ensure ( ) ;
1569-
1570- try {
1571- const { data } = await query < TimelineEventsResponse > ( {
1572- query : schema . IssueTimelineEvents ,
1573- variables : {
1574- owner : remote . owner ,
1575- name : remote . repositoryName ,
1576- number : issueModel . number ,
1577- } ,
1578- } ) ;
1579-
1580- if ( data . repository === null ) {
1581- Logger . error ( 'Unexpected null repository when getting issue timeline events' , GitHubRepository . ID ) ;
1582- return [ ] ;
1583- }
1584- const ret = data . repository . pullRequest . timelineItems . nodes ;
1585- const events = await parseCombinedTimelineEvents ( ret , await this . getCopilotTimelineEvents ( issueModel , true ) , this ) ;
1586-
1587- const crossRefs = new Map ( events
1588- . filter ( ( event ) : event is Common . CrossReferencedEvent => {
1589- if ( ( event . event === Common . EventType . CrossReferenced ) && ! event . source . isIssue ) {
1590- return ( compareIgnoreCase ( event . source . owner , issueModel . remote . owner ) === 0 && compareIgnoreCase ( event . source . repo , issueModel . remote . repositoryName ) === 0 ) ;
1591- }
1592- return false ;
1593-
1594- } ) . map ( ( event : Common . CrossReferencedEvent ) => {
1595- return [ event . source . url , event ] ;
1596- } ) ) ;
1597-
1598- for ( const pr of this . _pullRequestModelsByNumber . values ( ) ) {
1599- if ( crossRefs . has ( pr . model . html_url ) ) {
1600- crossRefs . delete ( pr . model . html_url ) ;
1601- }
1602- }
1603- const oldEvents = issueModel . timelineEvents ;
1604- issueModel . timelineEvents = events ;
1605- if ( crossRefs . size > 0 ) {
1606- this . _onDidChangePullRequests . fire ( [ issueModel ] ) ;
1607- } else if ( oldEvents . length !== events . length ) {
1608- this . _onDidChangePullRequests . fire ( [ issueModel ] ) ;
1609- }
1610- return events ;
1611- } catch ( e ) {
1612- console . log ( e ) ;
1613- return [ ] ;
1614- }
1615- }
1616-
1617- async copilotWorkingStatus ( issueModel : IssueModel ) : Promise < CopilotWorkingStatus | undefined > {
1618- const copilotEvents = await this . getCopilotTimelineEvents ( issueModel ) ;
1619- if ( copilotEvents . length > 0 ) {
1620- const lastEvent = copilotEvents [ copilotEvents . length - 1 ] ;
1621- if ( lastEvent . event === Common . EventType . CopilotFinished ) {
1622- return CopilotWorkingStatus . Done ;
1623- } else if ( lastEvent . event === Common . EventType . CopilotStarted ) {
1624- return CopilotWorkingStatus . InProgress ;
1625- } else if ( lastEvent . event === Common . EventType . CopilotFinishedError ) {
1626- return CopilotWorkingStatus . Error ;
1627- }
1628- }
1629- return CopilotWorkingStatus . NotCopilotIssue ;
1630- }
1631-
1632- /**
1633- * Get the timeline events of a pull request, including comments, reviews, commits, merges, deletes, and assigns.
1634- */
1635- async getTimelineEvents ( pullRequestModel : PullRequestModel ) : Promise < Common . TimelineEvent [ ] > {
1636- const getTimelineEvents = async ( ) => {
1637- Logger . debug ( `Fetch timeline events of PR #${ pullRequestModel . number } - enter` , PullRequestModel . ID ) ;
1638- const { query, remote, schema } = await this . ensure ( ) ;
1639- try {
1640- const { data } = await query < TimelineEventsResponse > ( {
1641- query : schema . TimelineEvents ,
1642- variables : {
1643- owner : remote . owner ,
1644- name : remote . repositoryName ,
1645- number : pullRequestModel . number ,
1646- } ,
1647- } ) ;
1648-
1649- if ( data . repository === null ) {
1650- Logger . error ( 'Unexpected null repository when fetching timeline' , PullRequestModel . ID ) ;
1651- }
1652- return data ;
1653- } catch ( e ) {
1654- Logger . error ( `Failed to get pull request timeline events: ${ e } ` , PullRequestModel . ID ) ;
1655- console . log ( e ) ;
1656- return undefined ;
1657- }
1658- } ;
1659-
1660- const [ data , latestReviewCommitInfo , currentUser , reviewThreads ] = await Promise . all ( [
1661- getTimelineEvents ( ) ,
1662- pullRequestModel . getViewerLatestReviewCommit ( ) ,
1663- ( await this . getAuthenticatedUser ( ) ) . login ,
1664- pullRequestModel . getReviewThreads ( )
1665- ] ) ;
1666-
1667-
1668- const ret = data ?. repository ?. pullRequest . timelineItems . nodes ?? [ ] ;
1669- const events = await parseCombinedTimelineEvents ( ret , await this . getCopilotTimelineEvents ( pullRequestModel , true ) , this ) ;
1670-
1671- this . addReviewTimelineEventComments ( events , reviewThreads ) ;
1672- insertNewCommitsSinceReview ( events , latestReviewCommitInfo ?. sha , currentUser , pullRequestModel . head ) ;
1673- Logger . debug ( `Fetch timeline events of PR #${ pullRequestModel . number } - done` , PullRequestModel . ID ) ;
1674- const oldEvents = pullRequestModel . timelineEvents ;
1675- pullRequestModel . timelineEvents = events ;
1676- if ( oldEvents . length !== events . length ) {
1677- this . _onDidChangePullRequests . fire ( [ pullRequestModel ] ) ;
1678- }
1679- return events ;
1680- }
1681-
1682- private addReviewTimelineEventComments ( events : Common . TimelineEvent [ ] , reviewThreads : IReviewThread [ ] ) : void {
1683- interface CommentNode extends IComment {
1684- childComments ?: CommentNode [ ] ;
1685- }
1686-
1687- const reviewEvents = events . filter ( ( e ) : e is Common . ReviewEvent => e . event === Common . EventType . Reviewed ) ;
1688- const reviewComments = reviewThreads . reduce ( ( previous , current ) => ( previous as IComment [ ] ) . concat ( current . comments ) , [ ] ) ;
1689-
1690- const reviewEventsById = reviewEvents . reduce ( ( index , evt ) => {
1691- index [ evt . id ] = evt ;
1692- evt . comments = [ ] ;
1693- return index ;
1694- } , { } as { [ key : number ] : Common . ReviewEvent } ) ;
1695-
1696- const commentsById = reviewComments . reduce ( ( index , evt ) => {
1697- index [ evt . id ] = evt ;
1698- return index ;
1699- } , { } as { [ key : number ] : CommentNode } ) ;
1700-
1701- const roots : CommentNode [ ] = [ ] ;
1702- let i = reviewComments . length ;
1703- while ( i -- > 0 ) {
1704- const c : CommentNode = reviewComments [ i ] ;
1705- if ( ! c . inReplyToId ) {
1706- roots . unshift ( c ) ;
1707- continue ;
1708- }
1709- const parent = commentsById [ c . inReplyToId ] ;
1710- parent . childComments = parent . childComments || [ ] ;
1711- parent . childComments = [ c , ...( c . childComments || [ ] ) , ...parent . childComments ] ;
1712- }
1713-
1714- roots . forEach ( c => {
1715- const review = reviewEventsById [ c . pullRequestReviewId ! ] ;
1716- if ( review ) {
1717- review . comments = review . comments . concat ( c ) . concat ( c . childComments || [ ] ) ;
1718- }
1719- } ) ;
1720-
1721- reviewThreads . forEach ( thread => {
1722- if ( ! thread . prReviewDatabaseId || ! reviewEventsById [ thread . prReviewDatabaseId ] ) {
1723- return ;
1724- }
1725- const prReviewThreadEvent = reviewEventsById [ thread . prReviewDatabaseId ] ;
1726- prReviewThreadEvent . reviewThread = {
1727- threadId : thread . id ,
1728- canResolve : thread . viewerCanResolve ,
1729- canUnresolve : thread . viewerCanUnresolve ,
1730- isResolved : thread . isResolved
1731- } ;
1732-
1733- } ) ;
1734-
1735- const pendingReview = reviewEvents . filter ( r => r . state ?. toLowerCase ( ) === 'pending' ) [ 0 ] ;
1736- if ( pendingReview ) {
1737- // Ensures that pending comments made in reply to other reviews are included for the pending review
1738- pendingReview . comments = reviewComments . filter ( c => c . isDraft ) ;
1739- }
1740- }
1741-
17421511 /**
17431512 * Get the status checks of the pull request, those for the last commit.
17441513 *
0 commit comments