Include work item status change in the issue close webhook

What does this MR do and why?

When a merge request closes an issue automatically (using a closing pattern), the issue's status changes to Complete as expected, but the workflowcomplete label is not applied and the old label remains. This happens because the close webhook did not include the status change in its changes payload.

This MR fixes that by making Issues::CloseService include the status change in the close webhook. It passes the item's status as old_associations to the existing hook call. This only happens when the work item has a status record and the work_item_status feature is licensed, otherwise nothing changes.

This extends the fix from !243503 (merged), which addressed the same problem for the update path. Auto-close and the /close quick action go through the close path instead, which !243503 (merged) did not cover, so they are fixed here.

Scope: this MR only affects work items that already have a current status record (work items created after the configurable work item statuses feature was enabled last year get one on creation). Some older work items do not have one yet. Creating those missing records (backfilling) is handled separately as part of the broader work item status work, it is not part of this MR.

Next steps

This MR is the backend half. On its own it makes the close webhook correct, but it does not yet change the label. The triage-ops follow-up is gitlab-org/quality/triage-ops!4414 (merged):

  • It makes StatusLabelSyncProcessor react to the close events (issue.close and work_item.close) so the sync also runs on close. This covers both auto-close by a merged MR and the /close quick action. Issue-type work items emit issue.close and other work item types emit work_item.close.
  • Because this MR puts the status change in the close webhook, the processor's existing logic then applies the matching workflow label (workflowcomplete) on close. No other processor changes are needed, the sibling RfhStatusLabelSyncProcessor already reacts to these events through wildcards.
  • gitlab-org/quality/triage-ops!4414 (merged) is gated on this MR being deployed, since it needs changes.status in the close webhook.
  • Reopen is affected the same way (the /reopen quick action does not clear the label). It is handled separately in #632254 (closed) using the same approach (Issues::ReopenService passing the status, plus a matching triage-ops change). It is kept out of this MR to keep it small and focused on close.

References

How to set up and validate locally

Click to expand
  1. Create an issue and give it a status (for example In dev) so it has a current status record.
  2. Set up a project webhook to capture issue hooks.
  3. Close the issue with the /close quick action (add a comment containing /close). Avoid the close button, that goes through the update path, which !243503 (merged) already covered.
  4. Observe that the close webhook now includes the status change under changes.status. Screenshot_2026-10-06_at_3.32.46_pm

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.

Edited by Agnes Slota

Merge request reports

Loading
Loading