Add GraphQL mutation for updating custom lifecycles
What does this MR do and why?
As part of the configurable work item statuses initiative, this MR introduces a GraphQL mutation called lifecycleUpdate for updating custom lifecycles.
The lifecycleUpdate API handles:
- Adding new statuses to the custom lifecycle
- Removing existing statuses from the custom lifecycle
- Updating names of custom statuses
- Updating default custom statuses
- Re-ordering custom statuses
Details
- If a custom lifecycle doesn't exist yet, a new one is created along with its statuses.
- Required updates—such as renaming default statuses—are applied as needed.
- Whenever an array of statuses is provided, the indexes of the default custom statuses (open, closed, and duplicated) must also be included. This ensures the lifecycle has the correct default statuses configured.
- The order of statuses in the array is important, as it determines their position within the lifecycle.
- If an existing status is missing from the provided array, it will be removed—but only if it's not currently in use (i.e., no work items have it set) and it isn't defined as a default status in the lifecycle.
References
- BE: Implement lifecycle and status management APIs
- BE: Add mutation to update lifecycle
- Work Items Custom Status Design Doc
- Configurable Work Item Statuses Epic
Screenshots or screen recordings
Scenario 1 - Create a custom lifecycle and statuses from the system-defined ones
View mutation
mutation UpdateLifecycle($input: LifecycleUpdateInput!) {
lifecycleUpdate(input: $input) {
lifecycle {
id
name
statuses {
id
name
}
defaultOpenStatus {
id
name
}
defaultClosedStatus {
id
name
}
defaultDuplicateStatus {
id
name
}
}
errors
}
}
{
"input": {
"namespacePath": "gitlab-org",
"id": "gid://gitlab/WorkItems::Statuses::SystemDefined::Lifecycle/1",
"statuses": [
{
"id": "gid://gitlab/WorkItems::Statuses::SystemDefined::Status/1",
"name": "To do",
"color": "#737278",
"description": null,
"category": "TO_DO"
},
{
"id": "gid://gitlab/WorkItems::Statuses::SystemDefined::Status/3",
"name": "Done",
"color": "#108548",
"description": null,
"category": "DONE"
},
{
"id": "gid://gitlab/WorkItems::Statuses::SystemDefined::Status/5",
"name": "Duplicate",
"color": "#DD2B0E",
"description": null,
"category": "CANCELLED"
}
],
"defaultOpenStatusIndex": 0,
"defaultClosedStatusIndex": 1,
"defaultDuplicateStatusIndex": 2
}
}
Scenario 2 - Add new custom statuses to an existing custom lifecycle, set new statuses as default ones and reorder all the statuses
View mutation
mutation UpdateLifecycle($input: LifecycleUpdateInput!) {
lifecycleUpdate(input: $input) {
lifecycle {
id
name
statuses {
id
name
}
defaultOpenStatus {
id
name
}
defaultClosedStatus {
id
name
}
defaultDuplicateStatus {
id
name
}
}
errors
}
}
{
"input": {
"namespacePath": "gitlab-org",
"id": "gid://gitlab/WorkItems::Statuses::Custom::Lifecycle/30",
"statuses": [
{
"name": "Ready for development",
"color": "#737278",
"description": null,
"category": "TO_DO"
},
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/127",
"name": "To do",
"color": "#737278",
"description": null,
"category": "TO_DO"
},
{
"name": "Complete",
"color": "#108548",
"description": null,
"category": "DONE"
},
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/128",
"name": "Done",
"color": "#108548",
"description": null,
"category": "DONE"
},
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/129",
"name": "Duplicate",
"color": "#DD2B0E",
"description": null,
"category": "CANCELLED"
}
],
"defaultOpenStatusIndex": 0,
"defaultClosedStatusIndex": 2,
"defaultDuplicateStatusIndex": 4
}
}
Scenario 3 - Remove custom statuses from an existing custom lifecycle, reorder statuses
View mutation
mutation UpdateLifecycle($input: LifecycleUpdateInput!) {
lifecycleUpdate(input: $input) {
lifecycle {
id
name
statuses {
id
name
}
defaultOpenStatus {
id
name
}
defaultClosedStatus {
id
name
}
defaultDuplicateStatus {
id
name
}
}
errors
}
}
{
"input": {
"namespacePath": "gitlab-org",
"id": "gid://gitlab/WorkItems::Statuses::Custom::Lifecycle/30",
"statuses": [
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/130",
"name": "Ready for development",
"color": "#737278",
"description": null,
"category": "TO_DO"
},
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/131",
"name": "Complete",
"color": "#108548",
"description": null,
"category": "DONE"
},
{
"id": "gid://gitlab/WorkItems::Statuses::Custom::Status/129",
"name": "Duplicate",
"color": "#DD2B0E",
"description": null,
"category": "CANCELLED"
}
],
"defaultOpenStatusIndex": 0,
"defaultClosedStatusIndex": 1,
"defaultDuplicateStatusIndex": 2
}
}
How to set up and validate locally
- Enable the
work_item_status_feature_flagfeature flag. - Use the mutations above to test creating a custom lifecycle, adding, updating, removing or reordering custom statuses.
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


