YouTrack Standalone 2017.2 Help

Methods and Operations

This page provides a list of the methods and operations that are supported the workflow programming language. The syntax for each method or operation is presented in the format: [name]([data type] parameter): [data type].

The methods and operations that are described on this page are grouped by the object type that they are related to.

To use a method or operation, simply add a dot after any field and write the name of the method or operation. You can continue to add methods and operations to the statement until it generates the desired condition. For example:

when comments.added.isNotEmpty

With code completion, the workflow editor displays a list of possible options that can be used with the preceding element.

  • Methods display the syntax and the object type they are associated with in the schema.

    workflowEditorMethods thumbnail

  • Operations are formatted in dark blue text in the editor and display a description of each available operation.

    workflowEditorOperations thumbnail

Issues

Changes that are applied to an issue are managed by a series of transactions. A transaction is a collection of current changes that are either saved to the database or discarded as a set. When a user edits an issue, a new transaction is started. The transaction is completed when the user clicks the Submit button. The single transaction includes all of the changes that were made to the issue.

Rules that are not executed according to a schedule are processed at the end of a transaction. Scheduled rules and scheduled blocks in state-machine rules are only processed for issues that are already reported or become reported in the current transaction.

The following methods are available for use with issues. See also Issue Fields.

getId(): string

Description

Returns the issue ID.

Example

user.notify("Issue is overdue", "Please, look at the issue: " + issue.getId());

getUrl(): string

Description

Returns the issue URL.

Example

user.notify("Issue is overdue", "Please, look at the issue: " + issue.getUrl());

applyCommand(string command, User runAs): void

Parameters

command

The command that is applied to the issue.

runAs

Specifies the user by which the command is applied. If this parameter is not set, the command is applied on behalf of the current user.

Description

Applies a command to an issue.

Example

applyCommand("for me Critical")

copy(): Issue

Description

Creates a copy of the current issue.

getEditedComments(): sequence<IssueComment>

Description

Gets the comments that are edited in the current transaction. Comments that are added and removed are not considered as edited. These values are represented by the issue.comments.added and issue.comments.removed properties.

addComment(string text, User user): IssueComment

Parameters

text

The text to add to the issue as a comment.

user

Optional. When used, adds the comment on behalf of the specified user.

Description

Adds a comment to the current issue. Sets the issue.comments.changed field to true for the current transaction.

Example

addComment("+1!!!");

clearAttachments(): void

Description

Remove all of the attachments from an issue.

hasTag(string name): Boolean

Parameters

name

The name of the tag to search for.

Description

Checks whether the specified tag is attached to an issue.

Example

hasTag("todo");

isStarred(): Boolean

Description

Checks whether any user has added the star tag to an issue.

addTag(string name): IssueTag

Parameters

name

The name of the tag to attach to the issue.

Description

Add a tag with the specified name to an issue. YouTrack adds the first matching tag that is visible to the current user. If a match is not found, a new private tag is created for the current user. When you use this method to add the star tag to an issue, the current user is added to the list of watchers.

To add a tag that is not visible to the current user, use the applyCommand method instead. Use "add tag <tagName>" for the command parameter and specify the login for the owner of the tag in the runAs parameter.

Example

addTag("todo");

removeTag(string name): IssueTag

Parameters

name

The name of the tag to remove from the issue.

Description

Remove a tag with the specified name from an issue. If the specified tag is not attached to the issue, an exception is thrown.

This method only works when the logged-in user is also the owner of the tag. To remove a tag that is owned by another user, use the applyCommand method instead. Use "remove tag <tagName>" for the command parameter and specify the login for the owner of the tag in the runAs parameter.

Example

removeTag("waiting for reply");

getDuplicateRoot(): Issue

Description

Returns the root issue in a tree of duplicates that are linked to the current issue.

Example

when issue.duplicateCluster.changed || issue.duplicates.changed || issue.is duplicated by.changed { info("Processing duplicate-cluster issue " + issue.getId()); var duplicateRoot = issue.getDuplicateRoot(); if (duplicateRoot != null) { issue.duplicates.clear; if (issue != duplicateRoot) { issue.duplicates.add(duplicateRoot); duplicateRoot.duplicates.clear; } } }

Issue Lifecycle

The following methods are related to the lifecycle of an issue. The lifecycle of an issue consists of the following stages:

Stage

Description

1. Issue is created in this transaction

The issue is still in draft form and does not have an issue ID. The default custom field values are set in this stage.

Rules are not triggered during this stage.

2. Issue is draft

Changes are made after creation but before the issue is reported. This stage includes all edits to the draft issue. Stateless and state-machine rules can be triggered during this stage. Scheduled rules and scheduled blocks in state-machine rules are not processed.

3. Issue becomes reported in this transaction

The issue becomes reported. The issue is submitted and is assigned an ID. All rules including scheduled rules and scheduled blocks in state-machine rules are processed during this stage.

4. Issue is reported

This stage includes all changes made to an issue after it has been reported. All rules including scheduled rules and scheduled blocks in state-machine rules are processed during this stage.

5. Issue is deleted in this transaction

The issue is deleted and is not available after this transaction is complete.

Rules are not triggered during this stage.

isReported(): Boolean

Description

Checks whether an issue is already reported or becomes reported in this transaction (stages 3 and 4). To apply changes to an issue draft (stage 2), use !isReported().

Example

for each dep in depends on { if (dep.isReported()) { assert dep.State.isResolved: l10n ( The issue has unresolved dependencies and thus cannot be set Fixed! ); } }

becomesReported(): Boolean

Description

Checks whether an issue becomes reported in this transaction (stage 3).

Example

when Assignee == null && (((Subsystem.changed || project.changed) && isReported()) || becomesReported()) { if (issue.Subsystem != null) { issue.Assignee = issue.Subsystem.owner; } }

The following methods are related to the issue.resolved property. This property is set based on the values that are stored in a custom field with a state data type. Each value that can be stored in this field has a Resolved property. This property determines whether the issue is considered to be resolved when it assigned a value for this field.

The resolved property is associated with the issue, which means that these methods do not contain references to the custom field.

isResolved(): Boolean

Description

Checks whether an issue is assigned a state that is considered resolved.

Example

when isResolved() { assert !votes.changed: l10n ( Voting for a resolved issue is not allowed. ); }

becomesResolved(): Boolean

Description

Checks whether an issue is assigned a state that is considered resolved in the current transaction.

Example

when issue.isReported() && issue.becomesResolved() && issue.subtask of.isNotEmpty { var parent = issue.subtask of.first; while (parent != null && !parent.isResolved()){ var allSubtasksResolved = true; for each subtask in parent.parent for { if (!subtask.State.isResolved) { allSubtasksResolved = false; break; } } if (allSubtasksResolved) { parent.State = {Done}; message(l10n ( Automatically set{parent.getId()} as Done)); } parent = parent.subtask of.first; } }

becomesUnresolved(): Boolean

Description

Checks whether an issue is assigned a state that is considered unresolved in the current transaction.

Example

when issue.becomesUnresolved() && issue.subtask of.isNotEmpty { var parent = issue.subtask of.first; while (parent != null && !(parent.project.isArchived()) && parent.isResolved()) { parent.State = {Open}; if (parent.Type != null) { message(l10n ( Automatically reopen {parent.Type} {parent.getId()} )); } else { message(l10n ( Automatically reopen {parent.getId()} )); } parent = parent.subtask of.first; } }

Notifications

These methods can be used to send notifications to unregistered users with an email address. To send notifications to existing users, use the notify, notifyAllUsers, sendMail, and sendJabber methods.

If overused, sending email messages to unregistered users can slow down the performance of your YouTrack server, which is not designed for use as a bulk email service. You can configure a system property to set a daily email message limit. For more information, see Configuration Parameters.

getNotificationEmail(): string

Description

Returns the email address that is used to send notifications for the project. If a From address is not set for the project, the From address for the YouTrack server is returned.

Example

when issue.becomesReported() { if (Last message related emails.isNotEmpty) { for each email in Last message related emails.split(" ", preserveAllTokens) { if (email.isNotBlank && !(email.eq(getNotificationEmail(), ignoreCase))) { if (All related emails.isEmpty) { All related emails = email; } else if (!(All related emails.split(" ", preserveAllTokens).contains(email))) { All related emails = All related emails + " " + email; } } } Last message related emails = null; } }

sendMail(string fromPersonal, string fromEmail, string email, string cc, string subject, string body): void

Parameters

fromPersonal

The sender of the email message. If this parameter is not set, the project From address is used. If a From address is not set for the project, the From address for the YouTrack server is used.

fromEmail
email

The email address of the primary recipient.

cc

The email addresses of additional recipients who receive a copy of the message. Multiple email addresses are delimited with commas. If this parameter is not set, the message is sent to a single recipient.

subject

The subject line of the email message

body

The email message text.

Description

Sends an email message with the specified parameters.

Example

when comments.added.isNotEmpty { if (Reporter email != null) { sendMail(Reporter email, "[YouTrack, Commented]", "New comment was added: " + comments.added.first.text)); } }

wikify(string text): string

Parameters

text

The string of text to convert to HTML.

Description

Converts text with wiki markup to HTML. Use this method to send "pretty" notifications to unregistered users.

Example

when comments.added.isNotEmpty { for each comment in comments.added { sendMail("myuser@example.com", "Issue is commented", wikify(comment.text)); } }

Fields

The following operations are available for all fields.

becomes([field] value): Boolean

Parameters

value

The value to check for the specified field.

Description

Checks whether a specific value is set for a field in the current transaction.

Example

when State == {Verified} && !State.becomes({Verified}) { assert comments.added.isEmpty: l10n ( Commenting for fixed and verified issues is disabled. ); }

canBeReadBy(User user): Boolean

Parameters

user

The user for whom the permission to read the field is checked.

Description

Checks whether a specific user has permission to read the field.

canBeUpdatedBy(User user): Boolean

Parameters

user

The user for whom the permission to update the field is checked.

Description

Checks whether a specific user has permission to update the field.

Example

when duplicates.added.isNotEmpty && State != {Duplicate} { if (State.canBeUpdatedBy(loggedInUser)) { State = {Duplicate}; } }

changed(): Boolean

Description

Checks whether a the value of the field is changed in the current transaction.

Example

for each comment in comments.added { text = text + " " + comment.text; } if (description.changed || becomesReported()) { text = text + " " + description; } if (summary.changed || becomesReported()) { text = text + " " + summary; }

oldValue(): [field type]

Description

Returns the previous value of the specified field before an update was applied.

Example

when State == {Verified} && !State.becomes({Verified}) { assert comments.added.isEmpty: l10n ( Commenting for fixed and verified issues is disabled. ); }

required(string message): void

Parameters

message

The message that is displayed to the user that describes the field requirement.

Description

Asserts that a value is set for a field. If a value for the required field is not set, the field is highlighted in the issue and the specified message is displayed.

Example

