Skip to content

Conversation

iamrajjoshi
Copy link
Collaborator

@iamrajjoshi iamrajjoshi commented Sep 26, 2025

Summary

Implements GitHub issue webhook handler to sync issue assignments between GitHub and Sentry. When a GitHub issue is assigned or unassigned, the webhook automatically updates the corresponding Sentry issue assignment using the external user mapping.

I do have this working E2E, but breaking this into chunks.

The payload we expect looks like:
image
https://docs.github.com/en/webhooks/webhook-events-and-payloads#issues

Changes

  • Added new IssuesEventWebhook handler class to process GitHub issue events
  • Integrated with sync_group_assignee_inbound_by_external_actor to sync assignments to Sentry groups
  • Handles both "assigned" and "unassigned" GitHub webhook events
  • Properly formats GitHub usernames with @ prefix for Sentry compatibility

Technical Details

The webhook handler:

  1. Extracts issue metadata (repository, issue number, assignee) from the GitHub webhook payload
  2. Constructs the external issue key in the format {repo_full_name}#{issue_number}
  3. Calls the existing sync utility to update the Sentry group assignment based on the GitHub assignee

Note: this is disabled from the start since i haven't updated the Github Integration config yet. It will come in a followup.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Sep 26, 2025
@iamrajjoshi iamrajjoshi force-pushed the raj/gh-feat-par/webhook branch 2 times, most recently from 3da0159 to e434468 Compare October 2, 2025 02:00
assignee_name = "@" + assignee_gh_name

# Sync the assignment to Sentry
sync_group_assignee_inbound_by_external_actor(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

do we want to FF this? i am thinking through how we will FF all the features i am adding also per integration and can't think of a clean way to do this.

open to suggestions.

Copy link
Member

Choose a reason for hiding this comment

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

Good call! yes, let's feature flag.

@iamrajjoshi iamrajjoshi marked this pull request as ready for review October 2, 2025 02:02
@iamrajjoshi iamrajjoshi requested a review from a team as a code owner October 2, 2025 02:02
cursor[bot]

This comment was marked as outdated.

repository = event.get("repository", {})
repo_full_name = repository.get("full_name")
issue_number = issue.get("number")
assignee_gh_name = event.get("assignee", {}).get("login")
Copy link
Contributor

Choose a reason for hiding this comment

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

Potential bug: The code will raise an AttributeError when the GitHub webhook payload contains "assignee": null, as it attempts to call .get("login") on a None object.
  • Description: The expression event.get("assignee", {}).get("login") will raise an AttributeError when processing a GitHub webhook for an unassigned issue. The GitHub API sends "assignee": null in this scenario. The event.get("assignee", {}) call correctly returns None instead of the default {}, but the subsequent chained call to .get("login") on this None value causes the exception. This crashes the webhook handler before it reaches the intended validation logic that checks for a falsy assignee_gh_name, preventing the synchronization of issue unassignments from GitHub.

  • Suggested fix: Safely access the nested login value. First, retrieve the assignee object using assignee = event.get("assignee"). Then, conditionally get the login value, for example: assignee_gh_name = assignee.get("login") if assignee else None.
    severity: 0.75, confidence: 0.95

Did we get this right? 👍 / 👎 to inform future reviews.

@iamrajjoshi iamrajjoshi added the Trigger: getsentry tests Once code is reviewed: apply label to PR to trigger getsentry tests label Oct 2, 2025
@iamrajjoshi iamrajjoshi self-assigned this Oct 3, 2025
@sentaur-athena sentaur-athena requested a review from a team October 3, 2025 21:36
@iamrajjoshi iamrajjoshi force-pushed the raj/gh-feat-par/webhook branch from e434468 to 2710e1f Compare October 3, 2025 22:33
@iamrajjoshi iamrajjoshi requested a review from a team as a code owner October 3, 2025 22:33
groups: QuerySet[Group], integration: RpcIntegration | Integration
) -> QuerySet[Group]:
for group in groups:
if not should_sync_assignee_inbound(group.organization):
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i have to do this at this layer because this is where we actually get the organization for the first time 😞

@iamrajjoshi iamrajjoshi force-pushed the raj/gh-feat-par/webhook branch 2 times, most recently from f83000c to 08a6007 Compare October 4, 2025 22:53
@GabeVillalobos GabeVillalobos merged commit 19aa1e5 into getsentry:master Oct 8, 2025
62 of 63 checks passed
Copy link

sentry-io bot commented Oct 10, 2025

Issues attributed to commits in this pull request

This pull request was merged and Sentry observed the following issues:

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 Trigger: getsentry tests Once code is reviewed: apply label to PR to trigger getsentry tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants