Add an event for requested changes on a merge request

What does this MR do and why?

This MR is the first of five merge requests for https://gitlab.com/gitlab-org/gitlab/-/work_items/634551. It adds a cloud event for a reviewer verdict of requested_changes. Nothing subscribes to the event yet. The next merge requests add the flow trigger action and a fix loop for Duo Developer.

  • Add MergeRequests::RequestedChangesCloudEvent.
  • MergeRequests::UpdateReviewerStateService publishes the event after it sets the requested_changes state and removes the approval of the reviewer.
  • For a verdict of GitLab Duo Code Review, the event data includes review_workflow_id, the review session.
  • The new wip feature flag dap_software_factory controls the publication. It is a generic feature flag for the Software Factory. Its actor is the root namespace, the same actor as ai_flow_trigger_chaining.
Why the event names the review session

The trigger in a later merge request chains the fix run from the review session, as !262581 (merged) does for a review summary. A chained run acts for the human at the root of the chain.

The envelope of a cloud event names a session only for a composite identity (gitlab_duo_workflow_id). Ai::DuoWorkflows::CodeReview::PublishCommentsWorker sets the verdict without the composite identity of the session (skip_composite_identity_passthrough!). So CreateCommentsService passes the session explicitly. It is the same session that CreateCommentsService links to its notes, and the same authorization check applies.

Only server code passes review_workflow_id. No caller of UpdateReviewerStateService passes request parameters to it.

References

Screenshots or screen recordings

Not applicable. The change has no UI.

How to set up and validate locally

  1. In the Rails console, enable the feature flag for the top-level group of a project:

    Feature.enable(:dap_software_factory, Group.find_by_full_path('gitlab-duo'))
  2. Spy on the event store, and request changes as a reviewer:

    mr = Project.find_by_full_path('gitlab-duo/test').merge_requests.opened.last
    reviewer = mr.reviewers.first
    events = []
    Gitlab::EventStore.singleton_class.prepend(Module.new { define_method(:publish) { |e| events << e; super(e) } })
    MergeRequests::UpdateReviewerStateService.new(project: mr.project, current_user: reviewer).execute(mr, 'requested_changes')
    events.map { |e| [e.class.name, e.event_data] }
  3. Confirm that the list includes MergeRequests::RequestedChangesCloudEvent with the IDs of the merge request.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

🤖 Generated with Claude Code

Merge request reports

Loading
Loading