Skip to content

feat(np): Restore issue action buttons in the MSTeams renderer - #125160

Merged
hobzcalvin merged 4 commits into
gp/msteams_integration_lookupsfrom
gp/msteams_issue_actions
Sep 24, 2026
Merged

hobzcalvin merged 4 commits into
gp/msteams_integration_lookupsfrom
gp/msteams_issue_actions

Conversation

@hobzcalvin

@hobzcalvin hobzcalvin commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Build the same resolve/archive/assign action set as MSTeamsIssueMessageBuilder,
minus the integration id the legacy builder embeds in each action payload,
which the renderer cannot supply because it has no access to the target the
card is being sent to. The webhook resolves the integration from the request
instead.

Cover it with a test that diffs the rendered card against the legacy builder's
across every group state, rather than relying only on the hand-reconstructed
expected card, which can drift in lockstep with a renderer bug.

Look the event up only when the payload carries an id, and let the issue card
builder take a group without one, so a card can offer actions for a group that
has no particular event attached.

Also pass strings, not ints, to Teams as that's their spec (and they coerce it / we were already translating back to ints).

@hobzcalvin
hobzcalvin added this pull request to stack #124985 September 21, 2026 23:30
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Sep 21, 2026
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from cc6eee4 to 13d4dc3 Compare September 21, 2026 23:44
@sentry

sentry Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Sentry Snapshot Testing

Name Added Removed Changed Renamed Unchanged Skipped Status
sentry-frontend
sentry-frontend
0 0 0 0 518 0 ✅ Unchanged

⚙️ sentry-frontend Snapshot Settings

@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch 2 times, most recently from 6d4c47b to 6924651 Compare September 22, 2026 17:48
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch 2 times, most recently from 9d87fcf to 49a94b5 Compare September 22, 2026 20:05
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from 49a94b5 to 36b3d92 Compare September 22, 2026 20:10
@hobzcalvin hobzcalvin changed the title gp/msteams issue actions feat(np): Restore issue action buttons in the MSTeams renderer Sep 22, 2026
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from 36b3d92 to 5355250 Compare September 22, 2026 21:02
@hobzcalvin
hobzcalvin marked this pull request as ready for review September 22, 2026 21:18
@hobzcalvin
hobzcalvin requested review from a team as code owners September 22, 2026 21:19
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from 5355250 to 7745b6a Compare September 22, 2026 23:00

@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 7745b6a. Configure here.

Comment thread src/sentry/notifications/platform/msteams/renderers/issue.py Outdated
Comment thread src/sentry/notifications/platform/msteams/renderers/issue.py
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from 7745b6a to 1e7e260 Compare September 23, 2026 18:01
hobzcalvin added a commit that referenced this pull request Sep 23, 2026
Stacked on #124857 (`gp/add_renderer_registry`). Supersedes #112890,
which could not be reopened after the branch was rebased.

### Summary

Adds `IssueMSTeamsRenderer`, so issue alerts sent through the
notification platform produce the same Adaptive Card the legacy
`MSTeamsIssueMessageBuilder` path produces today. The renderer registers
itself for `(MSTEAMS, ISSUE)` with the registry from the parent PR
rather than adding a `get_renderer` override to the provider.

Original work by @GabeVillalobos; rebased onto current master and
adapted to the registry.

Actions are limited to a single "View Issue" link. The legacy card also
offers resolve/archive/assign, which need the `RpcIntegration` for
action webhook routing; that is coming in #125160

---------

Co-authored-by: Gabe Villalobos <gabriel.villalobos@sentry.io>
Co-authored-by: Cursor <cursoragent@cursor.com>
The card action handler read payload["eventId"] unguarded and returned a 404
once the event lookup came back empty. That happens after _issue_state_change
has already applied, so the action takes effect but the card is never redrawn.

Look the event up only when the payload carries an id, and let the issue card
builder take a group without one, so a card can offer actions for a group that
has no particular event attached.

Co-authored-by: Cursor <cursoragent@cursor.com>
hobzcalvin and others added 3 commits September 23, 2026 11:34
Build the same resolve/archive/assign action set as MSTeamsIssueMessageBuilder,
minus the integration id the legacy builder embeds in each action payload,
which the renderer cannot supply because it has no access to the target the
card is being sent to. The webhook resolves the integration from the request
instead.

Cover it with a test that diffs the rendered card against the legacy builder's
across every group state, rather than relying only on the hand-reconstructed
expected card, which can drift in lockstep with a renderer bug.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adaptive Cards types Input.ChoiceSet choice values as strings, and Teams
returns whatever it was given as a string regardless, which is why the webhook
already coerces the archive count with int(). Emit the archive choices as
strings and narrow InputChoice.value off object so the two cannot diverge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hobzcalvin
hobzcalvin force-pushed the gp/msteams_issue_actions branch from 1e7e260 to e85df64 Compare September 23, 2026 18:34

@Christinarlong Christinarlong 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.

makes sense to me

@hobzcalvin
hobzcalvin merged commit 35f4e4b into master Sep 24, 2026
67 checks passed
@hobzcalvin
hobzcalvin deleted the gp/msteams_issue_actions branch September 24, 2026 17:33
"groupId": self.event.group.id,
"eventId": self.event.event_id,
"groupId": self.group.id,
"eventId": self.event.event_id if self.event else 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.

Can this ever be true? I wonder if we should guard against this case rather than just assuming it can be None.

assert without_integration_id(self.legacy_card()) == without_integration_id(
self.platform_card()
)

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.

Nice, I'm a fan of these tests, though I wonder if we should try to make this more data-driven testing, with different inputs to ensure content parity.

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