findLinkedCopilotPR searches for a PR created by the copilot-swe-agent bot that references the given issue. It queries the issue's timeline for CrossReferencedEvent items from PRs authored by copilot-swe-agent. The createdAfter parameter filters to only return PRs created after the specified time.
(ctx context.Context, client *githubv4.Client, owner, repo string, issueNumber int, createdAfter time.Time)
| 91 | // It queries the issue's timeline for CrossReferencedEvent items from PRs authored by copilot-swe-agent. |
| 92 | // The createdAfter parameter filters to only return PRs created after the specified time. |
| 93 | func findLinkedCopilotPR(ctx context.Context, client *githubv4.Client, owner, repo string, issueNumber int, createdAfter time.Time) (*linkedPullRequest, error) { |
| 94 | // Query timeline items looking for CrossReferencedEvent from PRs by copilot-swe-agent |
| 95 | var query struct { |
| 96 | Repository struct { |
| 97 | Issue struct { |
| 98 | TimelineItems struct { |
| 99 | Nodes []struct { |
| 100 | TypeName string `graphql:"__typename"` |
| 101 | CrossReferencedEvent struct { |
| 102 | Source struct { |
| 103 | PullRequest struct { |
| 104 | Number int |
| 105 | URL string |
| 106 | Title string |
| 107 | State string |
| 108 | CreatedAt githubv4.DateTime |
| 109 | Author struct { |
| 110 | Login string |
| 111 | } |
| 112 | } `graphql:"... on PullRequest"` |
| 113 | } |
| 114 | } `graphql:"... on CrossReferencedEvent"` |
| 115 | } |
| 116 | } `graphql:"timelineItems(first: 20, itemTypes: [CROSS_REFERENCED_EVENT])"` |
| 117 | } `graphql:"issue(number: $number)"` |
| 118 | } `graphql:"repository(owner: $owner, name: $name)"` |
| 119 | } |
| 120 | |
| 121 | variables := map[string]any{ |
| 122 | "owner": githubv4.String(owner), |
| 123 | "name": githubv4.String(repo), |
| 124 | "number": githubv4.Int(issueNumber), //nolint:gosec // Issue numbers are always small positive integers |
| 125 | } |
| 126 | |
| 127 | if err := client.Query(ctx, &query, variables); err != nil { |
| 128 | return nil, err |
| 129 | } |
| 130 | |
| 131 | // Look for a PR from copilot-swe-agent created after the assignment time |
| 132 | for _, node := range query.Repository.Issue.TimelineItems.Nodes { |
| 133 | if node.TypeName != "CrossReferencedEvent" { |
| 134 | continue |
| 135 | } |
| 136 | pr := node.CrossReferencedEvent.Source.PullRequest |
| 137 | if pr.Number > 0 && pr.Author.Login == "copilot-swe-agent" { |
| 138 | // Only return PRs created after the assignment time |
| 139 | if pr.CreatedAt.Time.After(createdAfter) { |
| 140 | return &linkedPullRequest{ |
| 141 | Number: pr.Number, |
| 142 | URL: pr.URL, |
| 143 | Title: pr.Title, |
| 144 | State: pr.State, |
| 145 | CreatedAt: pr.CreatedAt.Time, |
| 146 | }, nil |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 |
no test coverage detected