Skip to content

feat(workflow_engine): Add support for Issue Status Changes #93489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from

Conversation

saponifi3d
Copy link
Contributor

@saponifi3d saponifi3d commented Jun 12, 2025

Description

Whenever an Issue Group has a new activity, an Activity model is created.

This PR adds a registry to when an activity is created, so we can have a hook into when the model is created.

This also adds a handler for the registry, workflow_issue_status_change. This method will take the Activity, and create a WorkflowEventData object.

All of the conditions marked as WORKFLOW_TRIGGERS can work with Activity | GroupEvent already.

The ACTION_FILTER conditions were updated accordingly, most are just saying they don't know how to be evaluated for now.


Let me know if it'd help to break this PR up for review -- i have a few branches that built up this PR.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 12, 2025
@saponifi3d saponifi3d requested a review from wedamija June 12, 2025 23:34
@saponifi3d saponifi3d requested a review from snigdhas June 12, 2025 23:34
Copy link

codecov bot commented Jun 12, 2025

❌ 12 Tests Failed:

Tests completed Failed Passed Skipped
26537 12 26525 222
View the top 3 failed test(s) by shortest run time
tests.sentry.models.test_activity.ActivityTest::test_skips_status_change_notifications_if_disabled
Stack Traces | 2.02s run time
#x1B[1m#x1B[.../sentry/models/test_activity.py#x1B[0m:343: in test_skips_status_change_notifications_if_disabled
    _ = Activity.objects.create_group_activity(
#x1B[1m#x1B[.../sentry/models/activity.py#x1B[0m:107: in create_group_activity
    handler(activity)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:358: in workflow_issue_status_change
    process_workflows(workflow_event_data)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:258: in process_workflows
    organization = detector.project.organization
#x1B[1m#x1B[31mE   AttributeError: 'NoneType' object has no attribute 'project'#x1B[0m
tests.sentry.integrations.tasks.test_sync_status_inbound.TestSyncStatusInbound::test_resolve_default
Stack Traces | 2.7s run time
#x1B[1m#x1B[.../integrations/tasks/test_sync_status_inbound.py#x1B[0m:124: in test_resolve_default
    sync_status_inbound(
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/celery/local.py#x1B[0m:182: in __call__
    return self._get_current_object()(*a, **kw)
#x1B[1m#x1B[31msrc/sentry/celery.py#x1B[0m:104: in __call__
    return super().__call__(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../celery/app/task.py#x1B[0m:411: in __call__
    return self.run(*args, **kwargs)
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:186: in _wrapped
    result = func(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:256: in wrapped
    retry_task(exc)
#x1B[1m#x1B[.../sentry/taskworker/retry.py#x1B[0m:57: in retry_task
    current_task.retry(exc=exc)
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../celery/app/task.py#x1B[0m:727: in retry
    raise_with_context(exc or Retry('Task can be retried', None))
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:246: in wrapped
    return func(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:268: in wrapper
    response = function(*args, **kwargs)
#x1B[1m#x1B[.../integrations/tasks/sync_status_inbound.py#x1B[0m:267: in sync_status_inbound
    Group.objects.update_group_status(
#x1B[1m#x1B[.../sentry/models/group.py#x1B[0m:484: in update_group_status
    activity = Activity.objects.create_group_activity(
#x1B[1m#x1B[.../sentry/models/activity.py#x1B[0m:107: in create_group_activity
    handler(activity)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:358: in workflow_issue_status_change
    process_workflows(workflow_event_data)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:258: in process_workflows
    organization = detector.project.organization
#x1B[1m#x1B[31mE   AttributeError: 'NoneType' object has no attribute 'project'#x1B[0m
tests.sentry.integrations.tasks.test_sync_status_inbound.TestSyncStatusInbound::test_resolve_no_releases
Stack Traces | 2.8s run time
#x1B[1m#x1B[.../integrations/tasks/test_sync_status_inbound.py#x1B[0m:295: in test_resolve_no_releases
    sync_status_inbound(
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/celery/local.py#x1B[0m:182: in __call__
    return self._get_current_object()(*a, **kw)
#x1B[1m#x1B[31m.venv/lib/python3.13.../site-packages/sentry_sdk/utils.py#x1B[0m:1809: in runner
    return original_function(*args, **kwargs)
#x1B[1m#x1B[31msrc/sentry/celery.py#x1B[0m:104: in __call__
    return super().__call__(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../celery/app/task.py#x1B[0m:411: in __call__
    return self.run(*args, **kwargs)
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:186: in _wrapped
    result = func(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:256: in wrapped
    retry_task(exc)
#x1B[1m#x1B[.../sentry/taskworker/retry.py#x1B[0m:57: in retry_task
    current_task.retry(exc=exc)
#x1B[1m#x1B[.../sentry/silo/base.py#x1B[0m:158: in override
    return original_method(*args, **kwargs)
#x1B[1m#x1B[31m.venv/lib/python3.13.../celery/app/task.py#x1B[0m:727: in retry
    raise_with_context(exc or Retry('Task can be retried', None))
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:246: in wrapped
    return func(*args, **kwargs)
#x1B[1m#x1B[.../sentry/tasks/base.py#x1B[0m:268: in wrapper
    response = function(*args, **kwargs)
#x1B[1m#x1B[.../integrations/tasks/sync_status_inbound.py#x1B[0m:267: in sync_status_inbound
    Group.objects.update_group_status(
#x1B[1m#x1B[.../sentry/models/group.py#x1B[0m:484: in update_group_status
    activity = Activity.objects.create_group_activity(
#x1B[1m#x1B[.../sentry/models/activity.py#x1B[0m:107: in create_group_activity
    handler(activity)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:358: in workflow_issue_status_change
    process_workflows(workflow_event_data)
#x1B[1m#x1B[.../workflow_engine/processors/workflow.py#x1B[0m:258: in process_workflows
    organization = detector.project.organization
#x1B[1m#x1B[31mE   AttributeError: 'NoneType' object has no attribute 'project'#x1B[0m

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

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.

1 participant