@@ -33,70 +33,56 @@ public class GitHubProvider : IVcsProvider
3333
3434 // This query fragment will be executed for issues and pull requests
3535 // because we don't know whether issueNumber refers to an issue or a PR
36- private const string CONNECT_AND_DISCONNECT_EVENTS_GRAPHQL_QUERY_FRAGMENT = @"
37- {0}(number: $issueNumber) {{
38- timelineItems(first: $pageSize, itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT]) {{
39- nodes {{
40- __typename,
41- ...on ConnectedEvent {{
42- createdAt,
43- id,
44- source {{
45- __typename,
46- ... on Issue {{
47- number
48- }}
49- ... on PullRequest {{
50- number
51- }}
52- }},
53- subject {{
54- __typename
55- ... on Issue {{
56- number
57- }}
58- ... on PullRequest {{
59- number
60- }}
61- }}
62- }}
63- ...on DisconnectedEvent {{
64- createdAt,
65- id,
66- source {{
67- __typename,
68- ... on Issue {{
69- number
70- }}
71- ... on PullRequest {{
72- number,
73- author {{
74- avatarUrl,
75- resourcePath,
76- }}
77- }}
78- }},
79- subject {{
80- __typename
81- ... on Issue {{
82- number
83- }}
84- ... on PullRequest {{
85- number
86- }}
87- }}
88- }}
89- }}
90- }}
91- }}" ;
92-
93- private const string CONNECT_AND_DISCONNECT_EVENTS_GRAPHQL_QUERY = @"
94- query ConnectAndDisconnectEvents($repoName: String!, $repoOwner: String!, $issueNumber: Int!, $pageSize: Int!) {{
95- repository(name: $repoName, owner: $repoOwner) {{
96- {0},
97- {1}
98- }}
99- }}" ;
36+ private const string CLOSING_ISSUES_AND_PULLREQUESTS_GRAPHQL_QUERY = @"
37+ query ClosingIssuesAndPullRequests($repoName: String!, $repoOwner: String!, $issueNumber: Int!, $pageSize: Int!) {
38+ repository(name: $repoName, owner: $repoOwner) {
39+ issue(number: $issueNumber) {
40+ title
41+ id
42+ number
43+ url
44+ labels(first: 100) {
45+ nodes {
46+ name
47+ color
48+ description
49+ }
50+ }
51+ author {
52+ login
53+ avatarUrl
54+ resourcePath
55+ }
56+ closedByPullRequestsReferences(includeClosedPrs: true, first: $pageSize) {
57+ nodes {
58+ number
59+ id
60+ title
61+ author {
62+ login
63+ avatarUrl
64+ resourcePath
65+ }
66+ }
67+ }
68+ }
69+ pullRequest(number: $issueNumber) {
70+ number
71+ title
72+ closingIssuesReferences(first: $pageSize) {
73+ nodes {
74+ number
75+ title
76+ author {
77+ login
78+ avatarUrl
79+ resourcePath
80+ }
81+ }
82+ }
83+ }
84+ }
85+ }" ;
10086
10187 private readonly IGitHubClient _gitHubClient ;
10288 private readonly IMapper _mapper ;
@@ -439,13 +425,11 @@ public string GetIssueType(Issue issue)
439425
440426 public async Task < IEnumerable < Issue > > GetLinkedIssuesAsync ( string owner , string repository , Issue issue )
441427 {
442- var graphQLQuery = string . Format ( CultureInfo . InvariantCulture , CONNECT_AND_DISCONNECT_EVENTS_GRAPHQL_QUERY ,
443- string . Format ( CultureInfo . InvariantCulture , CONNECT_AND_DISCONNECT_EVENTS_GRAPHQL_QUERY_FRAGMENT , "issue" ) ,
444- string . Format ( CultureInfo . InvariantCulture , CONNECT_AND_DISCONNECT_EVENTS_GRAPHQL_QUERY_FRAGMENT , "pullRequest" ) ) ;
428+ ArgumentNullException . ThrowIfNull ( issue , nameof ( issue ) ) ;
445429
446430 var request = new GraphQLHttpRequest
447431 {
448- Query = graphQLQuery . Replace ( "\r \n " , string . Empty ) ,
432+ Query = CLOSING_ISSUES_AND_PULLREQUESTS_GRAPHQL_QUERY . Replace ( "\r \n " , string . Empty , StringComparison . OrdinalIgnoreCase ) ,
449433 Variables = new
450434 {
451435 pageSize = PAGE_SIZE ,
@@ -458,50 +442,19 @@ public async Task<IEnumerable<Issue>> GetLinkedIssuesAsync(string owner, string
458442 var graphQLResponse = await _graphQLClient . SendQueryAsync < dynamic > ( request ) . ConfigureAwait ( false ) ;
459443
460444 var rootNode = ( JsonElement ) graphQLResponse . Data ;
461- var issueNode = rootNode . GetJsonElement ( "repository.issue" ) ;
462- if ( issueNode . ValueKind == JsonValueKind . Null || issueNode . ValueKind == JsonValueKind . Undefined )
463- {
464- issueNode = rootNode . GetJsonElement ( "repository.pullRequest" ) ;
465- }
445+ var issueNode = rootNode . GetFirstJsonElement ( new [ ] { "repository.issue" , "repository.pullRequest" } ) ;
466446
467447 if ( issueNode . ValueKind == JsonValueKind . Null || issueNode . ValueKind == JsonValueKind . Undefined )
468448 {
469449 throw new NotFoundException ( $ "Unable to find issue/pull request { issue . PublicNumber } ") ;
470450 }
471451
472- var nodes = issueNode . GetJsonElement ( "timelineItems.nodes" ) ;
473- var sortedNodes = nodes . EnumerateArray ( ) . OrderBy ( n => n . GetJsonElement ( "createdAt" ) . GetDateTime ( ) ) ;
474- var connectedEvents = sortedNodes . Where ( n => n . GetJsonElement ( "__typename" ) . GetString ( ) == "ConnectedEvent" ) . ToArray ( ) ;
475- var disconnectedEvents = sortedNodes . Where ( n => n . GetJsonElement ( "__typename" ) . GetString ( ) == "DisconnectedEvent" ) . ToArray ( ) ;
476-
477- if ( ! connectedEvents . Any ( ) )
478- {
479- return Enumerable . Empty < Issue > ( ) ;
480- }
452+ var nodes = issueNode . GetFirstJsonElement ( new [ ] { "closedByPullRequestsReferences.nodes" , "closingIssuesReferences.nodes" } ) ;
481453
482454 var linkedIssues = new List < Issue > ( ) ;
483- foreach ( var connectEvent in connectedEvents )
455+ foreach ( var node in nodes . EnumerateArray ( ) )
484456 {
485- var linkedIssueNumber = connectEvent . GetJsonElement ( "subject.number" ) . GetInt32 ( ) ;
486- var correspondingDisconnectEvent = disconnectedEvents
487- . FirstOrDefault ( e =>
488- e . GetJsonElement ( "subject.number" ) . GetInt32 ( ) == linkedIssueNumber &&
489- e . GetJsonElement ( "createdAt" ) . GetDateTime ( ) >= connectEvent . GetJsonElement ( "createdAt" ) . GetDateTime ( ) ) ;
490-
491- if ( correspondingDisconnectEvent . ValueKind == JsonValueKind . Null || correspondingDisconnectEvent . ValueKind == JsonValueKind . Undefined )
492- {
493- var linkedIssue = await _gitHubClient . Issue . Get ( owner , repository , linkedIssueNumber ) . ConfigureAwait ( false ) ;
494- linkedIssues . Add ( _mapper . Map < Issue > ( linkedIssue ) ) ;
495- }
496- else if ( correspondingDisconnectEvent . GetJsonElement ( "createdAt" ) . GetDateTime ( ) >= connectEvent . GetJsonElement ( "createdAt" ) . GetDateTime ( ) )
497- {
498- continue ;
499- }
500- else
501- {
502- var linkedIssue = await _gitHubClient . Issue . Get ( owner , repository , linkedIssueNumber ) . ConfigureAwait ( false ) ;
503- linkedIssues . Add ( _mapper . Map < Issue > ( linkedIssue ) ) ;
504- }
457+ linkedIssues . Add ( _mapper . Map < Issue > ( node ) ) ;
505458 }
506459
507460 return linkedIssues ;
0 commit comments