Skip to content

Conversation

@suejung-sentry
Copy link
Member

@suejung-sentry suejung-sentry commented Dec 30, 2025

Hook up so we handle issue comment including the posting of eyes emoji from within sentry. This is behind an option for github.webhook.issue-comment which decides whether we route flow through this path or the path that forwards to overwatch.

Note that though in theory overwatch at some point also supported review (including posting 👀 ) for pull_request_review and pull_request_review_comment, I tried out these flows and they don't need to be working right now. I think it's fine to maintain parity and just port it over as just the issue comment is how you can trigger the on_command_phrase review.

Closes CW-10

@suejung-sentry suejung-sentry requested review from a team as code owners December 30, 2025 04:47
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Dec 30, 2025
@suejung-sentry suejung-sentry marked this pull request as draft December 30, 2025 04:48
@linear
Copy link

linear bot commented Dec 30, 2025

Copy link
Member

@armenzg armenzg left a comment

Choose a reason for hiding this comment

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

I'm sending some feedback for now. I need to implement something and get back to you.

comment_id: str,
) -> None:
if integration is None:
metrics.incr("seer.code_review.webhook.issue_comment.reaction_missing_integration")
Copy link
Member

Choose a reason for hiding this comment

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

I tend to use a prefix so I can easily create error widgets in Datadog.

class Metrics(enum.StrEnum):
ERROR = "seer.code_review.error"

Copy link
Member Author

Choose a reason for hiding this comment

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

This is really nice. Thanks for the best practice.
Should it be scoped this widely as all of seer.code_review.error, or worth narrowing down the ones I added to seer.code_review_.webhook.issue_comment.error?

client = integration.get_installation(organization_id=organization.id).get_client()
client.create_comment_reaction(repo.name, comment_id, GitHubReaction.EYES)
metrics.incr("seer.code_review.webhook.issue_comment.reaction_added")
except Exception:
Copy link
Member

Choose a reason for hiding this comment

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

You can either let the exception raise and handle it in the caller or you need to return the outcome to the caller and exit.

Image

Copy link
Member Author

Choose a reason for hiding this comment

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

On this one, I was purposely having the helper _add_eyes_reaction_to_comment log and swallow the exception so every caller of the helper wouldn't need to wrap in a try/catch. I would like us to still forward to seer even if for some reason the 👀 posting failed. For example if we hit a rate limit here, but still want the PR review itself to proceed. What do you think?

}

def _enable_code_review(self) -> None:
self.organization.update_option("sentry:enable_pr_review_test_generation", True)
Copy link
Member

Choose a reason for hiding this comment

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

Since we're adding new code, would it make sense to open a PR to add a more meaningful option? That way we can remediate the problem as we're making progress in the Overwatch port. I now see why you asked me about that other ticket.

It's possible this is way more complicated than I assume 😆 .

Copy link
Member Author

Choose a reason for hiding this comment

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

mock_forward.assert_not_called()

@patch("sentry.seer.code_review.webhooks.issue_comment._add_eyes_reaction_to_comment")
@patch("sentry.seer.code_review.webhooks.handlers._forward_to_seer")
Copy link
Member

Choose a reason for hiding this comment

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

For this case, instead of mocking the task scheduling remove this and use with self.tasks():

You will need to mock the function that would attempt to do the reaction.

I like to see closer to full integration testing when dealing with the success case.

Copy link
Member Author

Choose a reason for hiding this comment

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

updated!

Copy link
Member

@armenzg armenzg left a comment

Choose a reason for hiding this comment

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

This is very close. A few more changes and we can merge it.

mock_integration, self.organization, self.repo, "123456789"
)
mock_create_reaction.assert_called_once()
mock_seer.assert_called_once()
Copy link
Member

Choose a reason for hiding this comment

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

@suejung-sentry Calling Seer should not happen since we have not set the option to False (Switching from forwarding to Overwatch to Seer).

There's a bug in this code which I was going to handle in one of my PRs:

make_seer_request(path=SeerEndpoint.SENTRY_REQUEST.value, payload=event_payload)

I will be adding a way to prevent the call to Seer if the options for the specific Github event type is not set to False.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I totally thought we were flipping the other way around, my bad. I'll await your other PR that makes the fix and you can make any changes to this PR as we discussed

Comment on lines +107 to +114
if comment_id:
if not options.get("github.webhook.issue-comment"):
_add_eyes_reaction_to_comment(integration, organization, repo, str(comment_id))

# Import here to avoid circular dependency with handlers
from .handlers import _schedule_task

_schedule_task(event_type, event, organization, repo)
Copy link

Choose a reason for hiding this comment

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

Bug: The _schedule_task function is called unconditionally, causing duplicate processing when the github.webhook.issue-comment option is True.
Severity: HIGH | Confidence: High

🔍 Detailed Analysis

In issue_comment.py, the code checks the github.webhook.issue-comment option. If this option is False, it adds a reaction. However, the call to _schedule_task on line 114 occurs outside of this conditional check, meaning it is executed unconditionally. This causes a task to be scheduled in Sentry even when the option is True, a state intended to forward the event to another service (Overwatch). This results in the event being processed by both Sentry and the other service, leading to conflicting behavior.

💡 Suggested Fix

Move the _schedule_task(...) call inside the if not options.get("github.webhook.issue-comment"): block to ensure it is only executed when this option is False.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/sentry/seer/code_review/webhooks/issue_comment.py#L107-L114

Potential issue: In `issue_comment.py`, the code checks the
`github.webhook.issue-comment` option. If this option is `False`, it adds a reaction.
However, the call to `_schedule_task` on line 114 occurs outside of this conditional
check, meaning it is executed unconditionally. This causes a task to be scheduled in
Sentry even when the option is `True`, a state intended to forward the event to another
service (Overwatch). This results in the event being processed by both Sentry and the
other service, leading to conflicting behavior.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 8054017

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants