senior
Как создать Workflow Post-Function, Condition, Validator?
Расширения workflow позволяют добавлять автоматическую логику при переходах между статусами в Jira: Post-Function выполняет действие после перехода, Condition определяет видимость перехода, Validator проверяет условия перед выполнением.
Post-Function
Код AutoAssignFunction и Factory
<workflow-function key="auto-assign-function"
class="com.example.plugin.workflow.AutoAssignFunctionFactory">
<function-class>com.example.plugin.workflow.AutoAssignFunction</function-class>
<orderable>true</orderable>
<unique>false</unique>
<resource name="view" type="velocity"
location="templates/workflow/auto-assign-view.vm"/>
<resource name="input-parameters" type="velocity"
location="templates/workflow/auto-assign-input.vm"/>
</workflow-function>
public class AutoAssignFunction implements FunctionProvider {
private static final Logger log = LoggerFactory.getLogger(AutoAssignFunction.class);
@Override
public void execute(Map transientVars, Map args, PropertySet ps) {
MutableIssue issue = (MutableIssue) transientVars.get("issue");
String groupName = (String) args.get("groupName");
if (groupName == null || groupName.isEmpty()) {
log.warn("Имя группы не задано для AutoAssignFunction");
return;
}
GroupManager groupManager = ComponentAccessor.getGroupManager();
Collection<ApplicationUser> members = groupManager.getUsersInGroup(groupName);
if (!members.isEmpty()) {
ApplicationUser assignee = members.iterator().next();
issue.setAssignee(assignee);
log.info("Задача {} назначена на {}", issue.getKey(),
assignee.getDisplayName());
}
}
}
Condition
Пример
public class OnlyReporterCondition extends AbstractJiraCondition {
@Override
public boolean passesCondition(Map transientVars, Map args, PropertySet ps)
throws WorkflowException {
Issue issue = (Issue) transientVars.get("issue");
ApplicationUser currentUser = getCallerUser(transientVars, args);
if (issue == null || currentUser == null) return false;
return currentUser.equals(issue.getReporter());
}
}
Validator
Пример
public class CommentRequiredValidator implements Validator {
@Override
public void validate(Map transientVars, Map args, PropertySet ps)
throws InvalidInputException, WorkflowException {
int minLength = Integer.parseInt(
(String) args.getOrDefault("minLength", "10"));
IssueInputParameters inputParams =
(IssueInputParameters) transientVars.get("issueInputParameters");
String comment = inputParams != null ? inputParams.getComment() : null;
if (comment == null || comment.trim().length() < minLength) {
throw new InvalidInputException(
"Комментарий обязателен (минимум " + minLength + " символов)");
}
}
}
Частые ошибки
- Не вызвать
issue.store()в Post-Function — изменения не сохраняются - Бросать RuntimeException в Condition — нужно возвращать false, а не падать
- Тяжёлая логика в Condition — вызывается при каждом отображении задачи для определения доступных переходов
- Порядок Post-Functions важен — встроенные функции Jira (Update Issue, Generate Events) должны идти после кастомных
Как используется в 2026
- Workflow-расширения — одна из самых востребованных функций DC-плагинов
- В Cloud аналог — Forge jira:workflowCondition, jira:workflowValidator, jira:workflowPostFunction
- ScriptRunner покрывает около 80% типичных workflow-сценариев без написания Java-плагина
На собеседовании: чётко разграничьте три типа: Condition (видимость перехода), Validator (проверка перед), Post-Function (действие после). Factory-класс обязателен — он отвечает за UI конфигурации в admin-панели. В Condition нельзя бросать исключения — только возвращать boolean.