Skip to main content

workflow-json-generation-rules

Rules for generating workflow.json files for Logic Apps Standard. Covers connector selection, splitOn preference, file trigger semantics, runAfter structure, and mandatory reference lookup before writing.

Datos de origen

Repositorio
Azure/logicapps-migration-agent
Última actividad en el origen
21 de agosto de 2026 a las 12:58
Idioma detectado de SKILL.md
inglés
Estrellas
10
Forks
13

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
workflow-json-generation-rules
description
Rules for generating workflow.json files for Logic Apps Standard. Covers connector selection, splitOn preference, file trigger semantics, runAfter structure, and mandatory reference lookup before writing.
# Skill: Workflow JSON Generation Rules > **Purpose**: Authoritative rules for generating `workflow.json` files. Follow exactly. --- ## 1. Mandatory Reference Lookup BEFORE writing ANY `workflow.json`: 1. Read the skill `source-to-logic-apps-mapping` to get the Logic Apps equivalent connector, service provider ID, and operation names for each source component. 2. Use those operation names to call `migration_searchReferenceWorkflows` and `migration_readReferenceWorkflow` to get exact `operationId` and `serviceProviderConfiguration` for each trigger/action. 3. If the first search returns no relevant results, RETRY 2-4 more times with different word combinations. 4. Also call `migration_readReferenceDoc` with `action="search"` then `action="read"` to verify connector capabilities. 5. Do NOT invent `operationId` values, `serviceProviderConfiguration` structures, or connection formats — ALWAYS copy from references. --- ## 2. Workflow Definition Structure Each `workflow.json` must contain a `definition` key with: - `$schema` — MUST be exactly `"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#"` - `contentVersion` — use `"1.0.0.0"` - `triggers` — at least one trigger - `actions` — with `runAfter` (object mapping predecessor action names to status arrays) and `type` for each action - `metadata` — MUST include a `MigrationMetadata` object (see below) ### Definition Metadata Every `workflow.json` `definition` MUST include a `metadata.MigrationMetadata` object with the following fields: - Place `metadata` at the top level of `definition`. - `MigrationMetadata` is an object nested under `metadata`. - `MigrationCorrelationId` — a unique GUID identifying the migration run. - `MigrationDate` — the current timestamp captured at migration time, in ISO 8601 format (`yyyy-MM-ddTHH:mm:ss`). Example (replace placeholders with generated values): ```json "metadata": { "MigrationMetadata": { "MigrationCorrelationId": "<GENERATED-GUID>", "MigrationDate": "<CURRENT-TIMESTAMP-ISO-8601>" } } ``` ### Action Types - `Switch` — must have `cases` - `If` / `Condition` — must have `actions` (true branch) and optionally `else.actions` (false branch) - `Foreach` / `Until` — nest `actions` inside - `ServiceProvider` — with `serviceProviderConfiguration` - `ApiConnection` — only when no built-in ServiceProvider equivalent exists - `InvokeFunction` — for .NET local functions - `Workflow` / `InvokeWorkflow` — for calling child workflows ### Preference: ServiceProvider over ApiConnection Prefer `ServiceProvider` type with `serviceProviderConfiguration` over `ApiConnection` (managed connector) whenever a built-in equivalent exists. Built-in connectors run in-process with lower latency and no connection overhead. ### Parameterization (keep it simple) - For Logic Apps Standard, prefer `parameters.json` for cross-environment values. - In `workflow.json`, reference values with `@parameters('name')`. - In `parameters.json`, `@appsetting('name')` is the only valid expression type. - In `connections.json`, only `@parameters(...)` and `@appsetting(...)` are valid. - For more details, fetch Microsoft Learn docs about Standard parameters and app settings (`create-parameters-workflows`, `edit-app-settings-host-settings`). --- ## 3. SplitOn over ForEach When a trigger returns an array (batch of messages), ALWAYS use `splitOn` on the trigger instead of wrapping actions in a `For_each` loop: ```json "triggers": { "myTrigger": { "splitOn": "@triggerOutputs()?['body']", ... } } ``` SplitOn debatches the array so each item fires a separate workflow run. Only use `For_each` if splitOn is not supported by that trigger type. --- ## 4. File System Trigger Semantics - Do NOT add delete/remove/cleanup actions that remove the trigger input file by default. - The runtime does not re-trigger on the same unchanged file, so deleting is unnecessary unless the user explicitly requests archival/deletion behavior. --- ## 5. Trigger Output Verification (MANDATORY) > **⚠️ NEVER assume a trigger returns file/message content directly. ALWAYS verify what the trigger actually returns.** Many triggers return **metadata** (file path, message ID, blob URI) rather than the actual content. You MUST check the trigger's return type from the reference workflow before building downstream actions. ### 5.1 Procedure 1. After selecting a trigger via reference lookup (§1), read the reference workflow AND the reference docs to see what `triggerOutputs()` or `triggerBody()` actually contains. 2. Call `migration_readReferenceDoc` with `action="search"` for the trigger's connector name to find documentation on its output schema and return type. 3. Call `migration_readReferenceDoc` with `action="read"` on the top result to confirm the exact trigger output fields. 4. If the trigger returns a **file path** (e.g. File System `whenFilesAreAdded` returns `path` and `name`), you MUST add a separate **read content** action (e.g. `getFileContent`) before any parsing/processing. 5. If the trigger returns **message content directly** (e.g. HTTP Request trigger, Service Bus `receiveQueueMessage`), you can use `triggerBody()` directly. ### 5.2 Common Trigger Return Types | Trigger | Returns | Content Available Via | | ----------------------------------------- | -------------------------------- | ----------------------------------------- | | File System `whenFilesAreAdded` | File metadata (path, name, size) | Add `getFileContent` action with the path | | File System `whenFilesAreAddedOrModified` | File metadata (path, name, size) | Add `getFileContent` action with the path | | Azure Blob `whenABlobIsAddedOrModified` | Blob metadata (path, URI) | Add `readBlob` action with the path | | HTTP Request | Full request body | `triggerBody()` directly | | Service Bus `receiveQueueMessage` | Message content + properties | `triggerBody()?['contentData']` directly | | Service Bus `peekLockQueueMessagesV2` | Array of message metadata | Add `completeMessage` after processing | | FTP/SFTP `whenFileIsAdded` | File metadata | Add `getFileContent` action with the path | | Recurrence / Timer | No body | N/A — use actions to fetch data | ### 5.3 Rule - **If trigger returns metadata/path**: Add a content-reading action BEFORE any XmlParse, Parse JSON, Compose, or processing action. - **If trigger returns content directly**: Use `triggerBody()` or `triggerOutputs()?['body']` in downstream actions. - **If unsure**: Check BOTH the reference workflow AND the reference docs. If the reference workflow has a read-content action after the trigger, or the docs show the trigger returns metadata rather than content, you need a content-reading action too. --- ## 6. 1:1 Flow to Workflow Rule - Every flow (including sub-flows with significant logic) MUST be a separate workflow. - Use the `Workflow` action type to invoke child workflows from parent workflows. - Do NOT convert flows to local functions. --- ## 7. Plan Adherence When fixing any errors in workflow.json: - Do NOT deviate from the planned design. - Do NOT add/remove actions, change triggers, switch connectors, or alter schemas. - Before any fix, re-read the planning results to verify compliance. - If a fix requires changing the design, STOP and report to the user. --- ## 8. Scenario-Specific Action Overrides These overrides are deterministic — apply them directly without asking the user. ### 8.1 XML Field Extraction When extracting fields from an XML message body: 1. **FIRST**: Use `XmlParse` built-in action with the schema from `Artifacts/Schemas/`. This validates and extracts XML fields in one step. Access fields via: `body('Parse_XML')?['Root']?['fieldName']` 2. **ONLY IF** no schema exists and cannot be generated: fall back to `xpath()` expressions. Do NOT use `xpath()` when an XSD schema is available — XmlParse is a level-1 built-in action and MUST be preferred over level-2 expressions per the Component Priority Ladder. ### 8.2 XML Schema Validation When validating incoming XML against a schema: - Use `XmlValidation` built-in action — do NOT write custom validation logic or skip validation. ### 8.3 XML Transformation When transforming XML documents: - Use `Xslt` (Transform XML) built-in action with maps from `Artifacts/Maps/` — do NOT use Compose + string manipulation. ### 8.4 Output XML Construction When constructing XML output documents: - **FIRST**: Use `XmlCompose` built-in action (XML Operations) to compose XML from structured data. This assembles XML output from structured fields. - `XmlCompose` can reference schemas from **either** the local `Artifacts/Schemas/` folder **or** an **Integration Account** — select the source via the `Source` parameter (`LogicApp` or `IntegrationAccount`). If the flow uses the Integration Account model, use `IntegrationAccount` as the source. - If the source uses .NET code to build XML (e.g. `XmlDocument`, `XElement`) with complex business logic, use a **.NET local function**. - If the output is a simple static template with field substitution, `Compose` is acceptable. - Do NOT approximate XML construction with `Compose` + `concat()` when `XmlCompose` or a local function is more appropriate. ### 8.5 EDI Decode Output Handling > **⚠️ CRITICAL**: The EDIFACT `EdifactDecode` and X12 `X12Decode` built-in actions return **JSON**, not XML. If a downstream action or function expects XML (e.g. `XmlDocument.LoadXml()`), you MUST add an `XmlCompose` action after the decode action to convert the JSON back to XML using the appropriate message schema. Pattern: ``` Decode_EDIFACT (EdifactDecode) → JSON output → Compose_EDIFACT_XML (XmlCompose, Source: IntegrationAccount, Schema: message schema) → XML output → downstream action expecting XML ``` Do NOT pass the JSON decode output directly to XML-expecting code. Do NOT try to parse the JSON as XML — it will fail with "Data at the root level is invalid". ### 8.6 JSON Parsing When parsing JSON payloads: - Use `Parse JSON` built-in action — do NOT use `json()` expression for structured access. --- ## 9. Pre-Finalize Validation Checklist Before storing workflow definitions, cross-check EVERY action against this table. If ANY row in the "DON'T" column matches your output, fix it before proceeding. | Scenario | DO (correct) | DON'T (wrong — fix before storing) | | --------------------------- | ---------------------------------------------------- | ------------------------------------------------------ | | Trigger output assumption | Verify trigger return type from ref | Assume trigger returns file/message content directly | | File/Blob/FTP trigger | Add `getFileContent`/`readBlob` action after trigger | Use `triggerBody()` for content (it only has metadata) | | XML field extraction | `XmlParse` action + schema | `xpath()` expression when schema exists | | XML validation | `XmlValidation` action | Skip validation or custom code | | XML transformation | `Xslt` action + map file | `Compose` + string concat | | XML output assembly | `XmlCompose` action (Source: LogicApp or IntegrationAccount) | `Compose` + `concat()` for XML | | EDI decode → XML needed | Add `XmlCompose` after EdifactDecode/X12Decode | Pass JSON decode output directly to XML-expecting code | | Complex XML with .NET logic | .NET local function | `Compose` + `concat()` approximation | | JSON parsing | `Parse JSON` action | `json()` expression for structured access | | Array trigger debatching | `splitOn` on trigger | `For_each` loop wrapping all actions | | File trigger cleanup | Do nothing (no delete) | Delete/archive trigger input file | | Sub-flow (via flow-ref) | Separate workflow + `Workflow` action | Merge into parent or local function | | Custom source code | .NET local function | Expressions or inline approximation |
Ver en GitHub