YouTrack Server 2022.1 Help

Scrum

This workflow includes several rules that support the scrum framework for agile product development.

Name

@jetbrains/youtrack-workflow-scrum

Auto-attached

yes

Modules

Assign on move (on-change rule)

Block ideal days for epics (on-change rule)

Fix parent task when all subtasks are resolved (on-change rule)

Open parent task when any subtask is open (on-change rule)

Block story points for tasks (on-change rule)

Use Case

This workflow helps you automate and manage issues when you use a scrum framework for agile product development. The rules in this workflow help you manage assignees, ideal days, story points, subtasks, and sprints.

Modules

This workflow includes five different modules.

Assign on move

When the state of a reported issue is changed and not assigned, the Assignee is set to the currently logged-in user. This rule automatically assigns an issue to the user who moves a card, for example, from an Open state to the In Progress column on a scrum board.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); exports.rule = entities.Issue.onChange({ title: 'Assign on move', guard: (ctx) => { const issue = ctx.issue; return issue.isReported && !issue.fields.Assignee && issue.fields.isChanged(ctx.State); }, action: (ctx) => { const issue = ctx.issue; if (issue.project.findFieldByName(ctx.Assignee.name).findValueByLogin(ctx.currentUser.login)) { issue.fields.Assignee = ctx.currentUser; } }, requirements: { Assignee: { type: entities.User.fieldType }, State: { type: entities.State.fieldType } } });

Block ideal days for epics

This rule prevents users from setting ideal days for epics. Epics represent large features that contain multiple user stories and are usually delivered over a set of sprints. Ideal days are usually set for the tasks and not for epics.

When an user changes the value that is set for the Ideal days field for an issue that is assigned the Epic issue type, this rule checks the new value set for this field. If the Ideal days field is set to anything other than zero or empty, a warning is displayed. The change is rolled back to the previous value.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); exports.rule = entities.Issue.onChange({ title: 'Block ideal days for epics', guard: (ctx) => { const issueFields = ctx.issue.fields; return issueFields.is(ctx.Type, ctx.Type.Epic) && issueFields.isChanged(ctx.IdealDays); }, action: (ctx) => { workflow.check(!ctx.issue.fields.IdealDays, workflow.i18n('Epics can not have ideal days')); }, requirements: { Type: { type: entities.EnumField.fieldType, Epic: {} }, IdealDays: { type: entities.Field.integerType, name: 'Ideal days' } } });

Fix parent task when all subtasks are resolved

This rule helps you manage the state of issues with subtasks (parent tasks). The rule automatically changes the state of a parent task when all subtasks are resolved.

When a reported issue is set to a resolved state, this rule checks the issue for parent tasks. If the issue is a subtask of a parent task, the rule checks the status of all other issues that are linked as subtasks to the parent issue. If all subtasks are set to a resolved state, the state of the parent task is set to Done. A notification is displayed.

The rule then performs the same operation if the parent task is a subtask of another issue.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); exports.rule = entities.Issue.onChange({ title: 'Fix parent when all subtasks are resolved', guard: (ctx) => { return ctx.issue.isReported && ctx.issue.becomesResolved; }, action: (ctx) => { const processParent = function(issue) { if (issue.links['subtask of'].isEmpty()) { return; } const parent = issue.links['subtask of'].first(); if (parent && parent.project && !parent.project.isArchived && parent.isReported && !parent.isResolved) { const unresolvedSubtask = parent.links['parent for'].find(function(subtask) { return subtask.isReported && !(subtask.fields.State && subtask.fields.State.isResolved); }); if (!unresolvedSubtask) { const field = parent.project.findFieldByName(ctx.State.name); if (field) { const value = field.findValueByName(ctx.State.Done.name); if (value) { parent.State = value; if (parent.isVisibleTo(ctx.currentUser)) { workflow.message(workflow.i18n('Automatically set {0} as Fixed', parent.id)); } return parent; } } } } }; let issue = ctx.issue; while (issue) { issue = processParent(issue); } }, requirements: { State: { type: entities.State.fieldType, Done: {} } } });

Open parent task when any subtask is open

This rule helps you manage the state of issues with subtasks (parent tasks). The rule automatically re-opens a parent task when a subtask is set to an unresolved state.

When a reported issue is set to an unresolved state, this rule checks the issue for parent tasks. If the rule finds a parent task that does not belong to an archived project and is set to a resolved state, the state of the parent task is set to Open. A notification is displayed.

The rule then performs the same operation if the parent task is a subtask of another issue.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); exports.rule = entities.Issue.onChange({ title: 'Open parent task when any subtask is open', guard: (ctx) => { return ctx.issue.isReported && ctx.issue.becomesUnresolved; }, action: (ctx) => { const processParent = function(issue) { if (issue.links['subtask of'].isEmpty()) { return; } const parent = issue.links['subtask of'].first(); if (parent && parent.project && !parent.project.isArchived && parent.isReported && parent.isResolved) { const field = parent.project.findFieldByName(ctx.State.name); if (field) { const value = field.findValueByName(ctx.State.Open.name); if (value) { parent.State = value; workflow.message(workflow.i18n('Automatically reopen {0}', parent.id)); return parent; } } } }; let issue = ctx.issue; while (issue) { issue = processParent(issue); } }, requirements: { State: { type: entities.State.fieldType, Open: {} } } });

Block story points for tasks

This rule prevents users from setting story points for tasks. Story points are an arbitrary measure used by scrum teams to estimate the effort required to implement a user story. Story points are usually set for the user stories and not for tasks.

When an user changes the value that is set for the Story points field for an issue that is assigned the Task issue type, this rule checks the new value set for this field. If the Story points field is set to anything other than zero or empty, a warning is displayed. The change is rolled back to the previous value.

const entities = require('@jetbrains/youtrack-scripting-api/entities'); const workflow = require('@jetbrains/youtrack-scripting-api/workflow'); exports.rule = entities.Issue.onChange({ title: 'Block story points for tasks', guard: (ctx) => { const issueFields = ctx.issue.fields; return issueFields.is(ctx.Type, ctx.Type.Task) && issueFields.isChanged(ctx.StoryPoints); }, action: (ctx) => { workflow.check(!ctx.issue.fields.StoryPoints, workflow.i18n('Tasks can not have story points')); }, requirements: { Type: { type: entities.EnumField.fieldType, Task: {} }, StoryPoints: { name: 'Story points', type: entities.Field.integerType } } });
Last modified: 06 July 2022