How we implemented Jira-like automation in a Russian product


Hello everyone, my name is Alexey – I am the head of the EvaTeam integration department. This article is about how the automation setup is implemented in EvaProject – Russian analogue of Jira. It talks about what we had to face when moving from Jira, and how we implemented the functionality in our system.

About automation in Jira

Basic automation in Jira is, frankly, very poor. It is suitable only for small and undemanding teams. In fact, more or less full-fledged automation can only be obtained using extensions and plugins. For example, there is an official Jira Automation extension that allows you to add your own rules. But working with him is also not obvious and he chatters like a sailor in a boat. Fully works in the premium Cloud-version. Recently built into the Data Center version. And for the Server tariff, it is installed only as a separate extension with the ability to extend it until February 2024.

There are also plugins like ScriptRunner. Included in the top most popular extensions in the marketplace and allows you to build processes and automation. This is a really powerful thing that can help organize everything that happens in a company. But it is installed separately and requires an additional payment.

In general, Jira has rich automation through plugins and extensions. You can set up anything: from changing the artist when the status of a task changes, to turning on the coffee machine every day at 9 am.

Therefore, people face difficulties when switching to Russian software. There are few systems that will also allow you to flexibly automate processes, but we are not cowardly either. I’m talking about how this functionality works in our system.

Transition Automation

The automation was based on the usual Jira settings, as well as popular plugins. At the moment, much of this has already been implemented in EvaProject, but we still receive many requests for specific settings that we are constantly adding. The main thing that has been done is the architectural possibilities for further development in the direction of replacing Atlassian.

To set up the logic of business processes, we use the classic 3 whales of automation:

  1. Transition conditions;

  2. Validators;

  3. Actions.

Transition conditions

Transition conditions are processed for visual display in the status list. They define visibility. If the condition for displaying the transition is true, then it will be displayed in the status list. For example, you can configure the status “DONE” to appear only when a comment has been left in the task.

Status display when condition is met "Left a comment"

Status display when “Comment left” condition is met

Validator

These are additional conditions for statuses. If the validator condition is not met, an error occurs when switching to a certain status. The validator fixes why the error occurred and displays an informative window with the reason for its occurrence.

A warning window appears when a condition is not met

A warning window appears when a condition is not met

Used to create additional logic when making transitions. An example of setting up an error message that the user receives when certain conditions are triggered:

Validator setup

Validator setup

Validator examples.

For example, we need to add a condition so that it is not possible to change the status if the current time is more than the deadline, or change the status outside of working hours (for example, to take on work).

Actions

This is exactly what will happen in the system after the status change. The action does not impose additional conditions on the display and status change, but is performed after the transition from one application status to another.

In addition to the preset options for transition settings, a more flexible bzPython tool is also available, which is an analogue of the ScriptRunner plugin in Jira.

bzPyton

Using bzPyton, you can implement absolutely any kind of automation.

Example of adding bzPython

Example of adding bzPython

bzPyton is an internal business interpreter. The task in which a certain transition is made is passed to the interpreter in the self variable, which is an object of the CmfTask class and contains all information about this task, that is, all fields and methods of the CmfTask object. We can change the status, we can change the alarm clock and any other fields that are in the CmfTask model. The list of available fields can be found in the official documentation.

For example, let’s make the user who changed the status of the task become responsible for the task. Add a new action for the status, Action Type – bzPyton. In the interpreter window we write:

self.responsible = g.current_user

In this example:

self.responsible – responsible for the current task;

g.current_user – a special variable that contains the current user who is making the transition.

After the end of the transition, the user who made this transition will automatically be assigned the responsibility for the task.

Popular patterns for implementing automation using bzPyton can be found in the official documentation (https://docs.evateam.ru/docs/docs/DOC-000193#primery-bz-python)

For transitions, the amount of code is usually small. You can use larger scripts in Triggers or Cron.

And one more bzPython example for the validator. “Only allow the user who is the executor for the task to perform the transition”:

if self.responsible != g.current_user:
    return False

triggers

Triggers can be executed when any events occur in the system. For example, someone moved a task in a kanban to the next stage, a new worker arrived, or any other event. We can assign a trigger to it.

Adding an event for a trigger

Adding an event for a trigger

Events for triggers:

  1. Commenting;

  2. Creation;

  3. Removal;

  4. Preservation;

  5. Update.

Any of these events can be used with models:

  1. Task (CmfTask);

  2. Document (CmfDocument);

  3. List(CmfList);

  4. Deal (CmfDeal).

To create a new trigger, you need to go to the settings, select the administrator mode, click “Automation triggers”.

In the “Name” field, enter the desired name for the trigger and click “Add”.

Click “Edit”, a window with trigger parameters will open.

Trigger setting

Trigger setting

There are already preset filters. These are “Filter by logical type of object”, “Filter by type of activity”, “Filter by business process scheme”. For more flexible filter settings, it is possible to use the bzPyton interpreter.

A detailed description of the settings is contained in the official documentation (https://docs.evateam.ru/docs/docs/DOC-000238#avtomatizacziya-triggery)

Let’s try triggers.

Task for trigger: Automation to create a child task with the type “Subtask”.

To do this, select the following settings:

Add this code:

task_code = self.name.value
relation_task = models.CmfTask.get(code=task_code, fields=['name', 'cf_custom_field_1'])
if relation_task:
# Меняем имя дочерней задачи
self.name = f'{task_code} - {relation_task.name}'
# Получаем кастомное поле из второй задачи
custom_1 = relation_task.cf_custom_field_1
# Меняем текст дочерней задачи
self.text = f'<p>Это текст первой строки. Кастом поле-{custom_1}</p>\n<p>Это текст второй строки</p>'
# Получаем нужный тип связи. В данном случае тип связи "Взаимная" - "Относится к"
relation_type = models.CmfRelationType.get(code="system.link")
# Создаем связь между второй задачей и новой созданной(дочерней)
new_rel = models.CmfRelationOption(out_link=self, in_link=relation_task, relation_type=relation_type)
new_rel.save()

And the logic of the script looks like this:

  1. The script is executed if you press the “Add child task” button in the main task and write another already created task in the name code.

  2. The second task will be found by the code field. The fields name and cf_custom_field_1 will be obtained from this task.

  3. The received fields from the second task will be registered in the child one.

  4. A link of type system.link (Mutual) is created between the child and the second task.

  5. The trigger settings indicate “Event: Creation”, “Filter by the logical type of the object – Subtask”.

Cron

It is possible to automate the operation of the system not only by certain actions by users, but also by time. For this there is a special tool-scheduler. With it, for example, you can remove completed tasks from the list of tasks, or set up periodic cleaning of the archive.

You can also create a timed action in the settings in administrator mode. To do this, select “Cron Automation”. Create a new rule and proceed to editing:

Cron setup window

Cron setup window

Executable tasks for Cron do not contain the self variable. Scheduled objects must be found in the database according to certain criteria. For example, according to the schedule, you can find all tasks that have an expired alarm and change their status. That is, with the help of Cron, automation is usually performed on a large list of tasks that need to be processed once in a certain period of time.

Rules for filling the “Cron Expression” field

The execution time is specified by five columns separated by spaces: minutes (0-59), hours (0-23), days of the month (1-31), months (1-12) and day of the week (0-7). Values ​​can be in the form of numbers, ranges, or ““. Filling examples:

5 0 * * * – executed every day at 0:00 5 minutes; 0-59 * * * * – performed every minute;/5 * * * * – runs every five minutes;
5 4 * * sun – performed at 4:05 on Sunday;

Consider an example. We need to find every day all the tasks whose status has not changed for 7 days, automatically close them and send a notification to the owner of the task.

from datetime import timedelta
# Находим нужный workflow
wf = models.CmfWorkflow.get(code="WF-000005")
# Статус закрыто в нужном workflow
status_closed = models.CmfStatus.get(code="closed", workflow=wf)
seven_days_ago = g.now - timedelta(days=7)
# Находим задачи, у которых статус не менялся 7 дней
tasks = models.CmfTask.list(filter=['status_modified_at', '<=', seven_days_ago])
for task in tasks:
task.status = status_closed
task.save()
# Отправляем сообщение владельцу задачи
models.CmfNotify.place_notify(obj=task, person_id=task.cmf_owner.id.value,
msg=f'Заявка {task.code} отмечена как выполненная автоматически', text="Заголовок")

In addition to the three automation options, EvaProject also has Webhook and Git. Basic automation options, thanks to bzPyton, have maximum flexibility. Specific descriptions of the fields can be found in the documentation, or contact technical support.

The built-in interpreter supports syntax highlighting and also has tooltips for available commands. For example, if after self. press the letter r, then we will see all the possible options. All the names are “speaking”, that is, by the name you can understand what kind of function or variable it is.

End

In the next article I will tell you how we helped to set up automation using the example of one large company. Well, this is still the minimum part of the implemented and planned functionality. We constantly receive information from customers about how they “interestingly” used Jira and continue to add features for automation.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *