@@ -7,10 +7,13 @@ import * as buffer from 'buffer';
77import { ApolloQueryResult , DocumentNode , FetchResult , MutationOptions , NetworkStatus , QueryOptions } from 'apollo-boost' ;
88import * as vscode from 'vscode' ;
99import { AuthenticationError , AuthProvider , GitHubServerType , isSamlError } from '../common/authentication' ;
10+ import { COPILOT_ACCOUNTS } from '../common/comment' ;
1011import { Disposable } from '../common/lifecycle' ;
1112import Logger from '../common/logger' ;
1213import { GitHubRemote , parseRemote } from '../common/remote' ;
1314import { ITelemetry } from '../common/telemetry' ;
15+ import * as Common from '../common/timelineEvent' ;
16+ import { compareIgnoreCase , formatError } from '../common/utils' ;
1417import { PRCommentControllerRegistry } from '../view/pullRequestCommentControllerRegistry' ;
1518import { mergeQuerySchemaWithShared , OctokitCommon , Schema } from './common' ;
1619import { CredentialStore , GitHub } from './credentials' ;
@@ -39,6 +42,7 @@ import {
3942 RepoProjectsResponse ,
4043 RevertPullRequestResponse ,
4144 SuggestedActorsResponse ,
45+ TimelineEventsResponse ,
4246 ViewerPermissionResponse ,
4347} from './graphql' ;
4448import {
@@ -67,11 +71,14 @@ import {
6771 getOverrideBranch ,
6872 isInCodespaces ,
6973 parseAccount ,
74+ parseCombinedTimelineEvents ,
7075 parseGraphQLIssue ,
7176 parseGraphQLPullRequest ,
7277 parseGraphQLViewerPermission ,
7378 parseMergeMethod ,
7479 parseMilestone ,
80+ parseSelectRestTimelineEvents ,
81+ restPaginate ,
7582} from './utils' ;
7683
7784export const PULL_REQUEST_PAGE_SIZE = 20 ;
@@ -152,6 +159,8 @@ export class GitHubRepository extends Disposable {
152159
153160 private _onDidAddPullRequest : vscode . EventEmitter < PullRequestModel > = this . _register ( new vscode . EventEmitter ( ) ) ;
154161 public readonly onDidAddPullRequest : vscode . Event < PullRequestModel > = this . _onDidAddPullRequest . event ;
162+ private _onDidChangePullRequests : vscode . EventEmitter < void > = this . _register ( new vscode . EventEmitter ( ) ) ;
163+ public readonly onDidChangePullRequests : vscode . Event < void > = this . _onDidChangePullRequests . event ;
155164
156165 public get hub ( ) : GitHub {
157166 if ( ! this . _hub ) {
@@ -1443,6 +1452,81 @@ export class GitHubRepository extends Disposable {
14431452 return this . _credentialStore . isCurrentUser ( login ) ;
14441453 }
14451454
1455+
1456+ /**
1457+ * TODO: @alexr00 we should delete this https://github.com/microsoft/vscode-pull-request-github/issues/6965
1458+ */
1459+ async getCopilotTimelineEvents ( issueModel : IssueModel ) : Promise < Common . TimelineEvent [ ] > {
1460+ if ( ! COPILOT_ACCOUNTS [ issueModel . author . login ] ) {
1461+ return [ ] ;
1462+ }
1463+
1464+ Logger . debug ( `Fetch Copilot timeline events of issue #${ issueModel . number } - enter` , GitHubRepository . ID ) ;
1465+
1466+ const { octokit, remote } = await this . ensure ( ) ;
1467+ try {
1468+ const timeline = await restPaginate < typeof octokit . api . issues . listEventsForTimeline , OctokitCommon . ListEventsForTimelineResponse > ( octokit . api . issues . listEventsForTimeline , {
1469+ issue_number : issueModel . number ,
1470+ owner : remote . owner ,
1471+ repo : remote . repositoryName ,
1472+ per_page : 100
1473+ } ) ;
1474+
1475+ return parseSelectRestTimelineEvents ( issueModel , timeline ) ;
1476+ } catch ( e ) {
1477+ Logger . error ( `Error fetching Copilot timeline events of issue #${ issueModel . number } - ${ formatError ( e ) } ` , GitHubRepository . ID ) ;
1478+ return [ ] ;
1479+ }
1480+ }
1481+
1482+ async getIssueTimelineEvents ( issueModel : IssueModel ) : Promise < Common . TimelineEvent [ ] > {
1483+ Logger . debug ( `Fetch timeline events of issue #${ issueModel . number } - enter` , GitHubRepository . ID ) ;
1484+ const { query, remote, schema } = await this . ensure ( ) ;
1485+
1486+ try {
1487+ const { data } = await query < TimelineEventsResponse > ( {
1488+ query : schema . IssueTimelineEvents ,
1489+ variables : {
1490+ owner : remote . owner ,
1491+ name : remote . repositoryName ,
1492+ number : issueModel . number ,
1493+ } ,
1494+ } ) ;
1495+
1496+ if ( data . repository === null ) {
1497+ Logger . error ( 'Unexpected null repository when getting issue timeline events' , GitHubRepository . ID ) ;
1498+ return [ ] ;
1499+ }
1500+ const ret = data . repository . pullRequest . timelineItems . nodes ;
1501+ const events = await parseCombinedTimelineEvents ( ret , await this . getCopilotTimelineEvents ( issueModel ) , this ) ;
1502+
1503+ const crossRefs = new Map ( events
1504+ . filter ( ( event ) : event is Common . CrossReferencedEvent => {
1505+ if ( ( event . event === Common . EventType . CrossReferenced ) && ! event . source . isIssue ) {
1506+ return ( compareIgnoreCase ( event . source . owner , issueModel . remote . owner ) === 0 && compareIgnoreCase ( event . source . repo , issueModel . remote . repositoryName ) === 0 ) ;
1507+ }
1508+ return false ;
1509+
1510+ } ) . map ( ( event : Common . CrossReferencedEvent ) => {
1511+ return [ event . source . url , event ] ;
1512+ } ) ) ;
1513+
1514+ for ( const model of this . _pullRequestModels . values ( ) ) {
1515+ if ( crossRefs . has ( model . html_url ) ) {
1516+ crossRefs . delete ( model . html_url ) ;
1517+ }
1518+ }
1519+ if ( crossRefs . size > 0 ) {
1520+ this . _onDidChangePullRequests . fire ( ) ;
1521+ }
1522+
1523+ return events ;
1524+ } catch ( e ) {
1525+ console . log ( e ) ;
1526+ return [ ] ;
1527+ }
1528+ }
1529+
14461530 /**
14471531 * Get the status checks of the pull request, those for the last commit.
14481532 *
0 commit comments