Skip to content

Conversation

@JoshFerge
Copy link
Member

@JoshFerge JoshFerge commented Jan 28, 2026

Summary

Fixes issue where Sentry issues were being resolved prematurely when commits with "Fixes ISSUE-123" were pushed to feature branches. Issues should only resolve when code is actually merged to the default branch (i.e., when a release is created).

Changes

1. Feature flag for gradual rollout

Added organizations:defer-commit-resolution feature flag to control the behavior:

  • Flag ON (new behavior): Commits create GroupLinks and Activity but defer issue resolution to release creation
  • Flag OFF (legacy behavior): Commits immediately resolve issues (current production behavior)

2. Defer commit-based resolution to release creation

Modified resolved_in_commit() to create GroupLinks, Activity, and GroupHistory entries without immediately resolving issues when the feature flag is enabled. Resolution now happens via update_group_resolutions() when a release is created.

Action Flag OFF (Legacy) Flag ON (New)
Create GroupLink
Create Activity
Record GroupHistory
Self-assignment & subscriptions
Resolve issue immediately
Remove from inbox
Send issue_resolved signal

3. Fix Slack/Teams notifications

Created ResolvedInCommitActivityNotification that dynamically chooses the correct message:

  • Commit push path (issue not resolved yet): "will resolve"
  • API resolve path (issue resolved immediately): "marked as resolved in a commit"

4. Fix API duplicate GroupLink error

Changed GroupLink.objects.create() to get_or_create() in process_group_resolution(). This prevents IntegrityError when a user manually resolves an issue via the API using a commit that was already linked by the signal handler.

Files Changed

  • src/sentry/features/temporary.py - Add organizations:defer-commit-resolution feature flag
  • src/sentry/receivers/releases.py - Add feature flag check and conditional resolution logic
  • src/sentry/notifications/notifications/activity/resolved_in_commit.py - New notification class with dynamic message
  • src/sentry/integrations/slack/service.py - Use new notification class for commit activities
  • src/sentry/integrations/msteams/notifications.py - Use new notification class for commit activities
  • src/sentry/api/helpers/group_index/update.py - Use get_or_create for GroupLink
  • tests/sentry/receivers/test_releases.py - Tests for both flag ON and OFF behaviors

Test plan

  • Tests verify flag ON: commits create GroupLinks and GroupHistory but do NOT resolve issues
  • Tests verify flag OFF: commits immediately resolve issues (legacy behavior)
  • Verified existing API tests for "resolve in commit" endpoint still pass
  • Manual: With flag ON, push commit with "Fixes PROJECT-123" to feature branch → issue not resolved
  • Manual: With flag ON, create release with that commit → issue resolved
  • Manual: Slack notification says "will resolve" for commit push
  • Manual: Slack notification says "marked as resolved" for API resolve

Rollout Plan

  1. Deploy with feature flag OFF (no behavior change)
  2. Enable flag for internal Sentry org for testing
  3. Gradually rollout to more organizations
  4. Once stable, enable by default and eventually remove flag

Known issue (pre-existing, not addressed)

update_group_resolutions() in set_commits.py doesn't set resolved_at timestamp when resolving via releases. This is a pre-existing bug that affects all release-based resolutions, not introduced by this PR.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jan 28, 2026
@JoshFerge
Copy link
Member Author

bugbot review

@JoshFerge
Copy link
Member Author

@cursor review

@JoshFerge
Copy link
Member Author

@sentry review

Issues were being resolved immediately when commits with "Fixes ISSUE-123"
were pushed to any branch, including feature branches. This caused issues
to be resolved before the fix was actually merged to the main branch.

This change modifies `resolved_in_commit()` to only create GroupLinks and
Activity entries without immediately resolving issues. Resolution now
happens via `update_group_resolutions()` when a release is created that
includes the commit, ensuring issues are only resolved when code is
actually deployed.
@JoshFerge
Copy link
Member Author

bugbot review

@JoshFerge
Copy link
Member Author

@sentry review

Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@JoshFerge JoshFerge marked this pull request as ready for review January 28, 2026 02:29
Slack/Teams notifications for SET_RESOLVED_IN_COMMIT activities were
using ResolvedActivityNotification which says "marked as resolved" (past
tense). Since commits no longer immediately resolve issues, this was
misleading.

Created ResolvedInCommitActivityNotification that says "will resolve"
(future tense), matching the behavior of ResolvedInPullRequestActivityNotification.
When a commit with "Fixes ISSUE-123" is pushed, resolved_in_commit()
creates a GroupLink without resolving the issue. If a user then tries
to resolve via the API using the same commit, the direct create() would
fail with IntegrityError.

Changed to get_or_create to handle the case where the GroupLink already
exists from the signal handler.
The notification now checks group.status to determine the correct message:
- If issue is RESOLVED (API path): "marked as resolved in a commit"
- If issue is UNRESOLVED (commit push path): "will resolve"

This handles both scenarios where SET_RESOLVED_IN_COMMIT activity is created.
Adds a test that verifies the API handles the case where a GroupLink
already exists when resolving an issue with inCommit. This scenario
occurs when a commit is pushed with "Fixes ISSUE-123" (creating a
GroupLink via resolved_in_commit signal) and then the user manually
resolves via API with the same commit.
Add `organizations:defer-commit-resolution` feature flag to control
whether issues are resolved immediately when commits are pushed (legacy)
or deferred until a release is created (new behavior).

- Flag ON: Creates GroupLinks and Activity but defers resolution
- Flag OFF: Immediately resolves issues (legacy behavior)

This allows gradual rollout of the fix for premature issue resolution.
Copy link
Contributor

@cursor cursor bot left a comment

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.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

The test expects deferred resolution behavior, so it needs the
organizations:defer-commit-resolution flag enabled.

class FindReferencedGroupsTest(TestCase):
@with_feature("organizations:defer-commit-resolution")
def test_resolve_in_commit(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to keep a test without the feature until this is shipped?

# Issue should NOT be resolved immediately - resolution happens via releases
group.refresh_from_db()
assert group.status == GroupStatus.RESOLVED
assert group.status == GroupStatus.UNRESOLVED
Copy link
Member

Choose a reason for hiding this comment

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

Should you also test the logic of the when the commit gets merged into the default branch and then become part of a release?

There's also the case scenario when the commit gets squashed into the default branch and the sha changes. Would a new GroupLink be created and use that instead of the first commit with "Fixes" in the description?

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

4 participants