state Approved { enter { Assignee.required("Please select an assignee"); }

CustomFields

The following method is available for CustomField types. See also CustomField Fields.

getPresentation(): string

Description

Returns the presentation of the value for a custom field.

Example

if (!Type.name.eq(Type.getPresentation(), opts)) { message("The " + Type.getPresentation() + " has been changed."); }

ProjectFields

The following methods are available for ProjectField types. See also ProjectField Fields.

getValuePresentation(Issue issue): string

Parameters

issue

The issue for which the value presentation is returned.

Description

Returns the string presentation of the value that is used for this field in the specified issue.

getBackgroundColor(Issue issue): string

Parameters

issue

The issue for which the background color is returned.

Description

Returns the background color that is used for this field value in the specified issue. Can return null, "write" or a hex color presentation.

getForegroundColor(Issue issue): string

Parameters

issue

The issue for which the foreground color is returned.

Description

Returns the foreground color that is used for this field value in the specified issue. Can return null, "write" or a hex color presentation.

IssueTag

The following methods are available for IssueTag types. You can specify a tag with the literal reference {tag: [tagName]}. See also IssueTag Fields.

getShareGroup(): UserGroup

Description

Returns the UserGroup for whom the tag is visible. If the tag is visible only to its owner, returns null.

Example

var visible = tag.getShareGroup();

getUpdateShareGroup(): UserGroup

Description

Returns the UserGroup by whom the tag is updatable. If the tag is updatable only by its owner, returns null.

Example

var updatable = tag.getUpdateShareGroup();

SavedQuery

The following methods are available for SavedQuery types. You can specify a saved search with the literal reference {savedSearch: [savedSearchName]}. See also IssueTag Fields.

getOwner(): User

Description

Returns the User who created the saved search.

Example

var owner = {savedSearch: IDEA Backlog}.getOwner();

getShareGroup(): UserGroup

Description

Returns the UserGroup for whom the saved search is visible. If the saved search is visible only to its owner, returns null.

Example

var visible = {savedSearch: IDEA Backlog}.getShareGroup();

getUpdateShareGroup(): UserGroup

Description

Returns the UserGroup by whom the saved search is updatable. If the saved search is updatable only by its owner, returns null.

Example

var updatable = {savedSearch: IDEA Backlog}.getUpdateShareGroup();

Sequences

The workflow programming language contains a set of predefined sequences. These sequences include issues, comments, tags, users, issue links, enumerated custom fields, versions, builds, ownedFields, groups, states, static elements for sets of values, and strings. The workflow language does not let you define your own sequence of elements.

When you reference a sequence, you can look up the values that are stored in a specific field for each element. For example, issue.comments returns a sequence of IssueComment elements. You can find the first comment that was added to the issue with the operations added and first. You can then access fields for the first IssueComment, such as text or author. A statement that returns this field would look something like this:

if (comments.added.isNotEmpty) { text = comments.added.first.text;

You can also iterate over the elements in a sequence with a for each statement. For example:

for each version in Fix versions { if (version.releaseDate < now) { project.leader.notify("Overdue version!", "The issue " + getId()+ " has overdue fix version."); } }

The following operations are available for use with all sequence types.

add([sequence type] element): [element type]

Parameters

element

The element to add to the sequence.

Description

Adds an element to the specified sequence.

Example

Fix versions.add({Backlog});

added(): sequence<[element type]>

Description

Returns a sequence of elements that were added to the sequence during the current transaction.

Example

when State == {Verified} && !State.becomes({Verified}) { assert comments.added.isEmpty: l10n ( Commenting for fixed and verified issues is disabled. ); }

clear(): void

Description

Removes all of the elements in the sequence.

Example

relates to.clear;

contains([sequence type] element): Boolean

Parameters

element

The element to check for in the sequence.

Description

Checks whether a sequence contains a specific element.

Example

if (Fix versions.contains({2017.2})){ Priority = {Critical}; }

first(): [element type]

Description

The first element of the sequence. If the sequence is empty, a null value is returned.

Example

when comments.added.isNotEmpty { if (All related emails.isNotEmpty){ var myComment = comments.added.first;

isEmpty(): Boolelan

Description

True if the sequence is empty.

Example

when State == {Duplicate} && duplicates.removed.isNotEmpty { if (duplicates.isEmpty) { State = {Open}; } }

isNotEmpty(): Boolelan

Description

True if the sequence is not empty.

Example

when parent for.added.isNotEmpty { for each subtask in parent for.added { if (subtask.Assignee == null) { subtask.Assignee = Assignee; } } }

last(): [element type]

Description

The last element of the sequence. If the sequence is empty, a null value is returned.

Example

if (curNumber.is(numeric)) { referringIssue = loggedInUser.getIssues(project, "#" + issueID); if (referringIssue.isNotEmpty && referringIssue.first == referringIssue.last) { refers to.add(referringIssue.first);

remove([sequence type] element): [element type]

Parameters

element

The element to remove from the sequence.

Description

Removes an element from the specified sequence.

Example

Fix versions.remove({Next Release});

removed() sequence<[element type]>

Description

Returns a sequence of elements that were removed from the sequence during the current transaction.

Example

var tag = {tag:confirmed}; tags.remove(tag); if (tags.removed.contains(tag)) { message(l10n ( Tag ' {tag.name} ' is removed.));

Projects

The following methods are available for use with projects. See also Project Fields.

getUser(string login): User

Parameters

login

The username of the user.

Description

Returns a user by login. If no such user exists, a null value is returned.

Example

if (created < 2012-12-31 && !isResolved()) { tags.add(project.getUser("root").getSharedTag("obsolete?")); }

isArchived(): Boolean

Description

Checks the current status of a project.

Example

when Assignee.changed { for each subtask in parent for { if (subtask.project.isArchived()) { continue; } if (subtask.Assignee == Assignee.oldValue) { subtask.Assignee = Assignee; } } }

The following operation is available for use with projects.

valuesFor(CustomField field): sequence<[field type]>

Parameters

field

The name of the custom field for which values are returned.

Description

Returns a read-only sequence of values that are used by the custom field in this project.

Example

when parent for.added.isNotEmpty { for each subtask in parent for.added { if (project != subtask.project && issue.project.valuesFor(Fix versions).first != subtask.project.valuesFor(Fix versions).first) { continue; } if (!subtask.isResolved()) { subtask.Fix versions.clear; for each version in Fix versions { subtask.Fix versions.add(version); } } } }

Users

The following methods are available for use with User objects. See also User Fields.

getVisibleName(): string

Description

Returns the full name of the specified user. If the full name is not set, the username is returned.

isBanned(): Boolean

Description

Checks whether the user account is banned.

Example

if (Assignee.isBanned()) { Assignee = null; }

hasRole(string role): Boolean

Parameters

role

The name of role you want to check for.

Description

Checks whether the user has the specified role in any project.

Example

if (loggedInUser.hasRole("Developer")) { Assignee = loggedInUser; }

isInGroup(): string

Description

Checks whether the user is a member of the specified group.

Example

when Assignee.changed && Assignee != null { if (permittedGroup != null && !Assignee.isInGroup(permittedGroup.name)) { message(l10n ( Please take into account that new assignee ' {Assignee.fullName} ' isn't included into the visibility group ' {permittedGroup.name} '!)); } }

createNewIssue(string projectShortName): Issue

Parameters

projectShortName

The ID of the project in which the issue is created.

Description

Creates a new issue in the specified project.

Example

var todoIssue = loggedInUser.createNewIssue(project.shortName); todoIssue.summary = "iPhone :" + issue.summary; todoIssue.tags.add(iOSTag); tags.add(iOSTag);

watchIssue(Issue issue): void

Parameters

issue

The issue to which the user is added as a watcher.

Description

Adds the current user to the issue as a watcher (add Star tag).

Example

if (loggedInUser.isInGroup("developers") && loggedInUser.hasRole("Developer")) { loggedInUser.watchIssue(issue); } else { loggedInUser.unwatchIssue(issue); }

unwatchIssue(Issue issue): void

Parameters

issue

The issue to from which the user is removed as a watcher.

Description

Removes the current user from the list of watchers for the issue (remove Star tag).

Example

if (loggedInUser.isInGroup("developers") && loggedInUser.hasRole("Developer")) { loggedInUser.watchIssue(issue); } else { loggedInUser.unwatchIssue(issue); }

getTag(string tagName, Boolean createIfNotExists): IssueTag

Parameters

tagName

The name of the tag.

createIfNotExists

If true and the specified tag does not exist or is not visible to the user and the user has permission to create tags, a new tag with the specified name is created.

Description

Returns a tag that is visible to the user.

Example

var createIfNotExist = loggedInUser.getSharedTag("iOS") == null; var iOSTag = loggedInUser.getTag("iOS", createIfNotExist);

getSharedTag(string tagName): IssueTag

Parameters

tagName

The name of the tag.

Description

Returns a tag with the specified name that is shared with but not owned by the user. If such a tag does not exist, a null value is returned.

Example

var createIfNotExist = loggedInUser.getSharedTag("iOS") == null; var iOSTag = loggedInUser.getTag("iOS", createIfNotExist);

canVoteIssue(Issue issue): Boolean

Description

Checks whether the user is able to vote for the specified issue.

Example

var user = project.getUser("user"); if (user.canVoteIssue(issue)) { user.voteIssue(issue); }

voteIssue(Issue issue): void

Parameters

issue

The issue to which the vote is added.

Description

Adds a vote on behalf of the user to the issue, if allowed.

Example

>var user = project.getUser("user"); if (user.canVoteIssue(issue)) { user.voteIssue(issue); }

canUnvoteIssue(Issue issue): Boolean

Description

Checks whether the user is able to remove their vote from the specified issue.

unvoteIssue(Issue issue): void

Parameters

issue

The issue from which the vote is removed.

Description

Removes a vote on behalf of the user from the issue, if allowed

notify(string subject, string body, Boolean ignoreNotifyOnOwnChangesSetting)

Parameters

subject

The subject line of the email notification.

body

The message text of the email notification.

ignoreNotifyOnOwnChangesSetting

If false, the message is not sent when changes are performed on behalf of the current user. The corresponding flag is unchecked. Otherwise, the message is sent anyway.

Description

Sends an email notification to the email address that is set in the user profile.

Example

var projectLeader = project.leader; projectLeader.notify("Attention","Please pay attention to " + getId()); projectLeader.sendJabber("Please look at " + getId());

sendMail(string subject, string body): void

Parameters

subject

The subject line text of the email notification.

body

The message text of the email notification.

Description

An alias for notify(subject, body, true)

Example

sendMail(Reporter email, "[YouTrack, Commented]", "New comment was added: " + comments.added.first.text));

sendJabber(string text): void

Parameters

text

The message text for the Jabber notification.

Description

Sends a notification message over Jabber. Similar to notify method, the message won't be sent on own changes and corresponding flag unchecked.

Example

project.leader.sendJabber("Please pay attention to " + getId());

The following operation is available for use with User objects.

getIssues(SavedQuery context, string query): sequence<Issue>

Parameters

context

The name of the saved search to use as the context for the search query. The default context is Everything.

query

The search query. Can be an empty string.

Description

Returns a list of issues based on the specified context and search query.

Example

for each notMyIssue in loggedInUser.getIssues({savedSearch: Reported by me}, "for: -me") { notMyIssue.Assignee = loggedInUser; }

Variations

var issues = project.leader.getIssues(Everything, ""); var issues = project.leader.getIssues({savedSearch: Unassigned in A}, ""); var issues = project.leader.getIssues({savedSearch: Unassigned in A}, "Priority: Critical");

UserGroups

The following methods are available for use with UserGroups. See also UserGroup Fields.

getUsers(): sequence<User>

Description

Returns all of the users who are members of the specified group.

Example

var users = Assignees group.getUsers();

notifyAllUsers(string subject, string body): void

Parameters

subject

The subject line of the email notification.

body

The message text of the email notification.

Description

Sends an email notification to all of the users who are members of the group.

Example

permittedGroup.oldValue.notifyAllUsers("Visibility has been changed", "The visibility group for the issue " + "<a href=\"" + issue.getUrl() + "\">" + issue.getId() + "</a> has been changed to " + permittedGroup.name);
Last modified: 7 March 2019