This workflow includes several rules that support the scrum framework for agile product development.
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.
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Assign on move'),
guard: function(ctx) {
var issue = ctx.issue;
return issue.isReported && !issue.fields.Assignee && issue.fields.isChanged(ctx.State);
},
action: function(ctx) {
var 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.
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Block ideal days for epics'),
guard: function(ctx) {
var issue = ctx.issue;
return issue.Type.name === ctx.Type.Epic.name && issue.fields.isChanged(ctx.IdealDays);
},
action: function(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.
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Fix parent when all subtasks are resolved'),
guard: function(ctx) {
return ctx.issue.isReported && ctx.issue.becomesResolved;
},
action: function(ctx) {
var processParent = function(issue) {
if (issue.links['subtask of'].isEmpty()) {
return;
}
var parent = issue.links['subtask of'].first();
if (parent && parent.project && !parent.project.isArchived &&
parent.isReported && !parent.isResolved) {
var unresolvedSubtask = parent.links['parent for'].find(function(subtask) {
return subtask.isReported && !subtask.fields.State.isResolved;
});
if (!unresolvedSubtask) {
var field = parent.project.findFieldByName(ctx.State.name);
if (field) {
var value = field.findValueByName(ctx.State.Done.name);
if (value) {
parent.State = value;
workflow.message(workflow.i18n('Automatically set {0} as Done', parent.id));
return parent;
}
}
}
}
};
var 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.
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Open parent task when any subtask is open'),
guard: function(ctx) {
return ctx.issue.isReported && ctx.issue.becomesUnresolved;
},
action: function(ctx) {
var processParent = function(issue) {
if (issue.links['subtask of'].isEmpty()) {
return;
}
var parent = issue.links['subtask of'].first();
if (parent && parent.project && !parent.project.isArchived && parent.isReported && parent.isResolved) {
var field = parent.project.findFieldByName(ctx.State.name);
if (field) {
var value = field.findValueByName(ctx.State.Open.name);
if (value) {
parent.State = value;
workflow.message(workflow.i18n('Automatically reopen {0}', parent.id));
return parent;
}
}
}
};
var 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.
var entities = require('@jetbrains/youtrack-scripting-api/entities');
var workflow = require('@jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
title: workflow.i18n('Block story points for tasks'),
guard: function(ctx) {
return ctx.issue.fields.Type.name === ctx.Type.Task.name && ctx.issue.fields.isChanged(ctx.StoryPoints);
},
action: function(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
}
}
});