From 42b102213aec3f3611c4ca219cb208fe703bc729 Mon Sep 17 00:00:00 2001 From: "nikita.ryabchenko" Date: Fri, 6 Feb 2026 16:38:31 +0300 Subject: [PATCH 1/6] docs: add user guide for store (BPMN process task responses) - Add processes-store.md and processes-store.ru.md with usage guide for storing and referencing task responses via slugs and placeholders - Document temporary response exclusion from store - Link to store doc from admin processes section Co-authored-by: Cursor --- content/documentation/admin/processes.ru.md | 4 + content/documentation/user/processes-store.md | 82 +++++++++++++++++++ .../documentation/user/processes-store.ru.md | 82 +++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 content/documentation/user/processes-store.md create mode 100644 content/documentation/user/processes-store.ru.md diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index b684b57..54d8157 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -88,6 +88,10 @@ moduleStatus: experimental Конфигурация и использование параметров процесса описаны в разделе [шаблонизация](../user/templating.html#параметры-процесса). +### Хранилище результатов задач (store) + +Результаты выполненных задач можно передавать в последующие шаги процесса: ответ действия сохраняется под слагом элемента задачи, а в конфигурации следующих действий используются плейсхолдеры. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store.html). + ## Запуск процесса ### Ручной запуск diff --git a/content/documentation/user/processes-store.md b/content/documentation/user/processes-store.md new file mode 100644 index 0000000..e10351f --- /dev/null +++ b/content/documentation/user/processes-store.md @@ -0,0 +1,82 @@ +--- +title: Store for actions in BPMN — usage guide +menuTitle: Store (BPMN) +d8Edition: ee +moduleStatus: experimental +--- + +This document describes how to use the **store** in BPMN processes: how task responses are saved under a slug and how later tasks can reference them in action configuration via placeholders. + +## 1. What is the store? + +The store is a key–value map **per process instance**. It holds the **response payloads** of completed tasks, each under a key equal to that task element's **slug**. Only the **action response** (the object returned by the action) is written to the store; the request body is not. + +- **One store per process instance:** each run of a process has its own store. Another instance of the same process has a different store. +- **Key = task slug:** when a task finishes successfully, its action response is stored under the slug of that task element. +- **Read via placeholders:** in action configuration (URL, headers, body, etc.) you use Go-style template placeholders to read from the store. + +## 2. How it works + +### 2.1. Task element slug + +Each task element in the process has a **slug** (e.g. `create-project`, `deploy-step`). The slug must be unique within the process and is used as the store key for that task's response. + +### 2.2. Writing to the store + +When a task completes successfully, the engine saves that action's **response** into the instance store under the task's slug. No separate "store key" field is used; the slug is the key. If a **temporary response** is used, that response is not written to the store. + +### 2.3. Reading from the store + +When an action is prepared (e.g. before it runs), the current store is passed as process context. Any string field in the action configuration that supports placeholders can use store placeholders. Missing slugs or fields render as **empty string** and do **not** fail the action. + +## 3. How to use + +### 3.1. Set the slug on task elements + +In the process editor, for each task element that should expose its result to later steps: + +- Set the **Slug** field (e.g. `create-project`, `fetch-order`, `deploy-step`). +- Slug rules: required for tasks that need to be referenced from the store; typically 3–64 characters; use a format like `lowercase-with-hyphens`. + +Slugs must be unique among task elements in the same process. + +### 3.2. Reference the store in action configuration + +In any **later** action (in the same process instance), use Go template placeholders: + +- **Syntax:** `{{ .store.. }}` +- **Nested fields:** `{{ .store... }}` + +`` is the task element slug; `` (and optional ``) are keys from that task's action response. + +#### Examples + +- Use the ID from a "create project" task in a later request: + +```yaml +url: "https://api.example.com/projects/{{ .store.create-project.id }}/deploy" +``` + +- Use multiple store entries in one action: + +```yaml +headers: + X-Project-Id: "{{ .store.create-project.id }}" + X-Job-Id: "{{ .store.deploy-step.jobId }}" +body: | + {"ref": "{{ .store.previous-step.ref }}"} +``` + +- Nested field (if the response is an object with nested data): + +```yaml +projectId: "{{ .store.create-project.result.projectId }}" +``` + +### 3.3. Behavior when data is missing + +- If a **slug** is not in the store (e.g. the task has not run yet or failed), `{{ .store.. }}` is replaced with an **empty string**. +- If a **field** is missing in the response under that slug, the placeholder also renders as **empty string**. +- The action is **not** failed because of missing store data; only the placeholder output is empty. + +You can safely reference store keys that may not exist; the request will still be sent, with empty values where the store had no data. diff --git a/content/documentation/user/processes-store.ru.md b/content/documentation/user/processes-store.ru.md new file mode 100644 index 0000000..3b5b561 --- /dev/null +++ b/content/documentation/user/processes-store.ru.md @@ -0,0 +1,82 @@ +--- +title: Хранилище (store) для действий в BPMN — руководство +menuTitle: Store (BPMN) +d8Edition: ee +moduleStatus: experimental +--- + +В этом разделе описано, как пользоваться **хранилищем (store)** в процессах BPMN: как ответы задач сохраняются под слагом и как последующие задачи могут обращаться к ним в конфигурации действия через плейсхолдеры. + +## 1. Что такое хранилище (store)? + +Хранилище — это ключ–значение **для каждого экземпляра процесса**. В нём хранятся **ответы** завершённых задач, каждый под ключом, равным **слагу** элемента задачи. В хранилище записывается только **ответ действия** (объект, возвращаемый действием); тело запроса не сохраняется. + +- **Одно хранилище на экземпляр процесса:** у каждого запуска процесса своё хранилище. Другой экземпляр того же процесса имеет другое хранилище. +- **Ключ = слаг задачи:** при успешном завершении задачи ответ действия сохраняется под слагом этого элемента задачи. +- **Чтение через плейсхолдеры:** в конфигурации действия (URL, заголовки, тело запроса и т.д.) можно использовать плейсхолдеры в стиле Go-шаблонов для чтения из хранилища. + +## 2. Как это работает + +### 2.1. Слаг элемента задачи + +У каждого элемента задачи в процессе есть **слаг** (например, `create-project`, `deploy-step`). Слаг должен быть уникален в рамках процесса и используется как ключ в хранилище для ответа этой задачи. + +### 2.2. Запись в хранилище + +Когда задача успешно завершается, движок сохраняет **ответ** действия в хранилище экземпляра под слагом задачи. Отдельное поле «ключ хранилища» не используется; ключом является слаг. Если используется **временный ответ**, он не попадает в хранилище. + +### 2.3. Чтение из хранилища + +При подготовке действия (например, перед запуском) текущее хранилище передаётся в контексте процесса. Любое строковое поле в конфигурации действия, поддерживающее плейсхолдеры, может использовать плейсхолдеры хранилища. Отсутствующие слаги или поля подставляются как **пустая строка** и **не** приводят к ошибке действия. + +## 3. Как использовать + +### 3.1. Задать слаг у элементов задачи + +В редакторе процесса для каждой задачи, результат которой должен быть доступен последующим шагам: + +- Заполните поле **Слаг** (например, `create-project`, `fetch-order`, `deploy-step`). +- Правила слага: обязателен для задач, на которые нужно ссылаться из хранилища; обычно 3–64 символа; рекомендуется формат вроде `lowercase-with-hyphens`. + +Слаги должны быть уникальны среди элементов задач в одном процессе. + +### 3.2. Ссылка на хранилище в конфигурации действия + +В любом **последующем** действии (в том же экземпляре процесса) используйте плейсхолдеры Go-шаблонов: + +- **Синтаксис:** `{{ .store.. }}` +- **Вложенные поля:** `{{ .store... }}` + +`` — слаг элемента задачи; `` (и при необходимости ``) — ключи из ответа действия этой задачи. + +#### Примеры + +- Использовать ID из задачи «создать проект» в следующем запросе: + +```yaml +url: "https://api.example.com/projects/{{ .store.create-project.id }}/deploy" +``` + +- Использовать несколько записей хранилища в одном действии: + +```yaml +headers: + X-Project-Id: "{{ .store.create-project.id }}" + X-Job-Id: "{{ .store.deploy-step.jobId }}" +body: | + {"ref": "{{ .store.previous-step.ref }}"} +``` + +- Вложенное поле (если ответ — объект с вложенными данными): + +```yaml +projectId: "{{ .store.create-project.result.projectId }}" +``` + +### 3.3. Поведение при отсутствии данных + +- Если **слаг** отсутствует в хранилище (например, задача ещё не выполнялась или завершилась с ошибкой), `{{ .store.. }}` подставляется как **пустая строка**. +- Если **поле** отсутствует в ответе по этому слагу, плейсхолдер также подставляется как **пустая строка**. +- Действие **не** завершается ошибкой из-за отсутствующих данных в хранилище; пустым будет только результат подстановки плейсхолдера. + +Можно безопасно ссылаться на ключи хранилища, которых может не быть; запрос всё равно будет отправлен, с пустыми значениями там, где данных в хранилище не было. From 0fe2af73589d11b89e8ef0c1ff8985004ad5ef83 Mon Sep 17 00:00:00 2001 From: "nikita.ryabchenko" Date: Fri, 6 Feb 2026 16:47:26 +0300 Subject: [PATCH 2/6] fix: use trailing slash URL for processes-store link (Hugo pretty URLs) --- content/documentation/admin/processes.ru.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index 54d8157..3af68e9 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -90,7 +90,7 @@ moduleStatus: experimental ### Хранилище результатов задач (store) -Результаты выполненных задач можно передавать в последующие шаги процесса: ответ действия сохраняется под слагом элемента задачи, а в конфигурации следующих действий используются плейсхолдеры. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store.html). +Результаты выполненных задач можно передавать в последующие шаги процесса: ответ действия сохраняется под слагом элемента задачи, а в конфигурации следующих действий используются плейсхолдеры. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store/). ## Запуск процесса From a23418d8a64a52c7c36d6170fb7f60f9821b46cf Mon Sep 17 00:00:00 2001 From: "nikita.ryabchenko" Date: Fri, 6 Feb 2026 16:51:07 +0300 Subject: [PATCH 3/6] fix: use trailing slash for internal doc links (link check) Co-authored-by: Cursor --- content/documentation/admin/processes.ru.md | 2 +- content/documentation/admin/workflows.ru.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index 3af68e9..b6f2ec8 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -86,7 +86,7 @@ moduleStatus: experimental На вкладке `Параметры` настраиваются параметры процесса, которые могут использоваться во всех действиях процесса. -Конфигурация и использование параметров процесса описаны в разделе [шаблонизация](../user/templating.html#параметры-процесса). +Конфигурация и использование параметров процесса описаны в разделе [шаблонизация](../user/templating/#параметры-процесса). ### Хранилище результатов задач (store) diff --git a/content/documentation/admin/workflows.ru.md b/content/documentation/admin/workflows.ru.md index 85df7e1..9bac1dd 100644 --- a/content/documentation/admin/workflows.ru.md +++ b/content/documentation/admin/workflows.ru.md @@ -28,4 +28,4 @@ moduleStatus: experimental ### Параметры сценария -Конфигурация и использование параметров сценария описаны в разделе [шаблонизация](../user/templating.html#параметры-сценария). +Конфигурация и использование параметров сценария описаны в разделе [шаблонизация](../user/templating/#параметры-сценария). From caa8e183fa65805051c562711dc851ccd9f33ba9 Mon Sep 17 00:00:00 2001 From: "nikita.ryabchenko" Date: Tue, 10 Feb 2026 11:11:08 +0300 Subject: [PATCH 4/6] docs: flat store with Response to store rules, action overview update - Rewrite processes-store docs: flat store, Source/Target rules, no write without rules - Add Debug action section for testing store - Add 'Write to process store' section in admin actions overview - Update admin processes store description Co-authored-by: Cursor --- .../admin/actions/overview.ru.md | 17 +++ content/documentation/admin/processes.ru.md | 2 +- content/documentation/user/processes-store.md | 126 +++++++++++------ .../documentation/user/processes-store.ru.md | 128 ++++++++++++------ 4 files changed, 189 insertions(+), 84 deletions(-) diff --git a/content/documentation/admin/actions/overview.ru.md b/content/documentation/admin/actions/overview.ru.md index 067cc15..06a6d64 100644 --- a/content/documentation/admin/actions/overview.ru.md +++ b/content/documentation/admin/actions/overview.ru.md @@ -195,6 +195,23 @@ Headers — HTTP-заголовки в формате ключ-значение, * Источник: `{{ .response.id }}`. * Параметр сущности: `repository_id`. +#### Запись в store процесса + +После выполнения действия результат записывается в поле **response**. В разделе «Обновление» действия доступен блок **«Запись в store процесса»** (Write to process store). Он применяется только при выполнении действия в рамках процесса BPMN: если заданы правила записи в store, то после успешного выполнения задачи значения по этим правилам записываются в store инстанса процесса. + +В блоке задаётся список правил: + +| Поле | Описание | +|------|----------| +| **Источник (Source)** | Строка Go-шаблона, в котором контекстом является **response** этого действия (например `{{ .id }}`, `{{ .result.projectId }}`). Шаблон выполняется после успешного выполнения действия; результат (строка) записывается в store. | +| **Целевой ключ (Target)** | Имя ключа в store процесса (например `projectId`, `deployJobId`). Под этим ключом сохраняется значение из источника. | + +Если правил нет (список пустой), при выполнении действия в процессе в store ничего не записывается. Данные из store можно использовать в последующих задачах того же процесса через плейсхолдеры `{{ .store.<ключ> }}`. Подробнее см. [Хранилище для действий в BPMN](../../user/processes-store/). + +{{< alert level="info" >}} +Запись в store выполняется только после успешного выполнения действия. Временный ответ в store не записывается. +{{< /alert >}} + #### Обновление учётных данных пользователя После выполнения действия результат записывается в поле **response**. Если включена опция **обновление учётных данных пользователя**, то на основании данных из **response** действие автоматически обновляет учётные данные пользователя в соответствии с правилами обновления. diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index b6f2ec8..f9a931b 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -90,7 +90,7 @@ moduleStatus: experimental ### Хранилище результатов задач (store) -Результаты выполненных задач можно передавать в последующие шаги процесса: ответ действия сохраняется под слагом элемента задачи, а в конфигурации следующих действий используются плейсхолдеры. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store/). +Результаты выполненных задач можно передавать в последующие шаги процесса: в настройках действия задаются правила «Response to store» (Source — шаблон по response, Target — ключ в store), а в конфигурации следующих действий используются плейсхолдеры `{{ .store.<ключ> }}`. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store/). ## Запуск процесса diff --git a/content/documentation/user/processes-store.md b/content/documentation/user/processes-store.md index e10351f..f528948 100644 --- a/content/documentation/user/processes-store.md +++ b/content/documentation/user/processes-store.md @@ -5,78 +5,122 @@ d8Edition: ee moduleStatus: experimental --- -This document describes how to use the **store** in BPMN processes: how task responses are saved under a slug and how later tasks can reference them in action configuration via placeholders. +This document describes how the **store** works in BPMN processes: how data is written to the store and how later actions read it. ## 1. What is the store? -The store is a key–value map **per process instance**. It holds the **response payloads** of completed tasks, each under a key equal to that task element's **slug**. Only the **action response** (the object returned by the action) is written to the store; the request body is not. +The store is a **flat** key–value map **within a single process instance**. It holds only the data that is explicitly written according to action rules. Another instance of the same process has its own store. -- **One store per process instance:** each run of a process has its own store. Another instance of the same process has a different store. -- **Key = task slug:** when a task finishes successfully, its action response is stored under the slug of that task element. -- **Read via placeholders:** in action configuration (URL, headers, body, etc.) you use Go-style template placeholders to read from the store. +- **One store per process instance** — each process run has its own store. +- **Flat keys** — the store has no "task slug" level; only logical keys (e.g. `projectId`, `deployJobId`). +- **Write only by rules** — data is written to the store only when configured in the action settings (Response to store rules). If there are no rules, nothing is written to the store. +- **Read via placeholders** — in action configuration (URL, headers, body, etc.) you can use Go-style templates such as `{{ .store. }}`. -## 2. How it works +## 2. How data gets into the store -### 2.1. Task element slug +### Response to store rules (on the action) -Each task element in the process has a **slug** (e.g. `create-project`, `deploy-step`). The slug must be unique within the process and is used as the store key for that task's response. +In the **action** configuration, in the "Update" section, there is a block **"Write to process store"**. In it you define a list of rules: -### 2.2. Writing to the store +| Field | Value | Description | +|-------|-------|-------------| +| **Source** | Go template string | Expression with context = **response** of this action. Examples: `{{ .id }}`, `{{ .name }}`, `{{ .result.projectId }}`. The template is executed once after the action completes successfully; the result (string) is written to the store. | +| **Target** | Store key | Name of the key in the process store (e.g. `projectId`, `deployJobId`). The value from Source is saved under this key. | -When a task completes successfully, the engine saves that action's **response** into the instance store under the task's slug. No separate "store key" field is used; the slug is the key. If a **temporary response** is used, that response is not written to the store. +- If the action has **no rules** (empty list) — nothing is written to the store when the task completes successfully. +- If there are rules — after the task completes successfully, for each rule the Source template is executed with the response as context, and the result is written to the store under the Target key. -### 2.3. Reading from the store +### When writing happens -When an action is prepared (e.g. before it runs), the current store is passed as process context. Any string field in the action configuration that supports placeholders can use store placeholders. Missing slugs or fields render as **empty string** and do **not** fail the action. +1. The process task with this action completed **successfully** (action record status = Success). +2. The action has a **non-empty** list of Response to store rules. +3. For each rule: the Go template (Source) is executed with the response data; the resulting string is written to the store under the Target key. -## 3. How to use +If the same Target key is written by several tasks (or by the same action on re-run), **the value is overwritten**. When overwriting an existing key, a warning (Warn) is logged: store key already exists, data will be overwritten. -### 3.1. Set the slug on task elements +## 3. How to read from the store in other actions -In the process editor, for each task element that should expose its result to later steps: +In any **later** action of the same process instance, in fields that support placeholders (URL, headers, body, etc.), you can use: -- Set the **Slug** field (e.g. `create-project`, `fetch-order`, `deploy-step`). -- Slug rules: required for tasks that need to be referenced from the store; typically 3–64 characters; use a format like `lowercase-with-hyphens`. +- **Syntax:** `{{ .store. }}` -Slugs must be unique among task elements in the same process. +`` is the Target from the Response to store rules (e.g. `projectId`, `deployJobId`). The store holds only these flat keys. -### 3.2. Reference the store in action configuration +### Examples -In any **later** action (in the same process instance), use Go template placeholders: - -- **Syntax:** `{{ .store.. }}` -- **Nested fields:** `{{ .store... }}` - -`` is the task element slug; `` (and optional ``) are keys from that task's action response. - -#### Examples - -- Use the ID from a "create project" task in a later request: +- URL with project ID from a previous step: ```yaml -url: "https://api.example.com/projects/{{ .store.create-project.id }}/deploy" +url: "https://api.example.com/projects/{{ .store.projectId }}/deploy" ``` -- Use multiple store entries in one action: +- Several keys from the store in one action: ```yaml headers: - X-Project-Id: "{{ .store.create-project.id }}" - X-Job-Id: "{{ .store.deploy-step.jobId }}" + X-Project-Id: "{{ .store.projectId }}" + X-Job-Id: "{{ .store.deployJobId }}" body: | - {"ref": "{{ .store.previous-step.ref }}"} + {"ref": "{{ .store.orderRef }}"} ``` -- Nested field (if the response is an object with nested data): +An action that **reads** from the store does not need to know which action or task wrote the value — it only needs the **key name** (Target) that is declared in the process (in the settings of actions that write to the store). + +## 4. Behavior when data is missing + +- If a **key** is not in the store (the task has not run yet, had no write rules, or the write did not happen), the placeholder `{{ .store. }}` is replaced with an **empty string**. +- The action **does not fail** — the request is sent with an empty value in that place. + +So you can safely reference keys that are not yet in the store. + +## 5. Summary + +| Question | Answer | +|----------|--------| +| **Where is the store** | In the process instance data. One store per instance. | +| **What is in the store** | Only key–value pairs written by Response to store rules (flat set of keys). | +| **How to write** | In the **action** settings, add "Response to store" rules: Source — Go template over response (e.g. `{{ .id }}`), Target — store key (e.g. `projectId`). After the task completes successfully, values are written to the store according to these rules. | +| **How to read** | In another action's config use `{{ .store. }}`, where `` is one of the Targets from the rules. | +| **No rules on the action** | Nothing is written to the store when this action runs. | +| **Same key written multiple times** | The last written value remains; a warning about overwrite is logged. | +| **Key not in store** | Placeholder yields empty string; action does not fail. | + +## 6. Example scenario + +1. Action "Create project" is configured with Response to store rules: + - Source: `{{ .id }}`, Target: `projectId` + - Source: `{{ .name }}`, Target: `projectName` +2. A task with this action completed successfully; response was `{ "id": "123", "name": "My Project" }`. +3. The instance store now has: `projectId` = "123", `projectName` = "My Project". +4. The next task in the process uses an action with URL: + `https://api.example.com/projects/{{ .store.projectId }}/deploy` + At execution time `projectId` = "123" is substituted. + +## 7. Checking the store with the Debug action + +To verify that data is written to and read from the store, you can use the built-in **Debug** action. + +1. **Add a task with the Debug action** to the process (or create a process with a single such task). +2. **Debug request body** defines the data that will appear in the response. Debug puts the same fields in the response as in the request: `sleep_time`, `sleep_count`, `extra`. In `extra` you can put arbitrary keys — they are available in templates as `{{ .extra. }}`. + + Example body for Debug (fields from `extra` and top level go into the response and are available in templates as `{{ .extra.projectId }}`, `{{ .sleep_time }}`, etc.): ```yaml -projectId: "{{ .store.create-project.result.projectId }}" +sleep_time: 1 +sleep_count: 1 +extra: + example_key: example_value + projectId: "test-123" + message: "hello from debug" ``` -### 3.3. Behavior when data is missing + If the body does not contain `extra.projectId` or `extra.message`, those keys will not appear in the store (the template will yield an empty value; empty values are not written to the store). + +1. **Configure "Write to process store"** for this action: + - Rule 1: Source — `{{ .extra.projectId }}`, Target — `projectId` + - Rule 2: Source — `{{ .extra.message }}`, Target — `debugMessage` -- If a **slug** is not in the store (e.g. the task has not run yet or failed), `{{ .store.. }}` is replaced with an **empty string**. -- If a **field** is missing in the response under that slug, the placeholder also renders as **empty string**. -- The action is **not** failed because of missing store data; only the placeholder output is empty. +1. After the task completes successfully, the store will have keys `projectId` and `debugMessage`. In the **next** task of the process, in the action config use, for example: + - URL or body: `{{ .store.projectId }}`, `{{ .store.debugMessage }}` -You can safely reference store keys that may not exist; the request will still be sent, with empty values where the store had no data. +This way you can confirm that data from Debug is written to the store via the rules and is available to later actions. diff --git a/content/documentation/user/processes-store.ru.md b/content/documentation/user/processes-store.ru.md index 3b5b561..ba6ad92 100644 --- a/content/documentation/user/processes-store.ru.md +++ b/content/documentation/user/processes-store.ru.md @@ -5,78 +5,122 @@ d8Edition: ee moduleStatus: experimental --- -В этом разделе описано, как пользоваться **хранилищем (store)** в процессах BPMN: как ответы задач сохраняются под слагом и как последующие задачи могут обращаться к ним в конфигурации действия через плейсхолдеры. +В этом документе описано, как устроен **store** в процессах BPMN и как им пользоваться: как данные попадают в store и как следующие действия их читают. -## 1. Что такое хранилище (store)? +## 1. Что такое store -Хранилище — это ключ–значение **для каждого экземпляра процесса**. В нём хранятся **ответы** завершённых задач, каждый под ключом, равным **слагу** элемента задачи. В хранилище записывается только **ответ действия** (объект, возвращаемый действием); тело запроса не сохраняется. +Store — это **плоская** ключ–значение map **в рамках одного инстанса процесса**. В нём лежат только те данные, которые явно записываются по правилам действий. Другой инстанс того же процесса имеет свой store. -- **Одно хранилище на экземпляр процесса:** у каждого запуска процесса своё хранилище. Другой экземпляр того же процесса имеет другое хранилище. -- **Ключ = слаг задачи:** при успешном завершении задачи ответ действия сохраняется под слагом этого элемента задачи. -- **Чтение через плейсхолдеры:** в конфигурации действия (URL, заголовки, тело запроса и т.д.) можно использовать плейсхолдеры в стиле Go-шаблонов для чтения из хранилища. +- **Один store на инстанс процесса** — у каждого запуска процесса свой store. +- **Плоские ключи** — в store нет уровня «слаг задачи», только логические ключи (например `projectId`, `deployJobId`). +- **Запись только по правилам** — в store пишется только то, что задано в настройках действия (Response to store rules). Если правил нет — в store ничего не записывается. +- **Чтение через плейсхолдеры** — в конфиге действия (URL, заголовки, body и т.д.) можно использовать Go-шаблоны вида `{{ .store.<ключ> }}`. -## 2. Как это работает +## 2. Как данные попадают в store -### 2.1. Слаг элемента задачи +### Правила на действии (Response to store rules) -У каждого элемента задачи в процессе есть **слаг** (например, `create-project`, `deploy-step`). Слаг должен быть уникален в рамках процесса и используется как ключ в хранилище для ответа этой задачи. +У **действия** в разделе «Обновление» (Update) есть блок **«Запись в store процесса»** (Write to process store). В нём задаётся список правил: -### 2.2. Запись в хранилище +| Поле | Значение | Описание | +|------|----------|----------| +| **Source** | Строка Go-шаблона | Выражение с контекстом = **response** этого действия. Примеры: `{{ .id }}`, `{{ .name }}`, `{{ .result.projectId }}`. Шаблон выполняется один раз после успешного выполнения действия; результат (строка) записывается в store. | +| **Target** | Ключ в store | Имя ключа в store процесса (например `projectId`, `deployJobId`). Под этим ключом будет сохранено значение из Source. | -Когда задача успешно завершается, движок сохраняет **ответ** действия в хранилище экземпляра под слагом задачи. Отдельное поле «ключ хранилища» не используется; ключом является слаг. Если используется **временный ответ**, он не попадает в хранилище. +- Если у действия **нет ни одного правила** (список пустой) — при успешном выполнении задачи в store **ничего не пишется**. +- Если правила есть — после успешного завершения задачи для каждого правила выполняется шаблон Source с контекстом response, и результат записывается в store под ключом Target. -### 2.3. Чтение из хранилища +### Когда выполняется запись -При подготовке действия (например, перед запуском) текущее хранилище передаётся в контексте процесса. Любое строковое поле в конфигурации действия, поддерживающее плейсхолдеры, может использовать плейсхолдеры хранилища. Отсутствующие слаги или поля подставляются как **пустая строка** и **не** приводят к ошибке действия. +1. Задача процесса с этим действием завершилась **успешно** (статус action record = Success). +2. У действия задан **непустой** список правил Response to store. +3. Для каждого правила: выполняется Go-шаблон (Source) с данными response; полученная строка записывается в store под ключом Target. -## 3. Как использовать +Если для одного и того же ключа Target пишут несколько задач (или одно и то же действие при повторном запуске), **значение перезаписывается**. В логах при перезаписи существующего ключа пишется предупреждение (Warn): store key already exists, data will be overwritten. -### 3.1. Задать слаг у элементов задачи +## 3. Как читать из store в других действиях -В редакторе процесса для каждой задачи, результат которой должен быть доступен последующим шагам: +В любом **последующем** действии того же инстанса процесса в полях, поддерживающих плейсхолдеры (URL, заголовки, body и т.д.), можно использовать: -- Заполните поле **Слаг** (например, `create-project`, `fetch-order`, `deploy-step`). -- Правила слага: обязателен для задач, на которые нужно ссылаться из хранилища; обычно 3–64 символа; рекомендуется формат вроде `lowercase-with-hyphens`. +- **Синтаксис:** `{{ .store.<ключ> }}` -Слаги должны быть уникальны среди элементов задач в одном процессе. +`<ключ>` — это Target из правил Response to store (например `projectId`, `deployJobId`). В store лежат только такие плоские ключи. -### 3.2. Ссылка на хранилище в конфигурации действия +### Примеры -В любом **последующем** действии (в том же экземпляре процесса) используйте плейсхолдеры Go-шаблонов: - -- **Синтаксис:** `{{ .store.. }}` -- **Вложенные поля:** `{{ .store... }}` - -`` — слаг элемента задачи; `` (и при необходимости ``) — ключи из ответа действия этой задачи. - -#### Примеры - -- Использовать ID из задачи «создать проект» в следующем запросе: +- URL с ID проекта из предыдущего шага: ```yaml -url: "https://api.example.com/projects/{{ .store.create-project.id }}/deploy" +url: "https://api.example.com/projects/{{ .store.projectId }}/deploy" ``` -- Использовать несколько записей хранилища в одном действии: +- Несколько ключей из store в одном действии: ```yaml headers: - X-Project-Id: "{{ .store.create-project.id }}" - X-Job-Id: "{{ .store.deploy-step.jobId }}" + X-Project-Id: "{{ .store.projectId }}" + X-Job-Id: "{{ .store.deployJobId }}" body: | - {"ref": "{{ .store.previous-step.ref }}"} + {"ref": "{{ .store.orderRef }}"} ``` -- Вложенное поле (если ответ — объект с вложенными данными): +Действие, которое **читает** из store, не обязано знать, какое именно действие или задача записало значение — достаточно знать **имя ключа** (Target), которое объявлено в процессе (в настройках действий, которые что-то пишут в store). + +## 4. Поведение при отсутствующих данных + +- Если **ключа нет** в store (задача ещё не выполнялась, не имела правил записи или запись не произошла), плейсхолдер `{{ .store.<ключ> }}` подставляется как **пустая строка**. +- Действие при этом **не падает** — запрос уходит с пустым значением в этом месте. + +То есть можно безопасно ссылаться на ключи, которых ещё нет в store. + +## 5. Краткая схема + +| Вопрос | Ответ | +|--------|--------| +| **Где хранится store** | В данных инстанса процесса. Один store на инстанс. | +| **Что в store** | Только пары ключ–значение, записанные по правилам Response to store (плоский набор ключей). | +| **Как записать** | В настройках **действия** добавить правила «Response to store»: Source — Go-шаблон по response (например `{{ .id }}`), Target — ключ в store (например `projectId`). После успешного выполнения задачи значения по правилам попадут в store. | +| **Как читать** | В конфиге другого действия использовать `{{ .store.<ключ> }}`, где `<ключ>` — один из Target из правил. | +| **Нет правил у действия** | В store при выполнении этого действия ничего не записывается. | +| **Один ключ пишут несколько раз** | Остаётся последнее записанное значение; в лог пишется предупреждение о перезаписи. | +| **Ключа нет в store** | Плейсхолдер даёт пустую строку, действие не падает. | + +## 6. Пример сценария + +1. Действие «Создать проект» настроено с правилами Response to store: + - Source: `{{ .id }}`, Target: `projectId` + - Source: `{{ .name }}`, Target: `projectName` +2. Задача с этим действием выполнилась успешно; response был `{ "id": "123", "name": "My Project" }`. +3. В store инстанса записалось: `projectId` = "123", `projectName` = "My Project". +4. Следующая задача в процессе использует действие с URL: + `https://api.example.com/projects/{{ .store.projectId }}/deploy` + В момент выполнения подставится `projectId` = "123". + +## 7. Проверка store через действие Debug + +Чтобы проверить запись и чтение из store, удобно использовать встроенное действие **Debug**. + +1. **Добавьте задачу с действием Debug** в процесс (или создайте процесс с одной такой задачей). +2. **Тело запроса Debug** (body) задаёт данные, которые попадут в response. Debug кладёт в response те же поля, что и в запросе: `sleep_time`, `sleep_count`, `extra`. В `extra` можно положить произвольные ключи — они будут доступны в шаблонах как `{{ .extra.<ключ> }}`. + + Пример body для Debug (поля из `extra` и верхнего уровня попадают в response и доступны в шаблонах как `{{ .extra.projectId }}`, `{{ .sleep_time }}` и т.д.): ```yaml -projectId: "{{ .store.create-project.result.projectId }}" +sleep_time: 1 +sleep_count: 1 +extra: + example_key: example_value + projectId: "test-123" + message: "hello from debug" ``` -### 3.3. Поведение при отсутствии данных + Если в body нет `extra.projectId` или `extra.message`, в store эти ключи не попадут (шаблон даст пустое значение, запись в store для пустых не выполняется). + +1. **Настройте «Запись в store процесса»** у этого действия: + - Правило 1: Source — `{{ .extra.projectId }}`, Target — `projectId` + - Правило 2: Source — `{{ .extra.message }}`, Target — `debugMessage` -- Если **слаг** отсутствует в хранилище (например, задача ещё не выполнялась или завершилась с ошибкой), `{{ .store.. }}` подставляется как **пустая строка**. -- Если **поле** отсутствует в ответе по этому слагу, плейсхолдер также подставляется как **пустая строка**. -- Действие **не** завершается ошибкой из-за отсутствующих данных в хранилище; пустым будет только результат подстановки плейсхолдера. +1. После успешного выполнения задачи в store появятся ключи `projectId` и `debugMessage`. В **следующей** задаче процесса в конфиге действия используйте, например: + - URL или body: `{{ .store.projectId }}`, `{{ .store.debugMessage }}` -Можно безопасно ссылаться на ключи хранилища, которых может не быть; запрос всё равно будет отправлен, с пустыми значениями там, где данных в хранилище не было. +Так можно убедиться, что данные из Debug через правила попадают в store и доступны в следующих действиях. From 20bbb6ed0be41c8f6b3086ac187d637006f60a5e Mon Sep 17 00:00:00 2001 From: Nikita Velgin Date: Wed, 25 Feb 2026 02:26:48 +0300 Subject: [PATCH 5/6] update docs with latest fixes --- .../admin/actions/overview.ru.md | 20 +-- content/documentation/admin/processes.ru.md | 23 +++- .../documentation/release-notes/v1.3.0.ru.md | 5 +- content/documentation/user/processes-store.md | 126 ------------------ .../documentation/user/processes-store.ru.md | 126 ------------------ content/documentation/user/templating.ru.md | 28 ++++ 6 files changed, 62 insertions(+), 266 deletions(-) delete mode 100644 content/documentation/user/processes-store.md delete mode 100644 content/documentation/user/processes-store.ru.md diff --git a/content/documentation/admin/actions/overview.ru.md b/content/documentation/admin/actions/overview.ru.md index 06a6d64..9bc278d 100644 --- a/content/documentation/admin/actions/overview.ru.md +++ b/content/documentation/admin/actions/overview.ru.md @@ -61,11 +61,11 @@ weight: 10 Действие может выполняться с использованием одного из двух типов бэкенда: -- **Встроенный (BuiltIn)** — основная логика действия выполняется внутри платформы. +- **Встроенный** — основная логика действия выполняется внутри платформы. > При выборе встроенного бэкенда необходимо указать конкретный тип встроенного действия. В зависимости от выбранного типа платформа автоматически формирует пример тела запроса и определяет перечень учетных данных, необходимых для выполнения действия. -- **Вебхук (Webhook)** — основная логика действия выполняется внешним сервисом, которому платформа отправляет HTTP-запрос. +- **Вебхук** — основная логика действия выполняется внешним сервисом, которому платформа отправляет HTTP-запрос. #### Маскирование полей действия @@ -195,21 +195,21 @@ Headers — HTTP-заголовки в формате ключ-значение, * Источник: `{{ .response.id }}`. * Параметр сущности: `repository_id`. -#### Запись в store процесса +#### Запись в хранилище процесса -После выполнения действия результат записывается в поле **response**. В разделе «Обновление» действия доступен блок **«Запись в store процесса»** (Write to process store). Он применяется только при выполнении действия в рамках процесса BPMN: если заданы правила записи в store, то после успешного выполнения задачи значения по этим правилам записываются в store инстанса процесса. +После выполнения действия результат записывается в поле **response**. В разделе **«Обновление»** конфигурации действия доступен блок **«Запись в хранилище процесса»**. Он применяется только при выполнении действия в рамках процесса: если заданы правила записи в хранилище, то после успешного выполнения действия значения по этим правилам записываются в хранилище. В блоке задаётся список правил: -| Поле | Описание | -|------|----------| -| **Источник (Source)** | Строка Go-шаблона, в котором контекстом является **response** этого действия (например `{{ .id }}`, `{{ .result.projectId }}`). Шаблон выполняется после успешного выполнения действия; результат (строка) записывается в store. | -| **Целевой ключ (Target)** | Имя ключа в store процесса (например `projectId`, `deployJobId`). Под этим ключом сохраняется значение из источника. | +| Поле | Описание | Примеры | +|------|----------|---------| +| **Источник** | Строка Go-шаблона, в котором контекстом является **response** этого действия. Шаблон выполняется после успешного выполнения действия; результат (строка) записывается в хранилище. | `{{ .id }}` — получить поле id из ответа; `{{ .result.projectId }}` — получить вложенное поле projectId из result из ответа | +| **Ключ в хранилище** | Название ключа в хранилище процесса. Под этим ключом сохраняется значение из источника. | `projectId`, `deployJobId` | -Если правил нет (список пустой), при выполнении действия в процессе в store ничего не записывается. Данные из store можно использовать в последующих задачах того же процесса через плейсхолдеры `{{ .store.<ключ> }}`. Подробнее см. [Хранилище для действий в BPMN](../../user/processes-store/). +Если правил нет (список пустой), при выполнении действия в процессе в хранилище ничего не записывается. Данные из хранилища можно использовать в последующих действиях того же процесса через плейсхолдеры `{{ .store.<ключ> }}`. Подробнее об использовании хранилища см. в разделе [«Хранилище процесса»](../processes/#хранилище-процесса). {{< alert level="info" >}} -Запись в store выполняется только после успешного выполнения действия. Временный ответ в store не записывается. +Запись в хранилище выполняется только после успешного выполнения действия. {{< /alert >}} #### Обновление учётных данных пользователя diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index f9a931b..17e9e80 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -88,9 +88,28 @@ moduleStatus: experimental Конфигурация и использование параметров процесса описаны в разделе [шаблонизация](../user/templating/#параметры-процесса). -### Хранилище результатов задач (store) +### Хранилище процесса -Результаты выполненных задач можно передавать в последующие шаги процесса: в настройках действия задаются правила «Response to store» (Source — шаблон по response, Target — ключ в store), а в конфигурации следующих действий используются плейсхолдеры `{{ .store.<ключ> }}`. Подробнее см. [Хранилище для действий в BPMN](../user/processes-store/). +Хранилище процесса — это хранилище формата ключ-значение для передачи данных между действиями в процессе. + +#### Основные характеристики + +- **Одно хранилище на запуск процесса** — каждый запуск процесса имеет своё хранилище. +- **Плоские ключи** — в хранилище используются только логические ключи (например `projectId`, `deployJobId`). +- **Запись только по правилам** — в хранилище записывается только то, что задано в настройках действий, входящих в процесс (см. [«Запись в хранилище процесса»](../actions/overview/#запись-в-хранилище-процесса)). Если правил записи нет — в хранилище ничего не записывается. +- **Чтение через плейсхолдеры** — в конфигурации действий (URL, заголовки, body и т.д.) можно использовать Go-шаблоны вида `{{ .store.<ключ> }}` (см. [«Хранилище процесса»](../../user/templating/#хранилище-процесса)). + +#### Как данные попадают в хранилище + +1. Действие в процессе завершилось **успешно**. +2. У действия задан **непустой** список правил «Запись в хранилище процесса». +3. Для каждого правила выполняется Go-шаблон (Источник) с данными response; полученная строка записывается в хранилище под ключом (Ключ в хранилище). + +Если для одного и того же ключа пишут несколько действий (или одно и то же действие при повторном запуске), **значение перезаписывается**. + +#### Поведение при отсутствующих данных + +Если **ключа нет** в хранилище (действие ещё не выполнялось, не имело правил записи или запись не произошла), при выполнении шаблона `{{ .store.<ключ> }}` действие завершится с ошибкой. ## Запуск процесса diff --git a/content/documentation/release-notes/v1.3.0.ru.md b/content/documentation/release-notes/v1.3.0.ru.md index 4dcdb13..0af2639 100644 --- a/content/documentation/release-notes/v1.3.0.ru.md +++ b/content/documentation/release-notes/v1.3.0.ru.md @@ -22,9 +22,10 @@ weight: 940 - **Jira. Задачи** — для просмотра задач в Jira ([подробнее](../../admin/widgets/types/#jira-задачи)). - **Vault. Секреты** — для просмотра секретов в HashiCorp Vault или Deckhouse Stronghold ([подробнее](../../admin/widgets/types/#vault-секреты)). -### Действия +### Процессы и действия -Добавлена возможность отмены запущенных действий и процессов. +- Добавлен механизм обмена данными между действиями процесса: результаты выполнения действия можно записать в хранилище и использовать в последующих действиях ([подробнее](../../admin/processes/#хранилище-процесса)). +- Добавлена возможность отмены запущенных действий и процессов. ### Команды diff --git a/content/documentation/user/processes-store.md b/content/documentation/user/processes-store.md deleted file mode 100644 index f528948..0000000 --- a/content/documentation/user/processes-store.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: Store for actions in BPMN — usage guide -menuTitle: Store (BPMN) -d8Edition: ee -moduleStatus: experimental ---- - -This document describes how the **store** works in BPMN processes: how data is written to the store and how later actions read it. - -## 1. What is the store? - -The store is a **flat** key–value map **within a single process instance**. It holds only the data that is explicitly written according to action rules. Another instance of the same process has its own store. - -- **One store per process instance** — each process run has its own store. -- **Flat keys** — the store has no "task slug" level; only logical keys (e.g. `projectId`, `deployJobId`). -- **Write only by rules** — data is written to the store only when configured in the action settings (Response to store rules). If there are no rules, nothing is written to the store. -- **Read via placeholders** — in action configuration (URL, headers, body, etc.) you can use Go-style templates such as `{{ .store. }}`. - -## 2. How data gets into the store - -### Response to store rules (on the action) - -In the **action** configuration, in the "Update" section, there is a block **"Write to process store"**. In it you define a list of rules: - -| Field | Value | Description | -|-------|-------|-------------| -| **Source** | Go template string | Expression with context = **response** of this action. Examples: `{{ .id }}`, `{{ .name }}`, `{{ .result.projectId }}`. The template is executed once after the action completes successfully; the result (string) is written to the store. | -| **Target** | Store key | Name of the key in the process store (e.g. `projectId`, `deployJobId`). The value from Source is saved under this key. | - -- If the action has **no rules** (empty list) — nothing is written to the store when the task completes successfully. -- If there are rules — after the task completes successfully, for each rule the Source template is executed with the response as context, and the result is written to the store under the Target key. - -### When writing happens - -1. The process task with this action completed **successfully** (action record status = Success). -2. The action has a **non-empty** list of Response to store rules. -3. For each rule: the Go template (Source) is executed with the response data; the resulting string is written to the store under the Target key. - -If the same Target key is written by several tasks (or by the same action on re-run), **the value is overwritten**. When overwriting an existing key, a warning (Warn) is logged: store key already exists, data will be overwritten. - -## 3. How to read from the store in other actions - -In any **later** action of the same process instance, in fields that support placeholders (URL, headers, body, etc.), you can use: - -- **Syntax:** `{{ .store. }}` - -`` is the Target from the Response to store rules (e.g. `projectId`, `deployJobId`). The store holds only these flat keys. - -### Examples - -- URL with project ID from a previous step: - -```yaml -url: "https://api.example.com/projects/{{ .store.projectId }}/deploy" -``` - -- Several keys from the store in one action: - -```yaml -headers: - X-Project-Id: "{{ .store.projectId }}" - X-Job-Id: "{{ .store.deployJobId }}" -body: | - {"ref": "{{ .store.orderRef }}"} -``` - -An action that **reads** from the store does not need to know which action or task wrote the value — it only needs the **key name** (Target) that is declared in the process (in the settings of actions that write to the store). - -## 4. Behavior when data is missing - -- If a **key** is not in the store (the task has not run yet, had no write rules, or the write did not happen), the placeholder `{{ .store. }}` is replaced with an **empty string**. -- The action **does not fail** — the request is sent with an empty value in that place. - -So you can safely reference keys that are not yet in the store. - -## 5. Summary - -| Question | Answer | -|----------|--------| -| **Where is the store** | In the process instance data. One store per instance. | -| **What is in the store** | Only key–value pairs written by Response to store rules (flat set of keys). | -| **How to write** | In the **action** settings, add "Response to store" rules: Source — Go template over response (e.g. `{{ .id }}`), Target — store key (e.g. `projectId`). After the task completes successfully, values are written to the store according to these rules. | -| **How to read** | In another action's config use `{{ .store. }}`, where `` is one of the Targets from the rules. | -| **No rules on the action** | Nothing is written to the store when this action runs. | -| **Same key written multiple times** | The last written value remains; a warning about overwrite is logged. | -| **Key not in store** | Placeholder yields empty string; action does not fail. | - -## 6. Example scenario - -1. Action "Create project" is configured with Response to store rules: - - Source: `{{ .id }}`, Target: `projectId` - - Source: `{{ .name }}`, Target: `projectName` -2. A task with this action completed successfully; response was `{ "id": "123", "name": "My Project" }`. -3. The instance store now has: `projectId` = "123", `projectName` = "My Project". -4. The next task in the process uses an action with URL: - `https://api.example.com/projects/{{ .store.projectId }}/deploy` - At execution time `projectId` = "123" is substituted. - -## 7. Checking the store with the Debug action - -To verify that data is written to and read from the store, you can use the built-in **Debug** action. - -1. **Add a task with the Debug action** to the process (or create a process with a single such task). -2. **Debug request body** defines the data that will appear in the response. Debug puts the same fields in the response as in the request: `sleep_time`, `sleep_count`, `extra`. In `extra` you can put arbitrary keys — they are available in templates as `{{ .extra. }}`. - - Example body for Debug (fields from `extra` and top level go into the response and are available in templates as `{{ .extra.projectId }}`, `{{ .sleep_time }}`, etc.): - -```yaml -sleep_time: 1 -sleep_count: 1 -extra: - example_key: example_value - projectId: "test-123" - message: "hello from debug" -``` - - If the body does not contain `extra.projectId` or `extra.message`, those keys will not appear in the store (the template will yield an empty value; empty values are not written to the store). - -1. **Configure "Write to process store"** for this action: - - Rule 1: Source — `{{ .extra.projectId }}`, Target — `projectId` - - Rule 2: Source — `{{ .extra.message }}`, Target — `debugMessage` - -1. After the task completes successfully, the store will have keys `projectId` and `debugMessage`. In the **next** task of the process, in the action config use, for example: - - URL or body: `{{ .store.projectId }}`, `{{ .store.debugMessage }}` - -This way you can confirm that data from Debug is written to the store via the rules and is available to later actions. diff --git a/content/documentation/user/processes-store.ru.md b/content/documentation/user/processes-store.ru.md deleted file mode 100644 index ba6ad92..0000000 --- a/content/documentation/user/processes-store.ru.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: Хранилище (store) для действий в BPMN — руководство -menuTitle: Store (BPMN) -d8Edition: ee -moduleStatus: experimental ---- - -В этом документе описано, как устроен **store** в процессах BPMN и как им пользоваться: как данные попадают в store и как следующие действия их читают. - -## 1. Что такое store - -Store — это **плоская** ключ–значение map **в рамках одного инстанса процесса**. В нём лежат только те данные, которые явно записываются по правилам действий. Другой инстанс того же процесса имеет свой store. - -- **Один store на инстанс процесса** — у каждого запуска процесса свой store. -- **Плоские ключи** — в store нет уровня «слаг задачи», только логические ключи (например `projectId`, `deployJobId`). -- **Запись только по правилам** — в store пишется только то, что задано в настройках действия (Response to store rules). Если правил нет — в store ничего не записывается. -- **Чтение через плейсхолдеры** — в конфиге действия (URL, заголовки, body и т.д.) можно использовать Go-шаблоны вида `{{ .store.<ключ> }}`. - -## 2. Как данные попадают в store - -### Правила на действии (Response to store rules) - -У **действия** в разделе «Обновление» (Update) есть блок **«Запись в store процесса»** (Write to process store). В нём задаётся список правил: - -| Поле | Значение | Описание | -|------|----------|----------| -| **Source** | Строка Go-шаблона | Выражение с контекстом = **response** этого действия. Примеры: `{{ .id }}`, `{{ .name }}`, `{{ .result.projectId }}`. Шаблон выполняется один раз после успешного выполнения действия; результат (строка) записывается в store. | -| **Target** | Ключ в store | Имя ключа в store процесса (например `projectId`, `deployJobId`). Под этим ключом будет сохранено значение из Source. | - -- Если у действия **нет ни одного правила** (список пустой) — при успешном выполнении задачи в store **ничего не пишется**. -- Если правила есть — после успешного завершения задачи для каждого правила выполняется шаблон Source с контекстом response, и результат записывается в store под ключом Target. - -### Когда выполняется запись - -1. Задача процесса с этим действием завершилась **успешно** (статус action record = Success). -2. У действия задан **непустой** список правил Response to store. -3. Для каждого правила: выполняется Go-шаблон (Source) с данными response; полученная строка записывается в store под ключом Target. - -Если для одного и того же ключа Target пишут несколько задач (или одно и то же действие при повторном запуске), **значение перезаписывается**. В логах при перезаписи существующего ключа пишется предупреждение (Warn): store key already exists, data will be overwritten. - -## 3. Как читать из store в других действиях - -В любом **последующем** действии того же инстанса процесса в полях, поддерживающих плейсхолдеры (URL, заголовки, body и т.д.), можно использовать: - -- **Синтаксис:** `{{ .store.<ключ> }}` - -`<ключ>` — это Target из правил Response to store (например `projectId`, `deployJobId`). В store лежат только такие плоские ключи. - -### Примеры - -- URL с ID проекта из предыдущего шага: - -```yaml -url: "https://api.example.com/projects/{{ .store.projectId }}/deploy" -``` - -- Несколько ключей из store в одном действии: - -```yaml -headers: - X-Project-Id: "{{ .store.projectId }}" - X-Job-Id: "{{ .store.deployJobId }}" -body: | - {"ref": "{{ .store.orderRef }}"} -``` - -Действие, которое **читает** из store, не обязано знать, какое именно действие или задача записало значение — достаточно знать **имя ключа** (Target), которое объявлено в процессе (в настройках действий, которые что-то пишут в store). - -## 4. Поведение при отсутствующих данных - -- Если **ключа нет** в store (задача ещё не выполнялась, не имела правил записи или запись не произошла), плейсхолдер `{{ .store.<ключ> }}` подставляется как **пустая строка**. -- Действие при этом **не падает** — запрос уходит с пустым значением в этом месте. - -То есть можно безопасно ссылаться на ключи, которых ещё нет в store. - -## 5. Краткая схема - -| Вопрос | Ответ | -|--------|--------| -| **Где хранится store** | В данных инстанса процесса. Один store на инстанс. | -| **Что в store** | Только пары ключ–значение, записанные по правилам Response to store (плоский набор ключей). | -| **Как записать** | В настройках **действия** добавить правила «Response to store»: Source — Go-шаблон по response (например `{{ .id }}`), Target — ключ в store (например `projectId`). После успешного выполнения задачи значения по правилам попадут в store. | -| **Как читать** | В конфиге другого действия использовать `{{ .store.<ключ> }}`, где `<ключ>` — один из Target из правил. | -| **Нет правил у действия** | В store при выполнении этого действия ничего не записывается. | -| **Один ключ пишут несколько раз** | Остаётся последнее записанное значение; в лог пишется предупреждение о перезаписи. | -| **Ключа нет в store** | Плейсхолдер даёт пустую строку, действие не падает. | - -## 6. Пример сценария - -1. Действие «Создать проект» настроено с правилами Response to store: - - Source: `{{ .id }}`, Target: `projectId` - - Source: `{{ .name }}`, Target: `projectName` -2. Задача с этим действием выполнилась успешно; response был `{ "id": "123", "name": "My Project" }`. -3. В store инстанса записалось: `projectId` = "123", `projectName` = "My Project". -4. Следующая задача в процессе использует действие с URL: - `https://api.example.com/projects/{{ .store.projectId }}/deploy` - В момент выполнения подставится `projectId` = "123". - -## 7. Проверка store через действие Debug - -Чтобы проверить запись и чтение из store, удобно использовать встроенное действие **Debug**. - -1. **Добавьте задачу с действием Debug** в процесс (или создайте процесс с одной такой задачей). -2. **Тело запроса Debug** (body) задаёт данные, которые попадут в response. Debug кладёт в response те же поля, что и в запросе: `sleep_time`, `sleep_count`, `extra`. В `extra` можно положить произвольные ключи — они будут доступны в шаблонах как `{{ .extra.<ключ> }}`. - - Пример body для Debug (поля из `extra` и верхнего уровня попадают в response и доступны в шаблонах как `{{ .extra.projectId }}`, `{{ .sleep_time }}` и т.д.): - -```yaml -sleep_time: 1 -sleep_count: 1 -extra: - example_key: example_value - projectId: "test-123" - message: "hello from debug" -``` - - Если в body нет `extra.projectId` или `extra.message`, в store эти ключи не попадут (шаблон даст пустое значение, запись в store для пустых не выполняется). - -1. **Настройте «Запись в store процесса»** у этого действия: - - Правило 1: Source — `{{ .extra.projectId }}`, Target — `projectId` - - Правило 2: Source — `{{ .extra.message }}`, Target — `debugMessage` - -1. После успешного выполнения задачи в store появятся ключи `projectId` и `debugMessage`. В **следующей** задаче процесса в конфиге действия используйте, например: - - URL или body: `{{ .store.projectId }}`, `{{ .store.debugMessage }}` - -Так можно убедиться, что данные из Debug через правила попадают в store и доступны в следующих действиях. diff --git a/content/documentation/user/templating.ru.md b/content/documentation/user/templating.ru.md index c0a20eb..074c430 100644 --- a/content/documentation/user/templating.ru.md +++ b/content/documentation/user/templating.ru.md @@ -497,3 +497,31 @@ title: Шаблонизация {{ .workflow.notificationEmail }} // Email для уведомлений из параметров сценария {{ .workflow.retryAttempts }} // Количество попыток повтора из параметров сценария ``` + +## Хранилище процесса + +Хранилище доступно только в процессах и используется для передачи данных между действиями. В настройках действия задаются правила записи в хранилище (см. [«Запись в хранилище процесса»](../../admin/actions/overview/#запись-в-хранилище-процесса)), а в конфигурации последующих действий используются плейсхолдеры для чтения данных. + +Для получения значения из хранилища используйте следующую конструкцию: + +```go +{{ .store.<ключ> }} +``` + +где: + +- `store` — указывает на то, что идет обращение к хранилищу процесса. +- `<ключ>` — название ключа в хранилище, под которым было сохранено значение (поле **Ключ в хранилище** в правилах записи). + +Особенности использования: + +- Хранилище доступно только в процессах, в обычных действиях и сценариях плейсхолдеры `{{ .store.* }}` не работают. +- Если ключа нет в хранилище (действие ещё не выполнялось, не имело правил записи или запись не произошла), действие завершится с ошибкой. +- Если для одного и того же ключа пишут несколько действий, остаётся последнее записанное значение. + +Примеры использования: + +```go +{{ .store.projectId }} // ID проекта из хранилища +{{ .store.orderRef }} // Референс заказа из хранилища +``` From 55ce45231ea67336380f572cea0a94c062662d03 Mon Sep 17 00:00:00 2001 From: Nikita Velgin Date: Wed, 25 Feb 2026 02:32:16 +0300 Subject: [PATCH 6/6] fix typos --- content/documentation/admin/processes.ru.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/documentation/admin/processes.ru.md b/content/documentation/admin/processes.ru.md index 17e9e80..07fa6f8 100644 --- a/content/documentation/admin/processes.ru.md +++ b/content/documentation/admin/processes.ru.md @@ -102,8 +102,8 @@ moduleStatus: experimental #### Как данные попадают в хранилище 1. Действие в процессе завершилось **успешно**. -2. У действия задан **непустой** список правил «Запись в хранилище процесса». -3. Для каждого правила выполняется Go-шаблон (Источник) с данными response; полученная строка записывается в хранилище под ключом (Ключ в хранилище). +2. У действия настроены правила «Запись в хранилище процесса». +3. Для каждого правила выполняется Go-шаблон из поля **Источник** с данными ответа действия; полученная строка записывается в хранилище под ключом, указанным в поле **Ключ в хранилище**. Если для одного и того же ключа пишут несколько действий (или одно и то же действие при повторном запуске), **значение перезаписывается**.