Skip to content

feat(issues): Add endpoint for pull requests linked to an issue#116744

Merged
scttcper merged 15 commits into
masterfrom
scttcper/issue-linked-pull-requests
Jun 8, 2026
Merged

feat(issues): Add endpoint for pull requests linked to an issue#116744
scttcper merged 15 commits into
masterfrom
scttcper/issue-linked-pull-requests

Conversation

@scttcper

@scttcper scttcper commented Jun 2, 2026

Copy link
Copy Markdown
Member

Linked PRs only live in the activity timeline today This adds a current-state read API so the recent ones can be surfaced somewhere more useful like the issue sidebar.

GET /organizations/{org}/issues/{issue_id}/pull-requests/ returns the 5 most recent PRs linked through GroupLink, with a best-effort status that's live-fetched for GitHub/GHE and unknown everywhere else.

gated behind organizations:issue-details-linked-pull-requests.

part of CORE-207

Linked PRs only lived in the activity timeline, which is historical and
capped. This adds a current-state read API that pulls the high-signal
recent PRs out of activity and into something the sidebar can render.

GET /organizations/{org}/issues/{issue_id}/pull-requests/ returns the
5 most recent PRs linked through GroupLink (pull_request + resolves) in
the last 90 days, newest first. Reuses PullRequestSerializer for the
base fields and decorates each row with dateLinked and a best-effort
status (merged/open/closed/draft/unknown).

Status is live-fetched via the integration client for GitHub/GHE only,
scoped to the PR org so a stale Repository.integration_id can't reach
another org's installation. Anything else degrades to unknown. Nothing
is persisted, status from webhooks can be a follow-up.

Gated behind organizations:issue-details-linked-pull-requests, backend
only for now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 2, 2026
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

scttcper and others added 6 commits June 2, 2026 17:08
mypy flagged the create_linked_pull_request helper for missing param and
return types.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the new group pull requests URL name to the region-pinned list so getsentry URL action checks know how to route it.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
Push the org filter into the pull request lookup instead of filtering the bulk result in Python.

Keeps the GroupLink ordering, just makes the access boundary more obvious.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
Normalize the tiny provider response shape before mapping it to the sidebar PR status.

Keeps the fallback behavior the same, just makes the status code a little easier to read and type.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
Use explicit literal returns for provider PR states so full backend typing can verify the PullRequestStatus response type.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
Keep the linked pull requests endpoint off the legacy unscoped group URL helper so getsentry URL validation does not need a new deprecated action entry.

Regenerate known API URL types after removing the legacy issues/groups pull-requests routes.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
@scttcper scttcper marked this pull request as ready for review June 3, 2026 23:02
@scttcper scttcper requested review from a team as code owners June 3, 2026 23:02

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4a349c2. Configure here.

Comment thread src/sentry/issues/endpoints/group_pull_requests.py
Comment thread src/sentry/issues/endpoints/group_pull_requests.py Outdated
Remove the deprecation decorator from the new endpoint and stop filtering linked pull requests by age. The response remains capped to the five newest resolving links.

Co-Authored-By: Codex GPT-5 <noreply@openai.com>
@linear-code

linear-code Bot commented Jun 3, 2026

Copy link
Copy Markdown

CORE-207

# Conflicts:
#	static/app/utils/api/knownSentryApiUrls.generated.ts

assert response.status_code == 404

def test_empty_response(self) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could add a test that limit of 5 PRs is respected when there are more than 5 that exist

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also when a PR or repo gets deleted?

title="Commit link",
linked_type=GroupLink.LinkedType.commit,
)
Activity.objects.create(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's silly but i think the SET_RESOLVED_IN_PULL_REQUEST Activity is actually irrelevant to issue resolution via PR behavior (although probably still good to include in the test for consistency). more discussion of that here: https://sentry.slack.com/archives/C0B349R63M1/p1779886618643259

}
date_linked_by_pr_id = {link.linked_id: link.datetime for link in group_links}
pull_request_responses: list[LinkedPullRequestResponse] = []
for pull_request in pull_requests:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably doesn't matter in practice but could maybe issue these status requests in parallel if latency becomes a factor

project_id=group.project_id,
linked_type=GroupLink.LinkedType.pull_request,
relationship=GroupLink.Relationship.resolves,
).order_by("-datetime")[:DEFAULT_LIMIT]

@shayna-ch shayna-ch Jun 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the 90 day time frame be specified here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i ended up removing the 90 day time frame, i can clean that up more


installation = integration.get_installation(organization_id=pull_request.organization_id)
client = installation.get_client()
get_pull_request = getattr(client, "get_pull_request", None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we be using the SCM platform to retrieve PRs?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe soon?

@scttcper scttcper enabled auto-merge (squash) June 8, 2026 23:08
@scttcper scttcper merged commit 02ffc5e into master Jun 8, 2026
117 of 119 checks passed
@scttcper scttcper deleted the scttcper/issue-linked-pull-requests branch June 8, 2026 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants