Reputation: 113
How can I get the Projects and linked issues for a given pull request from github API V3? The pulls
endpoint does not give information on either of them.
In the github's pull requests section's sidebar there are Projects
and Linked issues
mentioned. But I could not find a way to get this information via API calls.
Screenshot of the sidebar for reference
I want to find out which issues a pull request closes on merging successfully.
Upvotes: 6
Views: 4059
Reputation: 718
Find linked PRs from Issues and vice-versa. Not exactly what you're asking, but this was the most relevant SO post I could find.
Fully working Python implementation (PyGithub):
def get_linked_pr_from_issue(issue: Issue) -> PullRequest | None:
"""Check if the given issue has a linked pull request.
This function iterates over the timeline of the issue and checks if there is a 'cross-referenced' event.
If such an event is found, it checks if the source of the event is an issue and if so, it returns the issue as a pull request.
Usage:
issue: Issue = repo.get_issue(number=8)
pr_or_none = check_if_issue_has_linked_pr(issue)
Args:
issue (Issue): The issue to check for a linked pull request.
Returns:
PullRequest: The linked pull request if it exists, None otherwise.
"""
events_pages: PaginatedList[TimelineEvent] = issue.get_timeline()
pg_num = 0
while events_pages.get_page(pg_num):
page = events_pages.get_page(pg_num)
pg_num += 1
for e in page:
if str(e.event) == 'cross-referenced':
if e.source and e.source.issue:
return e.source.issue.as_pull_request()
def get_linked_issue_from_pr(pr: PullRequest) -> Issue | None:
"""Check if the given pull request has a linked issue.
This function iterates over the timeline of the pull request and checks if there is a 'cross-referenced' event.
If such an event is found, it checks if the source of the event is a pull request and if so, it returns the pull request as an issue.
Usage:
pr: PullRequest = repo.get_pull(number=8)
issue_or_none = check_if_pr_has_linked_issue(pr)
Args:
pr (PullRequest): The pull request to check for a linked issue.
Returns:
Issue: The linked issue if it exists, None otherwise.
"""
events_pages: PaginatedList[TimelineEvent] = pr.as_issue().get_timeline()
pg_num = 0
while events_pages.get_page(pg_num):
page = events_pages.get_page(pg_num)
pg_num += 1
for e in page:
if str(e.event) == 'cross-referenced':
if e.source and e.source.issue:
return e.source.issue
Upvotes: 0
Reputation: 71
2022 Update:
There is now a closingIssuesReferences property on pull requests in GraphQL.
pullRequest(number: $number) {
id
closingIssuesReferences (first: 50) {
edges {
node {
id
body
number
title
}
}
}
}
Upvotes: 7
Reputation: 45362
To get the projects with cards linking to a specific pull request you can use Github GraphQL API using this payload :
{
repository(owner: "twbs", name: "bootstrap") {
pullRequest(number: 30342) {
projectCards {
nodes {
project {
name
}
}
}
}
}
}
But for the linked issues I don't think the API is available yet. You can still scrape the list from github.com if the repo is public. The following python script get the list of issues URL using beautifulsoup :
import requests
from bs4 import BeautifulSoup
import re
repo = "twbs/bootstrap"
pr = "30342"
r = requests.get(f"https://github.com/{repo}/pull/{pr}")
soup = BeautifulSoup(r.text, 'html.parser')
issueForm = soup.find("form", { "aria-label": re.compile('Link issues')})
print([ i["href"] for i in issueForm.find_all("a")])
Upvotes: 6
Reputation: 11
(Post this here in case it's helpful for anyone else looking to get Issues linked to a Pull Request)
There's no direct way of getting a list of Issues linked to a Pull Request.
But each Pull Request includes a timeline of events and one of those events is when an Issue gets linked. Using the timeline of events I was able to write a GitHub APIv4 API request and some javascript to get the Issues linked to a PR:
First, here's the GraphQL query:
{
resource(url: "https://github.com/Org/Project/pull/1234") {
... on PullRequest {
timelineItems(itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT], first: 100) {
nodes {
... on ConnectedEvent {
id
subject {
... on Issue {
number
}
}
}
... on DisconnectedEvent {
id
subject {
... on Issue {
number
}
}
}
}
}
}
}
}
If you run this in the GitHub GraphQL Explorer (https://developer.github.com/v4/explorer/), you'll see all the events that an Issue was connected and disconnected to a Pull Request.
Using that query, I pass the response to this code that I wrote for a nodejs app that then determines which Issue is still linked to the Pull Request
const issues = {};
resource.timelineItems.nodes.map(node => {
if (issues.hasOwnProperty(node.subject.number)) {
issues[node.subject.number]++;
} else {
issues[node.subject.number] = 1;
}
});
const linkedIssues = [];
for (const [issue, count] of Object.entries(issues)) {
if (count % 2 != 0) {
linkedIssues.push(issue);
}
}
console.log(issues);
console.log(linkedIssues);
The logic here is as follows:
Get a list of all events on a Pull Request of the type CONNECTED_EVENT and DISCONNECTED_EVENT
Create a map, keyed by Issue number and keep a count of how may times the issue is CONNECTED and DISCONNECTED
From that map, look for keys that have an odd-numbered count, as these are the events that have been CONNECTED that don't have a corresponding DISCONNECTED event.
It's not a super elegant solution, but it solves what I need, which was to find those Linked issues.
Hopefully this helps someone else out
Upvotes: 1
Reputation: 1432
In theory, the following query should return the linked pull request numbers for an issue. However it returns an error message hinting about internal error right now. I opened a ticket at github about it.
(project kode-konveyor/TaskMarket, issue #121)
{
repository(owner: "kode-konveyor", name: "TaskMarket") {
issue(number: 121) {
id
number
title
timelineItems {
__typename
... on IssueTimelineItemsConnection {
nodes {
__typename
... on ConnectedEvent {
source {
__typename
... on PullRequest {
number
}
}
subject {
__typename
... on PullRequest {
number
}
}
}
}
}
}
}
}
}
Upvotes: 0