From b4d2f38d0c56132f71d455240ad84cd61938cfba Mon Sep 17 00:00:00 2001 From: Craig Thacker Date: Mon, 24 Aug 2026 14:39:45 +0100 Subject: [PATCH] feat(schema): annotated WDL schema, as JSON and YAML The published 2016-06-01 workflow definition schema is machine generated: 147 KB, no definitions section, everything inlined through allOf/oneOf, and descriptions that restate the property name. It validates a definition but does not teach one, and says nothing about the behaviours that pass validation and fail at run time. It also rejects definitions Azure itself emits. Validating the 87 workflow definitions in this workspace against it, only 13 of the 35 whole definitions pass. Against this schema, all 35 do. schema/ holds the upstream copy, a hand authored annotations.yaml, a generator, and the two outputs. The generator merges 21 notes into the descriptions and applies 5 corrections, then writes the result as both JSON and YAML. Every pointer is asserted to resolve, so an upstream reshape fails loudly rather than dropping notes. The corrections, each found by validating real definitions rather than by reading, and each widening what is accepted: - retryPolicy.type enum is PascalCase upstream, lowercase in practice (39 real actions rejected) - the authentication union has no ManagedServiceIdentity branch, which is the recommended auth for an Http action calling Azure (28) - retryPolicy.count is typed integer, rejecting an expression (5) - InitializeVariable and SetVariable types are PascalCase upstream (3) - InitializeVariable caps variables at maxItems 1, but a portal export from a live workflow carries three (1) The YAML is the SCHEMA in YAML, for readability and for tools that take a YAML schema. A workflow definition is still JSON: WDL has no YAML dialect, and the schema says so where someone will read it. --- schema/README.md | 102 + schema/annotations.yaml | 312 ++ schema/generate.py | 252 ++ .../workflowdefinition.annotated.schema.json | 2541 +++++++++++++++++ .../workflowdefinition.annotated.schema.yaml | 1869 ++++++++++++ schema/workflowdefinition.schema.json | 2461 ++++++++++++++++ 6 files changed, 7537 insertions(+) create mode 100644 schema/README.md create mode 100644 schema/annotations.yaml create mode 100644 schema/generate.py create mode 100644 schema/workflowdefinition.annotated.schema.json create mode 100644 schema/workflowdefinition.annotated.schema.yaml create mode 100644 schema/workflowdefinition.schema.json diff --git a/schema/README.md b/schema/README.md new file mode 100644 index 0000000..eebe09c --- /dev/null +++ b/schema/README.md @@ -0,0 +1,102 @@ +# The workflow definition schema, annotated + +The Azure Logic Apps workflow definition schema, version `2016-06-01`, with Libre DevOps +annotations and five corrections, published as **JSON and YAML**. + +| File | What it is | +|---|---| +| `workflowdefinition.schema.json` | the upstream schema, committed verbatim so a rebuild needs no network | +| `workflowdefinition.annotated.schema.json` | the deliverable: annotated and corrected | +| `workflowdefinition.annotated.schema.yaml` | the same document in YAML | +| `annotations.yaml` | the notes and corrections, hand authored, the only file to edit | +| `generate.py` | fetches upstream, applies both layers, writes the two outputs | + +## Why this exists + +The published schema is machine generated: 147 KB, no `definitions` section, everything inlined +through `allOf`/`oneOf`, and descriptions like `"The flow triggers."` that restate the property +name. It validates a definition but it does not teach one, and it says nothing about the +behaviours that pass validation and then fail at run time. + +Worse, **it rejects definitions Azure itself emits**. Validating the 87 workflow definitions in +this workspace against it: + +| | Whole definitions validating cleanly | +|---|---| +| upstream schema | **13 of 35** | +| this schema | **35 of 35** | + +## The corrections + +Every one was found by validating real definitions, not by reading. Each widens what is accepted; +none makes the schema accept less. The occurrence count is how many real actions upstream rejected. + +| Correction | Occurrences | What upstream gets wrong | +|---|---:|---| +| `retry-policy-type-casing` | 39 | enum is `None`/`Fixed`/`Exponential`; the designer and every example emit lowercase | +| `authentication-managed-identity` | 28 | the `authentication` union has no `ManagedServiceIdentity` branch, which is the recommended auth for an Http action calling Azure | +| `retry-policy-count-expression` | 5 | `count` is typed `integer`, rejecting `"@parameters('retry_count')"`; any WDL value may be an expression string | +| `variable-type-casing` | 3 | `InitializeVariable` and `SetVariable` types are PascalCase upstream, lowercase in practice | +| `initialize-variable-multiple` | 1 | `variables` is capped at `maxItems: 1`; a portal export from a live workflow carries three | + +Each correction is recorded in the output under `x-annotation.corrections`, with its pointer, +reason and occurrence count, and is called out in the `description` at the node it changed. Report +them upstream and delete the entry when fixed. + +## Using it + +**Point your editor at it** while authoring a `.json.tftpl` template, and you get hover +documentation and completion on every property, without false errors on correct workflows. + +VS Code, in `.vscode/settings.json`: + +```json +{ + "json.schemas": [ + { + "fileMatch": ["templates/*.json.tftpl", "**/workflow.json"], + "url": "./schema/workflowdefinition.annotated.schema.json" + } + ] +} +``` + +**Validate in CI** with any draft-04 validator, for example: + +```bash +uv run --with check-jsonschema check-jsonschema \ + --schemafile schema/workflowdefinition.annotated.schema.json \ + templates/*.json +``` + +Note that a `.json.tftpl` template is not valid JSON until `templatefile` has rendered its +`${tokens}`, so validate the rendered output rather than the template, or substitute the tokens +first. + +## Regenerating + +```bash +uv run schema/generate.py # refresh from the live upstream schema +uv run schema/generate.py --offline # rebuild from the committed upstream copy +uv run schema/generate.py --check # fail if the committed outputs are stale +``` + +Edit `annotations.yaml`, never the generated files. Every annotation and correction pointer is +asserted to resolve, so if Microsoft reshapes the schema the build fails loudly rather than +silently dropping notes. + +## There is no YAML dialect of WDL + +The YAML file here is **the schema** in YAML, for readability and for tools that accept a YAML +schema. A workflow definition itself is JSON. See the +[Libre DevOps Logic App standard](https://libredevops.org/docs/documents/azure-logic-app-standards). + +## Sources + +Annotations were written against these, all checked 24 August 2026: + +- [Workflow Definition Language overview](https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-definition-language) +- [Schema reference](https://learn.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-schema) +- [Triggers and actions reference](https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-actions-triggers) +- [Expression functions reference](https://learn.microsoft.com/en-us/azure/logic-apps/expression-functions-reference) +- [Libre DevOps Azure Logic App standard](https://libredevops.org/docs/documents/azure-logic-app-standards) diff --git a/schema/annotations.yaml b/schema/annotations.yaml new file mode 100644 index 0000000..b11b008 --- /dev/null +++ b/schema/annotations.yaml @@ -0,0 +1,312 @@ +# Annotations layered onto the published Azure Logic Apps workflow definition schema. +# +# The upstream schema at +# https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json +# is machine generated: 147 KB, no `definitions` section, everything inlined through allOf/oneOf, +# and descriptions like "The flow triggers." that restate the property name. It validates, but it +# does not teach, and it says nothing about the behaviours that pass validation and then fail at +# run time. +# +# This file is the annotation layer. `generate.py` fetches the upstream schema, merges each note +# below into the `description` at that JSON Pointer, and writes the annotated schema as both JSON +# and YAML. Keeping the notes here rather than in the generated files means the annotations stay +# reviewable in a diff and survive an upstream refresh. +# +# Every pointer is asserted to exist at generate time, so an upstream reshape fails the build +# rather than silently dropping a note. +# +# Sources for the notes, all checked 24 August 2026: +# https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-definition-language +# https://learn.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-schema +# https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-workflow-actions-triggers +# https://learn.microsoft.com/en-us/azure/logic-apps/expression-functions-reference +# https://libredevops.org/docs/documents/azure-logic-app-standards +--- +meta: + title: Azure Logic Apps workflow definition schema, annotated + upstream: https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json + annotated_by: Libre DevOps + annotations_checked: "2026-08-24" + +notes: + "": | + A Logic Apps workflow definition, schema version 2016-06-01. + + THE SHAPE. Six properties carry everything: `triggers` starts the run, `actions` do the work, + `parameters` declares what varies between environments, `outputs` exposes results, + `contentVersion` stamps the definition, and `$schema` points here. + + WHAT THIS DOCUMENT IS NOT. This schema describes the JSON. It does NOT describe the `@{...}` + runtime expression layer inside those strings. A definition can be schema-valid and still fail + at run time because an expression referenced a missing property or evaluated an operand it + should not have. See the expression functions reference, and the pitfalls section of the + Libre DevOps Logic App standard. + + THERE IS NO YAML DIALECT. A workflow definition is JSON. The YAML rendering of THIS SCHEMA + exists for readability and for tools that accept YAML schemas; it does not mean a definition + may be written in YAML. + + PLATFORM LIMITS the schema does not encode: maximum 250 actions, maximum 10 triggers. The + designer authors a single trigger; more than one is expressible only in the language itself. + + DOCUMENTED BUT ABSENT: `staticResults`, referenced by `runtimeConfiguration.staticResult.name` + on an action, is documented as a definition-level attribute and is NOT declared in this + schema's root `properties`. Using it validates only because the root does not forbid unknown + properties. + + "/properties/$schema": | + The schema location. Required by this document, and the string that makes an editor validate + the file as you type. Keep it as exported. + + "/properties/contentVersion": | + Your version stamp for the definition, "1.0.0.0" by default. It is metadata: the platform does + not use it to order or reject deployments. Worth setting so a deployed workflow can be matched + back to a commit. + + "/properties/description": | + Free text describing the workflow. Distinct from the `hidden-title` tag on the Azure resource, + which is what the portal list shows. Set both. + + "/properties/metadata": | + Arbitrary key/value metadata carried with the definition. The designer writes its own entries + here. Leave what the designer put there alone: rewriting it is how a template stops diffing + cleanly against a fresh export. + + "/properties/parameters": | + Parameter DECLARATIONS, not values. This is the single most misunderstood part of deploying a + workflow as code. + + A declaration says a parameter exists, its type, and optionally a default and allowed values. + The VALUE lives outside the definition, in the ARM/azapi request body's `properties.parameters`. + A portal export carries both halves, which is why an unedited export deploys. + + Anything declared here with no value anywhere fails at deploy with `InvalidTemplate`, "the + value for the workflow parameter ... is not provided". Catch it at plan time instead. + + `$connections` is declared here like any other parameter, and its value is generated rather + than hand written. See the Logic App standard's connections section. + + "/properties/parameters/additionalProperties/allOf/1/properties/defaultValue": | + Used when no value is supplied at deployment. Lowest precedence of everything that can set a + parameter, so treat it as a fallback rather than as configuration. + + Never put a secret here. A `defaultValue` on a SecureString still lives in the definition file + and therefore in source control. + + "/properties/parameters/additionalProperties/allOf/1/properties/allowedValues": | + Constrains the accepted values. Cheap and underused: it turns a typo in a tfvars file into a + deployment error rather than a workflow that runs and does the wrong thing. + + "/properties/outputs": | + Values the run exposes when it finishes. Read them from the run history or, for a Request + trigger, return them with a Response action. + + Outputs are evaluated at the END of the run, so an expression here that references an action + which was skipped evaluates against nothing. Guard with `if()` rather than assuming the happy + path ran. + + "/properties/outputs/additionalProperties/allOf/0/properties/type": | + The eight WDL types: Array, Bool, Float, Int, Object, SecureObject, SecureString, String. + + SecureString and SecureObject are the ones that matter operationally. Their values are masked + in run history and, deployed through the azapi module, ride the provider's write-only + `sensitive_body` so they never reach Terraform state or plan output. A secret typed into the + designer and exported lands in a template file, so it must be moved to a secure parameter. + + "/properties/triggers": | + What starts a run. Every trigger is one of the nine types below and the key you give it is its + name, which is also the string every `@triggerBody()` and `runAfter` reference resolves + against. Renaming a trigger is a breaking change to the definition. + + Maximum 10 triggers, though the designer authors one. Names are stored keys: keep the + designer's underscore-escaped form rather than tidying it. + + "/properties/triggers/additionalProperties/allOf/1/properties/conditions": | + Guards that must be true for the trigger to fire. Filtering HERE is cheaper than filtering in a + first action, because on Consumption an action that runs is an action that bills. + + Typical use: only act on incident creation rather than every enrichment update, or only on a + severity floor. + + "/properties/triggers/additionalProperties/allOf/1/properties/splitOn": | + Debatching. Points at an array in the trigger output and starts one workflow RUN per element + rather than one run holding the array. + + Two consequences people meet the hard way. Run count, and therefore Consumption cost, becomes + a function of payload size. And `splitOn` cannot be combined with a synchronous Response: each + element is its own run, so there is no single response to return. + + "/properties/triggers/additionalProperties/allOf/1/properties/correlation": | + Sets the client tracking id for the run, which is what lets you find every run belonging to one + logical transaction across workflows. Set it from the upstream id (an incident number, a ticket + id) rather than leaving it to the platform, or cross-workflow triage becomes guesswork. + + "/properties/actions": | + The work, and the execution graph. The key is the action name and it is a stored key: it is + what `runAfter` and `@body('name')` reference, and what appears in run history. + + ORDERING IS `runAfter` AND NOTHING ELSE. There is no top-level sequence and the order keys + appear in the JSON is irrelevant. Deploying a definition whole keeps that as the only ordering + graph. Assembling the same workflow from per-resource Terraform resources creates a second + graph that can disagree with it. + + Maximum 250 actions. The designer escapes spaces to underscores in names; keep its form. + + "/properties/actions/additionalProperties/allOf/0/properties/runAfter": | + The dependency edge: a map of predecessor action name to the list of statuses that let this + action run. + + `"runAfter": {}` means "run first". An action whose predecessor finishes in a status NOT listed + is Skipped, not failed, and its own successors then evaluate against Skipped. + + THIS IS HOW TRY/CATCH IS BUILT. A catch action lists `["Failed", "TimedOut"]` on the scope it + guards; a finally action lists every terminal status. Getting the status list wrong produces a + workflow that silently skips its own error handling and reports success. + + Statuses: Succeeded, Failed, Skipped, TimedOut, Cancelled, Aborted, Faulted, Ignored, Paused, + Running, Suspended, Waiting. In practice a hand-authored definition uses the first five. + + "/properties/actions/additionalProperties/allOf/0/properties/trackedProperties": | + Key/value pairs emitted with the action's diagnostic record, so they are queryable in Log + Analytics without opening run history. This is the cheapest observability in Logic Apps and it + is almost always skipped. + + Track the correlating ids (incident number, ticket id, tenant) rather than payloads: tracked + properties land in logs, so anything sensitive here is a data protection problem. + + "/properties/actions/additionalProperties/allOf/1/properties/type": | + The action type, one of 38. Grouped by what they are for: + + CONTROL FLOW: If, Switch, Foreach, Until, Scope, Terminate. + DATA: Compose, ParseJson, Query, Select, Table, Join, Expression. + VARIABLES: InitializeVariable, SetVariable, AppendToArrayVariable, AppendToStringVariable, + IncrementVariable, DecrementVariable. + CALLING OUT: Http, HttpWebhook, ApiConnection, ApiConnectionWebhook, ApiManagement, Function, + Workflow, SendToBatch, Batch. + REQUEST/RESPONSE: Request, Response. + INTEGRATION ACCOUNT: Liquid, Xslt, XmlValidation, FlatFileEncoding, FlatFileDecoding, + IntegrationAccountArtifactLookup. + OTHER: Wait, Recurrence, SlidingWindow. + + `Workflow` dispatches to another workflow BY RESOURCE ID, and ARM validates that target exists + at PUT time (`NestedWorkflowNotFound`). Deploying a dispatcher therefore has to happen after + its target: the azapi module expresses that with `deploy_tier`. + + "/properties/actions/additionalProperties/allOf/1/properties/operationOptions": | + Per-action behaviour switches. The two worth knowing: + + `DisableAsyncPattern` makes an action that would return 202 and poll wait for the real result + instead, which is usually what you meant. + + `SuppressWorkflowHeaders` stops Logic Apps injecting its own headers into an outbound request, + which some strict endpoints reject. + + "/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration": | + Per-action runtime settings, and the home of the retry policy. + + `retryPolicy` defaults to `exponential`, 4 retries over roughly 20 seconds to 1 hour, on 408, + 429 and 5xx ONLY. A 4xx that is not 408 or 429 never retries, so an auth failure fails + immediately, which is correct. + + SET IT EXPLICITLY on anything that calls out. The default is rarely the right budget, and an + inherited default is a decision nobody made. `"type": "none"` is the honest way to say a call + must not be retried, which matters for anything non-idempotent. + + `staticResult` names an entry in the definition-level `staticResults` object to return mock + outputs, for testing. Note that `staticResults` itself is not declared in this schema. + + `concurrency` caps parallel iterations on Foreach and Until. Leaving it unset means the + platform picks, and a debatched trigger plus unbounded concurrency is how a downstream API + gets rate limited by your own workflow. + + "/properties/triggers/additionalProperties/allOf/2/oneOf/1": | + THE CATCH-ALL TRIGGER BRANCH. This branch declares no `type` and no properties, so it accepts + any trigger shape the eight typed branches above do not. + + That is why an `ApiConnectionWebhook` trigger validates: the schema has no branch modelling it, + despite it being a documented managed API trigger type and the shape of the Sentinel incident + trigger that starts most SOAR playbooks. It passes because nothing checks it, not because it + was checked. + + Practical consequence: a typo inside an ApiConnectionWebhook trigger is not caught here. The + plan-time guards in the azapi module cover the parts that matter (the `$connections` wiring and + the callback trigger name); the rest is caught at deploy. + +# --------------------------------------------------------------------------------------------- +# Corrections. +# +# The published schema rejects workflow definitions that Azure itself emits and deploys. These are +# not opinions: each one was found by validating 87 real workflow definitions from this workspace +# against the upstream schema, and the occurrence count is how many real actions it rejected. +# +# `generate.py` applies these to the annotated outputs and records them under `x-annotation`, so +# the annotated schema is usable as an editor schema without redlining correct code. Every change +# WIDENS what is accepted; none of them makes the schema accept less. +# +# Report upstream and delete the entry when it is fixed. +# --------------------------------------------------------------------------------------------- +corrections: + - id: retry-policy-type-casing + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/type + op: enum_add + values: [none, fixed, exponential] + occurrences: 39 + why: >- + The schema declares the enum PascalCase as None, Fixed and Exponential. The designer, every + Microsoft example and every real definition use lowercase. Both cases are accepted by the + platform, so the enum is widened rather than replaced. + + - id: retry-policy-count-expression + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/count + op: type_union + values: [integer, string] + occurrences: 5 + why: >- + Declared `integer`, which rejects `"count": "@parameters('retry_count')"`. Any WDL value may + be an expression string, so a typed scalar that does not also accept `string` is wrong + wherever an expression is legal. This is the general defect; `count` is where it bites. + + - id: authentication-managed-identity + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/authentication + op: oneof_add + occurrences: 28 + value: + type: object + properties: + type: + type: string + enum: [ManagedServiceIdentity] + description: The HTTP authentication type. + identity: + type: string + description: The resource id of a user-assigned managed identity. Omit for the system-assigned identity. + audience: + type: string + description: The audience the token is requested for, for example https://management.azure.com. + description: >- + Managed identity authentication. Added by Libre DevOps: the 2016-06-01 schema predates it + and has no branch for it, so the standard way to authenticate an Http action to an Azure + endpoint fails validation upstream. + why: >- + The `authentication` oneOf carries Basic, ClientCertificate, None, ActiveDirectoryOAuth and + Raw, but not ManagedServiceIdentity, which is the recommended and most common auth type for + an Http action calling Azure. 28 real actions in this workspace are rejected by it. + + - id: variable-type-casing + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType + op: enum_add + values: [array, boolean, float, integer, object, string] + occurrences: 3 + why: >- + Same casing defect as the retry policy, on InitializeVariable and SetVariable. The schema + declares Array, Boolean, Float, Integer, Object, String; the designer emits lowercase. + + - id: initialize-variable-multiple + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/34/properties/inputs/properties/variables + op: remove_key + values: [maxItems] + occurrences: 1 + why: >- + The schema caps `variables` at one item. The designer only offers one, but a portal code view + export taken from a live workflow in this workspace carries three, so the platform both emits + and accepts more. `minItems` is left in place. diff --git a/schema/generate.py b/schema/generate.py new file mode 100644 index 0000000..9112b3c --- /dev/null +++ b/schema/generate.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.10" +# dependencies = ["pyyaml>=6"] +# /// +"""Build the annotated Azure Logic Apps workflow definition schema, as JSON and YAML. + +The published schema validates a definition but does not teach one: 147 KB of machine-generated +JSON with no `definitions` section, everything inlined through allOf/oneOf, and descriptions that +restate the property name. It also says nothing about the behaviours that pass validation and then +fail at run time. + +This merges `annotations.yaml` into the upstream schema's `description` fields and writes: + + workflowdefinition.annotated.schema.json the validator, with the notes inside descriptions + workflowdefinition.annotated.schema.yaml the same document, readable, notes as block scalars + +Both remain valid JSON Schema draft-04 and still validate a real workflow definition, because the +only thing added is `description`, which carries no validation semantics. + +Every annotation pointer is asserted to exist. If Microsoft reshapes the schema, this fails loudly +rather than dropping notes on the floor. + +Usage: + uv run schema/generate.py # refresh from the live upstream schema + uv run schema/generate.py --offline # rebuild from the committed upstream copy + uv run schema/generate.py --check # fail if the committed outputs are stale + +Exit codes: 0 clean, 1 stale or a fetch failed, 2 a pointer no longer resolves. +""" +from __future__ import annotations + +import argparse +import json +import sys +import urllib.error +import urllib.request +from pathlib import Path + +import yaml + + +class _BlockDumper(yaml.SafeDumper): + """Dump multi-line strings as literal blocks, so the annotations stay readable in YAML.""" + + +def _str_representer(dumper: yaml.SafeDumper, data: str): + if "\n" in data: + # Trailing whitespace on a line makes a literal block unparseable, so strip it. + cleaned = "\n".join(line.rstrip() for line in data.split("\n")) + return dumper.represent_scalar("tag:yaml.org,2002:str", cleaned, style="|") + return dumper.represent_scalar("tag:yaml.org,2002:str", data) + + +_BlockDumper.add_representer(str, _str_representer) + +HERE = Path(__file__).resolve().parent +ANNOTATIONS = HERE / "annotations.yaml" +UPSTREAM_COPY = HERE / "workflowdefinition.schema.json" +OUT_JSON = HERE / "workflowdefinition.annotated.schema.json" +OUT_YAML = HERE / "workflowdefinition.annotated.schema.yaml" + +UPSTREAM_URL = ( + "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/" + "2016-06-01/workflowdefinition.json" +) + + +def fetch(url: str) -> str: + request = urllib.request.Request(url, headers={"User-Agent": "libre-devops-schema-annotator"}) + with urllib.request.urlopen(request, timeout=60) as response: + return response.read().decode("utf-8") + + +def resolve(document: object, pointer: str) -> object: + """Resolve a JSON Pointer (RFC 6901). The empty pointer is the document itself.""" + if pointer == "": + return document + node = document + for raw in pointer.lstrip("/").split("/"): + token = raw.replace("~1", "/").replace("~0", "~") + if isinstance(node, list): + node = node[int(token)] + elif isinstance(node, dict): + node = node[token] + else: + raise KeyError(pointer) + return node + + +def annotate(schema: dict, notes: dict[str, str]) -> int: + """Merge each note into the description at its pointer. Returns the count applied.""" + applied = 0 + for pointer, note in notes.items(): + try: + node = resolve(schema, pointer) + except (KeyError, IndexError, ValueError): + print(f"error: pointer no longer resolves: {pointer!r}", file=sys.stderr) + print(" the upstream schema has been reshaped; fix annotations.yaml", file=sys.stderr) + raise SystemExit(2) + if not isinstance(node, dict): + print(f"error: pointer does not address an object: {pointer!r}", file=sys.stderr) + raise SystemExit(2) + + upstream = (node.get("description") or "").strip() + body = note.strip() + # Keep Microsoft's own wording first where it says anything, then the annotation. The + # upstream text is often a bare restatement, so it is dropped when the note subsumes it. + if upstream and upstream.rstrip(".").lower() not in body.lower(): + node["description"] = f"{upstream}\n\n{body}" + else: + node["description"] = body + applied += 1 + return applied + + +def correct(schema: dict, corrections: list[dict]) -> list[dict]: + """Apply each widening correction. Returns a record of what was applied.""" + applied = [] + for fix in corrections: + pointer, op = fix["pointer"], fix["op"] + try: + node = resolve(schema, pointer) + except (KeyError, IndexError, ValueError): + print(f"error: correction {fix['id']!r} pointer no longer resolves: {pointer}", file=sys.stderr) + raise SystemExit(2) + + if op == "enum_add": + missing = [v for v in fix["values"] if v not in node.get("enum", [])] + node.setdefault("enum", []).extend(missing) + elif op == "type_union": + node["type"] = list(fix["values"]) + elif op == "oneof_add": + node.setdefault("oneOf", []).append(fix["value"]) + elif op == "remove_key": + for key in fix["values"]: + node.pop(key, None) + else: + print(f"error: unknown correction op {op!r} in {fix['id']!r}", file=sys.stderr) + raise SystemExit(2) + + node["description"] = ( + (node.get("description") or "").strip() + + f"\n\nCORRECTED BY LIBRE DEVOPS ({fix['id']}): {' '.join(fix['why'].split())} " + + f"Rejected {fix['occurrences']} real action(s) upstream." + ).strip() + applied.append({k: fix[k] for k in ("id", "pointer", "op", "occurrences", "why") if k in fix}) + return applied + + +def build(schema: dict, meta: dict, notes: dict[str, str], corrections: list[dict]) -> dict: + annotated = json.loads(json.dumps(schema)) # deep copy, keeps ordering + count = annotate(annotated, notes) + fixes = correct(annotated, corrections) + annotated["x-annotation"] = { + **meta, + "notes_applied": count, + "corrections": fixes, + "generated_by": "schema/generate.py", + "warning": ( + "Generated file. Edit schema/annotations.yaml and regenerate; edits here are lost. " + "Validation differs from upstream ONLY by the corrections listed above, each of which " + "widens what is accepted so that definitions Azure itself emits stop being rejected." + ), + } + return annotated + + +def yaml_header(meta: dict, count: int) -> str: + return ( + "# Azure Logic Apps workflow definition schema, annotated.\n" + "#\n" + f"# Upstream: {meta['upstream']}\n" + f"# Annotations by {meta['annotated_by']}, checked {meta['annotations_checked']}.\n" + f"# {count} annotations applied.\n" + "#\n" + "# CORRECTED: the upstream schema rejects definitions Azure itself emits. See\n" + "# x-annotation.corrections at the end of this file for each change and why.\n" + "#\n" + "# GENERATED FILE. Edit schema/annotations.yaml and run schema/generate.py.\n" + "#\n" + "# This is the SCHEMA in YAML, for readability and for tools that accept a YAML schema.\n" + "# A workflow definition itself is JSON: Workflow Definition Language has no YAML dialect.\n" + "#\n" + "# Validation differs from upstream only by those corrections, each of which WIDENS what\n" + "# is accepted. Nothing here makes the schema stricter.\n" + "---\n" + ) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--offline", action="store_true", help="rebuild from the committed upstream copy") + parser.add_argument("--check", action="store_true", help="fail if the committed outputs are stale") + args = parser.parse_args() + + spec = yaml.safe_load(ANNOTATIONS.read_text(encoding="utf-8")) + meta, notes, corrections = spec["meta"], spec["notes"], spec.get("corrections", []) + + if args.offline or args.check: + if not UPSTREAM_COPY.exists(): + print(f"error: {UPSTREAM_COPY.name} is missing; run without --offline first", file=sys.stderr) + return 1 + raw = UPSTREAM_COPY.read_text(encoding="utf-8") + else: + try: + raw = fetch(UPSTREAM_URL) + except (urllib.error.URLError, TimeoutError) as exc: + print(f"error: fetching the upstream schema failed: {exc}", file=sys.stderr) + return 1 + + schema = json.loads(raw) + annotated = build(schema, meta, notes, corrections) + + out_json = json.dumps(annotated, indent=2, ensure_ascii=False) + "\n" + out_yaml = yaml_header(meta, annotated["x-annotation"]["notes_applied"]) + yaml.dump( + annotated, + Dumper=_BlockDumper, + sort_keys=False, + default_flow_style=False, + allow_unicode=True, + width=100, + ) + + if args.check: + stale = [ + path.name + for path, want in ((OUT_JSON, out_json), (OUT_YAML, out_yaml)) + if not path.exists() or path.read_text(encoding="utf-8") != want + ] + if stale: + print("stale: " + ", ".join(stale), file=sys.stderr) + print("run: uv run schema/generate.py --offline", file=sys.stderr) + return 1 + print(f"clean: {OUT_JSON.name}, {OUT_YAML.name}") + return 0 + + if not args.offline: + UPSTREAM_COPY.write_text(raw if raw.endswith("\n") else raw + "\n", encoding="utf-8") + OUT_JSON.write_text(out_json, encoding="utf-8") + OUT_YAML.write_text(out_yaml, encoding="utf-8") + + print(f"{annotated['x-annotation']['notes_applied']} annotations applied, " + f"{len(annotated['x-annotation']['corrections'])} corrections applied") + for path in (UPSTREAM_COPY, OUT_JSON, OUT_YAML): + if path.exists(): + print(f" {path.name:46} {path.stat().st_size:>9,} bytes") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/schema/workflowdefinition.annotated.schema.json b/schema/workflowdefinition.annotated.schema.json new file mode 100644 index 0000000..2657912 --- /dev/null +++ b/schema/workflowdefinition.annotated.schema.json @@ -0,0 +1,2541 @@ +{ + "$id": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Logic App Template Schema", + "description": "The workflow.\n\nA Logic Apps workflow definition, schema version 2016-06-01.\n\nTHE SHAPE. Six properties carry everything: `triggers` starts the run, `actions` do the work,\n`parameters` declares what varies between environments, `outputs` exposes results,\n`contentVersion` stamps the definition, and `$schema` points here.\n\nWHAT THIS DOCUMENT IS NOT. This schema describes the JSON. It does NOT describe the `@{...}`\nruntime expression layer inside those strings. A definition can be schema-valid and still fail\nat run time because an expression referenced a missing property or evaluated an operand it\nshould not have. See the expression functions reference, and the pitfalls section of the\nLibre DevOps Logic App standard.\n\nTHERE IS NO YAML DIALECT. A workflow definition is JSON. The YAML rendering of THIS SCHEMA\nexists for readability and for tools that accept YAML schemas; it does not mean a definition\nmay be written in YAML.\n\nPLATFORM LIMITS the schema does not encode: maximum 250 actions, maximum 10 triggers. The\ndesigner authors a single trigger; more than one is expressible only in the language itself.\n\nDOCUMENTED BUT ABSENT: `staticResults`, referenced by `runtimeConfiguration.staticResult.name`\non an action, is documented as a definition-level attribute and is NOT declared in this\nschema's root `properties`. Using it validates only because the root does not forbid unknown\nproperties.", + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "runAfter": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Aborted", + "Cancelled", + "Failed", + "Faulted", + "Ignored", + "Paused", + "Running", + "Skipped", + "Succeeded", + "Suspended", + "TimedOut", + "Waiting" + ], + "description": "The status of a flow." + } + }, + "description": "The operation run after.\n\nThe dependency edge: a map of predecessor action name to the list of statuses that let this\naction run.\n\n`\"runAfter\": {}` means \"run first\". An action whose predecessor finishes in a status NOT listed\nis Skipped, not failed, and its own successors then evaluate against Skipped.\n\nTHIS IS HOW TRY/CATCH IS BUILT. A catch action lists `[\"Failed\", \"TimedOut\"]` on the scope it\nguards; a finally action lists every terminal status. Getting the status list wrong produces a\nworkflow that silently skips its own error handling and reports success.\n\nStatuses: Succeeded, Failed, Skipped, TimedOut, Cancelled, Aborted, Faulted, Ignored, Paused,\nRunning, Suspended, Waiting. In practice a hand-authored definition uses the first five." + }, + "trackedProperties": { + "description": "The tracked properties.\n\nKey/value pairs emitted with the action's diagnostic record, so they are queryable in Log\nAnalytics without opening run history. This is the cheapest observability in Logic Apps and it\nis almost always skipped.\n\nTrack the correlating ids (incident number, ticket id, tenant) rather than payloads: tracked\nproperties land in logs, so anything sensitive here is a data protection problem." + } + } + }, + { + "type": "object", + "properties": { + "metadata": { + "description": "The operation metadata." + }, + "type": { + "type": "string", + "enum": [ + "ApiConnection", + "ApiConnectionWebhook", + "ApiManagement", + "AppendToArrayVariable", + "AppendToStringVariable", + "Batch", + "Compose", + "DecrementVariable", + "Expression", + "FlatFileDecoding", + "FlatFileEncoding", + "Foreach", + "Function", + "Http", + "HttpWebhook", + "If", + "IncrementVariable", + "InitializeVariable", + "IntegrationAccountArtifactLookup", + "Join", + "Liquid", + "ParseJson", + "Query", + "Recurrence", + "Request", + "Response", + "Scope", + "Select", + "SendToBatch", + "SetVariable", + "SlidingWindow", + "Switch", + "Table", + "Terminate", + "Until", + "Wait", + "Workflow", + "XmlValidation", + "Xslt" + ], + "description": "The type of the flow operation.\n\nThe action type, one of 38. Grouped by what they are for:\n\nCONTROL FLOW: If, Switch, Foreach, Until, Scope, Terminate.\nDATA: Compose, ParseJson, Query, Select, Table, Join, Expression.\nVARIABLES: InitializeVariable, SetVariable, AppendToArrayVariable, AppendToStringVariable,\nIncrementVariable, DecrementVariable.\nCALLING OUT: Http, HttpWebhook, ApiConnection, ApiConnectionWebhook, ApiManagement, Function,\nWorkflow, SendToBatch, Batch.\nREQUEST/RESPONSE: Request, Response.\nINTEGRATION ACCOUNT: Liquid, Xslt, XmlValidation, FlatFileEncoding, FlatFileDecoding,\nIntegrationAccountArtifactLookup.\nOTHER: Wait, Recurrence, SlidingWindow.\n\n`Workflow` dispatches to another workflow BY RESOURCE ID, and ARM validates that target exists\nat PUT time (`NestedWorkflowNotFound`). Deploying a dispatcher therefore has to happen after\nits target: the azapi module expresses that with `deploy_tier`." + }, + "kind": { + "type": "string", + "enum": [ + "AddToTime", + "Alert", + "ApiConnection", + "AzureMonitorAlert", + "Button", + "ConvertTimeZone", + "CurrentTime", + "EventGrid", + "Geofence", + "GetFutureTime", + "GetPastTime", + "Http", + "JsonToJson", + "JsonToText", + "PowerApp", + "SecurityCenterAlert", + "SubtractFromTime", + "XmlToJson", + "XmlToText" + ], + "description": "The kind of the flow operation." + }, + "description": { + "type": "string", + "description": "The operation description." + }, + "operationOptions": { + "type": "string", + "description": "The operation options.\n\nPer-action behaviour switches. The two worth knowing:\n\n`DisableAsyncPattern` makes an action that would return 202 and poll wait for the real result\ninstead, which is usually what you meant.\n\n`SuppressWorkflowHeaders` stops Logic Apps injecting its own headers into an outbound request,\nwhich some strict endpoints reject." + }, + "runtimeConfiguration": { + "type": "object", + "properties": { + "paginationPolicy": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowPaginationPolicy" + }, + "contentTransfer": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferConfiguration" + }, + "concurrency": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowConcurrencyConfiguration" + } + }, + "description": "The flow template operation runtime configuration.\n\nPer-action runtime settings, and the home of the retry policy.\n\n`retryPolicy` defaults to `exponential`, 4 retries over roughly 20 seconds to 1 hour, on 408,\n429 and 5xx ONLY. A 4xx that is not 408 or 429 never retries, so an auth failure fails\nimmediately, which is correct.\n\nSET IT EXPLICITLY on anything that calls out. The default is rarely the right budget, and an\ninherited default is a decision nobody made. `\"type\": \"none\"` is the honest way to say a call\nmust not be retried, which matters for anything non-idempotent.\n\n`staticResult` names an entry in the definition-level `staticResults` object to return mock\noutputs, for testing. Note that `staticResults` itself is not declared in this schema.\n\n`concurrency` caps parallel iterations on Foreach and Until. Leaving it unset means the\nplatform picks, and a debatched trigger plus unbounded concurrency is how a downstream API\ngets rate limited by your own workflow.", + "definitions": { + "FlowConcurrencyConfiguration": { + "type": "object", + "properties": { + "repetitions": { + "type": "integer", + "description": "The repetitions." + }, + "runs": { + "type": "integer", + "description": "The runs." + }, + "maximumWaitingRuns": { + "type": "integer", + "description": "The maximum waiting runs." + } + }, + "description": "The flow concurrency configuration." + }, + "FlowContentTransferConfiguration": { + "type": "object", + "properties": { + "transferMode": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferMode" + } + }, + "description": "The flow content transfer configuration." + }, + "FlowContentTransferMode": { + "type": "string", + "enum": [ + "Chunked" + ], + "description": "The flow content transfer mode." + }, + "FlowPaginationPolicy": { + "type": "object", + "properties": { + "minimumItemCount": { + "type": "integer", + "description": "The minimum item count." + } + }, + "description": "The flow pagination policy." + } + } + } + }, + "required": [ + "type" + ] + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnection" + ] + }, + "inputs": { + "allOf": [ + { + "type": "object", + "properties": { + "host": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host" + }, + "method": { + "type": "string", + "default": "POST", + "description": "The method of the request." + }, + "path": { + "type": "string", + "description": "The path for the request." + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "host", + "path" + ] + }, + { + "type": "object", + "properties": { + "operationOptions": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/operationOptions" + }, + "retryPolicy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "None", + "Fixed", + "Exponential", + "none", + "fixed", + "exponential" + ], + "description": "The type of retry policy to use.\n\nCORRECTED BY LIBRE DEVOPS (retry-policy-type-casing): The schema declares the enum PascalCase as None, Fixed and Exponential. The designer, every Microsoft example and every real definition use lowercase. Both cases are accepted by the platform, so the enum is widened rather than replaced. Rejected 39 real action(s) upstream." + }, + "interval": { + "type": "string", + "description": "The interval between retries." + }, + "count": { + "type": [ + "integer", + "string" + ], + "description": "The number of times a retry should be attempted.\n\nCORRECTED BY LIBRE DEVOPS (retry-policy-count-expression): Declared `integer`, which rejects `\"count\": \"@parameters('retry_count')\"`. Any WDL value may be an expression string, so a typed scalar that does not also accept `string` is wrong wherever an expression is legal. This is the general defect; `count` is where it bites. Rejected 5 real action(s) upstream." + }, + "minimumInterval": { + "type": "string", + "description": "The minimum time delay for the exponential retry." + }, + "maximumInterval": { + "type": "string", + "description": "The maximum time delay for the exponential retry." + } + }, + "description": "The retry policy." + }, + "authentication": { + "oneOf": [ + { + "type": "string", + "description": "A Logic Apps expression." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Basic" + ], + "description": "The HTTP authentication type." + }, + "username": { + "type": "string", + "description": "The username." + }, + "password": { + "type": "string", + "description": "The password." + } + }, + "description": "The HTTP basic authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ClientCertificate" + ], + "description": "The HTTP authentication type." + }, + "password": { + "type": "string", + "description": "The password." + }, + "pfx": { + "type": "string", + "description": "The PFX." + } + }, + "description": "The HTTP client certificate authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "None" + ], + "description": "The HTTP authentication type." + } + }, + "additionalProperties": false, + "description": "No HTTP authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ActiveDirectoryOAuth" + ], + "description": "The HTTP authentication type." + }, + "authority": { + "type": "string", + "description": "The authority." + }, + "tenant": { + "type": "string", + "description": "The tenant ID." + }, + "audience": { + "type": "string", + "description": "The audience." + }, + "clientId": { + "type": "string", + "description": "The client ID." + }, + "secret": { + "type": "string", + "description": "The secret." + }, + "pfx": { + "type": "string", + "description": "The PFX." + }, + "password": { + "type": "string", + "description": "The password used to decrypt the PFX." + } + }, + "description": "The HTTP OAuth authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Raw" + ], + "description": "The HTTP authentication type." + }, + "scheme": { + "type": "string", + "description": "The raw authentication scheme." + }, + "parameter": { + "type": "string", + "description": "The raw authentication parameter." + }, + "value": { + "type": "string", + "description": "The raw authentication value." + } + }, + "description": "The HTTP raw authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ManagedServiceIdentity" + ], + "description": "The HTTP authentication type." + }, + "identity": { + "type": "string", + "description": "The resource id of a user-assigned managed identity. Omit for the system-assigned identity." + }, + "audience": { + "type": "string", + "description": "The audience the token is requested for, for example https://management.azure.com." + } + }, + "description": "Managed identity authentication. Added by Libre DevOps: the 2016-06-01 schema predates it and has no branch for it, so the standard way to authenticate an Http action to an Azure endpoint fails validation upstream." + } + ], + "description": "The HTTP authentication.\n\nCORRECTED BY LIBRE DEVOPS (authentication-managed-identity): The `authentication` oneOf carries Basic, ClientCertificate, None, ActiveDirectoryOAuth and Raw, but not ManagedServiceIdentity, which is the recommended and most common auth type for an Http action calling Azure. 28 real actions in this workspace are rejected by it. Rejected 28 real action(s) upstream." + } + }, + "description": "The retryable action input." + } + ], + "description": "The ApiConnection operation input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnectionWebhook" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs" + }, + { + "type": "object", + "properties": { + "schema": { + "description": "The schema of an API connection webhook operation." + }, + "accessKeyType": { + "type": "string", + "enum": [ + "Primary", + "Secondary" + ], + "description": "The access key type." + } + } + } + ], + "description": "The API connection webhook operation input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiManagement" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "api": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/ApiManagementApiReference" + }, + "method": { + "type": "string", + "description": "The method of the request." + }, + "pathTemplate": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/PathTemplate" + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "body": { + "description": "The body of the request." + }, + "subscriptionKey": { + "type": "string", + "description": "The subscription key." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "api", + "pathTemplate" + ] + } + ], + "description": "The API Management operation input.", + "definitions": { + "ApiManagementApiReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The API Management API reference." + }, + "PathTemplate": { + "description": "The path template for the request." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "SendToBatch" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "host": { + "type": "object", + "properties": { + "workflow": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host/definitions/FlowReference" + }, + "triggerName": { + "type": "string", + "description": "The trigger name." + } + }, + "required": [ + "triggerName", + "workflow" + ], + "description": "The workflow host.", + "definitions": { + "FlowReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + }, + { + "required": [ + "id" + ] + } + ], + "description": "The flow reference." + } + } + }, + "batchName": { + "type": "string", + "description": "The batch name." + }, + "partitionName": { + "type": "string", + "description": "The partition name." + }, + "messageId": { + "type": "string", + "description": "The message identifier." + }, + "content": { + "description": "The content." + } + }, + "required": [ + "host", + "batchName", + "content" + ] + } + ], + "description": "The Send to Batch action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Compose" + ] + }, + "inputs": { + "description": "The Compose action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "AddToTime" + ] + }, + "inputs": { + "type": "object", + "properties": { + "baseTime": { + "type": "string", + "description": "The base time." + }, + "interval": { + "type": "integer", + "description": "The interval of time." + }, + "timeUnit": { + "type": "string", + "description": "The unit of time specified." + } + }, + "required": [ + "baseTime", + "interval", + "timeUnit" + ], + "description": "The inputs for the add to time or subtract from time operation kinds." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "ConvertTimeZone" + ] + }, + "inputs": { + "type": "object", + "properties": { + "baseTime": { + "type": "string", + "description": "The base time." + }, + "sourceTimeZone": { + "type": "string", + "description": "The time zone to convert from." + }, + "destinationTimeZone": { + "type": "string", + "description": "The time zone to convert to." + }, + "formatString": { + "type": "string", + "description": "The date time format string." + } + }, + "required": [ + "baseTime", + "sourceTimeZone", + "destinationTimeZone" + ], + "description": "The convert time zone operation kind input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "CurrentTime" + ] + }, + "inputs": { + "type": "object", + "additionalProperties": false + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "GetFutureTime" + ] + }, + "inputs": { + "type": "object", + "properties": { + "interval": { + "type": "integer", + "description": "The interval of time." + }, + "timeUnit": { + "type": "string", + "description": "The unit of time specified." + } + }, + "required": [ + "interval", + "timeUnit" + ], + "description": "The inputs for the get future time and get past time operation kinds." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "GetPastTime" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/8/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "SubtractFromTime" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/5/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "FlatFileDecoding" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "integrationAccount": { + "type": "object", + "properties": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name." + } + }, + "required": [ + "name" + ], + "description": "The artifact information." + } + }, + "required": [ + "schema" + ], + "description": "The integration account schema information." + } + }, + "required": [ + "content", + "integrationAccount" + ] + } + ], + "description": "The content and schema action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "FlatFileEncoding" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs" + }, + { + "type": "object", + "properties": { + "emptyNodeGenerationMode": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/12/properties/inputs/definitions/EmptyNodeGenerationMode" + } + } + } + ], + "description": "The flat file encoding action input.", + "definitions": { + "EmptyNodeGenerationMode": { + "type": "string", + "enum": [ + "ForcedDisabled", + "ForcedEnabled", + "HonorSchemaNodeProperty" + ], + "description": "The empty node generation mode." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Function" + ] + }, + "inputs": { + "type": "object", + "allOf": [ + { + "properties": { + "function": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference" + } + } + }, + { + "properties": { + "functionApp": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionAppReference" + }, + "uri": { + "type": "string", + "description": "The operation URI as defined in the function app Swagger." + } + } + } + ], + "properties": { + "method": { + "type": "string", + "description": "The method of the request." + }, + "queries": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "description": "The queries for the request." + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "description": "The function action input.", + "definitions": { + "FunctionAppReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The function app reference." + }, + "FunctionReference": { + "allOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The resource reference identifier." + }, + "name": { + "type": "string", + "description": "The resource reference name." + }, + "type": { + "type": "string", + "description": "The resource reference type." + } + }, + "description": "The base resource reference." + } + ], + "description": "The function reference." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Http" + ] + }, + "inputs": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + } + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/5" + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "IntegrationAccountArtifactLookup" + ] + }, + "inputs": { + "type": "object", + "properties": { + "artifactType": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/16/properties/inputs/definitions/ArtifactType" + }, + "artifaceName": { + "type": "string", + "description": "The name of the artifact." + } + }, + "description": "The integration account artifact lookup input.", + "definitions": { + "ArtifactType": { + "type": "string", + "enum": [ + "Schema", + "Map", + "Partner", + "Agreement" + ], + "description": "The type of artifact." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Join" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "joinWith": { + "type": "string", + "description": "The separator." + } + }, + "required": [ + "from" + ], + "description": "The Join action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Liquid" + ] + }, + "kind": { + "enum": [ + "JsonToJson", + "JsonToText", + "XmlToJson", + "XmlToText" + ] + }, + "inputs": { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "integrationAccount": { + "type": "object", + "properties": { + "map": { + "#ref": "common/ArtifactInformation.json" + } + }, + "required": [ + "map" + ], + "description": "The integration account map information." + }, + "transformedContentSchema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "required": [ + "content", + "integrationAccount" + ], + "description": "The liquid action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ParseJson" + ] + }, + "inputs": { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "description": "The Parse JSON action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Query" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "where": { + "type": "string", + "description": "The where condition." + } + }, + "required": [ + "from" + ], + "description": "The query action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Response" + ] + }, + "inputs": { + "type": "object", + "properties": { + "statusCode": { + "type": [ + "integer", + "string" + ], + "description": "The status code for the response." + }, + "headers": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + } + } + ], + "description": "The headers for the request." + }, + "body": { + "description": "The body of the response." + }, + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "required": [ + "statusCode" + ], + "description": "The response action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Foreach" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "foreach": { + "type": [ + "array", + "string" + ], + "description": "The For Each expression." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "If" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "else": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfElseProperty" + }, + "expression": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfExpressionObjectProperty" + } + ], + "description": "The If expression." + } + }, + "definitions": { + "IfElseProperty": { + "type": "object", + "properties": { + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + } + }, + "IfExpressionObjectProperty": { + "description": "The If object expression property.", + "$comment": "TODO(joechung): Find out what the schema is for If expression objects." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Scope" + ] + }, + "inputs": { + "type": "object", + "properties": { + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Switch" + ] + }, + "cases": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/definitions/FlowTemplateActionCaseBranch" + }, + "description": "The Switch action case branches." + }, + "default": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "description": "The actions." + } + }, + "description": "The flow template action branch." + }, + "expression": { + "type": [ + "number", + "string" + ], + "description": "The Switch expression." + } + }, + "definitions": { + "FlowTemplateActionCaseBranch": { + "type": "object", + "properties": { + "case": { + "description": "The case." + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + }, + "required": [ + "case" + ], + "description": "The flow template action case branch." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Until" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "expression": { + "type": "string", + "description": "The Until expression." + }, + "limit": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/26/definitions/UntilLimitProperty" + } + }, + "definitions": { + "UntilLimitProperty": { + "type": "object", + "properties": { + "count": { + "type": [ + "number", + "string" + ], + "description": "The until count limit." + }, + "timeout": { + "type": "string", + "description": "The until timeout limit." + } + }, + "description": "The Until limits." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Select" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The select source." + }, + "select": { + "description": "The select transform." + } + }, + "required": [ + "from", + "select" + ], + "description": "The Select action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Table" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "format": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableFormat" + }, + "columns": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableColumn" + } + } + }, + "required": [ + "from" + ], + "description": "The table action input.", + "definitions": { + "TableColumn": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The header." + }, + "value": { + "description": "The value." + } + }, + "description": "The table column." + }, + "TableFormat": { + "type": "string", + "enum": [ + "CSV", + "HTML" + ], + "description": "The table format." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Terminate" + ] + }, + "inputs": { + "type": "object", + "properties": { + "runStatus": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/0/properties/runAfter/additionalProperties/items" + }, + { + "enum": [ + "Cancelled", + "Failed", + "Succeeded" + ] + } + ] + }, + "runError": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/29/properties/inputs/definitions/TerminateActionRunError" + } + }, + "description": "The Terminate action input.", + "definitions": { + "TerminateActionRunError": { + "type": "object", + "properties": { + "code": { + "type": [ + "number", + "string" + ], + "description": "The code." + }, + "message": { + "type": "string", + "description": "The message." + } + }, + "description": "The run error." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "AppendToArrayVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "AppendToStringVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "DecrementVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "IncrementVariable" + ] + }, + "inputs": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name." + }, + "type": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType" + }, + "value": { + "description": "The variable value." + } + }, + "description": "The variable action input.", + "definitions": { + "FlowVariableDataType": { + "type": "string", + "enum": [ + "Array", + "Boolean", + "Float", + "Integer", + "Object", + "String", + "array", + "boolean", + "float", + "integer", + "object", + "string" + ], + "description": "The flow variable data type.\n\nCORRECTED BY LIBRE DEVOPS (variable-type-casing): Same casing defect as the retry policy, on InitializeVariable and SetVariable. The schema declares Array, Boolean, Float, Integer, Object, String; the designer emits lowercase. Rejected 3 real action(s) upstream." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "InitializeVariable" + ] + }, + "inputs": { + "type": "object", + "properties": { + "variables": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + }, + "minItems": 1, + "description": "CORRECTED BY LIBRE DEVOPS (initialize-variable-multiple): The schema caps `variables` at one item. The designer only offers one, but a portal code view export taken from a live workflow in this workspace carries three, so the platform both emits and accepts more. `minItems` is left in place. Rejected 1 real action(s) upstream." + } + }, + "description": "The Initialize Variable action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "SetVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Wait" + ] + }, + "inputs": { + "type": "object", + "properties": { + "interval": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/TimeInterval" + }, + "until": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/WaitUntil" + } + }, + "maxProperties": 1, + "description": "The Wait action input.", + "definitions": { + "TimeInterval": { + "type": "object", + "properties": { + "unit": { + "allOf": [ + { + "description": "The wait unit." + }, + { + "type": "string", + "enum": [ + "Second", + "Minute", + "Hour", + "Day", + "Week", + "Month", + "Year" + ] + } + ] + }, + "count": { + "type": "integer", + "description": "The wait count." + } + }, + "description": "The wait interval." + }, + "WaitUntil": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "description": "The timestamp." + } + }, + "description": "The Until." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Workflow" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "host": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host" + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "host" + ] + } + ], + "description": "The flow action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "XmlValidation" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Xslt" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "parameters": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The XSLT (Extensible Stylesheet Language Transformations) parameters." + }, + "integrationAccount": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/18/properties/inputs/properties/integrationAccount" + }, + "function": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The function reference." + }, + "transformOptions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/39/properties/inputs/definitions/XsltTransformOptions" + } + }, + "required": [ + "content" + ] + } + ], + "description": "The XSLT (Extensible Stylesheet Language Transformations) action input.", + "definitions": { + "XsltTransformOptions": { + "type": "string", + "description": "The XSLT options flag." + } + } + } + } + } + ] + } + ], + "description": "A flow template action.", + "definitions": { + "FlowTemplateActionBranch": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties" + }, + "description": "The actions." + } + }, + "description": "The flow template action branch." + }, + "FlowTemplateActionCaseBranch": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/definitions/FlowTemplateActionBranch" + }, + { + "type": "object", + "properties": { + "case": { + "description": "The case." + } + }, + "required": [ + "case" + ], + "description": "The flow template action case branch." + } + ] + }, + "FlowTemplateActionUntil": { + "type": "object", + "properties": { + "limit": { + "description": "The do-until limit." + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "The expression." + }, + "dependsOn": { + "type": "string", + "description": "The dependency." + } + }, + "description": "The template action expression condition." + }, + "description": "The do-until conditions." + } + }, + "description": "The do-until policy." + } + } + }, + "description": "The flow run actions.\n\nThe work, and the execution graph. The key is the action name and it is a stored key: it is\nwhat `runAfter` and `@body('name')` reference, and what appears in run history.\n\nORDERING IS `runAfter` AND NOTHING ELSE. There is no top-level sequence and the order keys\nappear in the JSON is irrelevant. Deploying a definition whole keeps that as the only ordering\ngraph. Assembling the same workflow from per-resource Terraform resources creates a second\ngraph that can disagree with it.\n\nMaximum 250 actions. The designer escapes spaces to underscores in names; keep its form." + }, + "metadata": { + "description": "The definition metadata.\n\nArbitrary key/value metadata carried with the definition. The designer writes its own entries\nhere. Leave what the designer put there alone: rewriting it is how a template stops diffing\ncleanly against a fresh export." + }, + "$schema": { + "enum": [ + "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#" + ], + "type": "string", + "description": "The definition schema.\n\nThe schema location. Required by this document, and the string that makes an editor validate\nthe file as you type. Keep it as exported." + }, + "contentVersion": { + "type": "string", + "pattern": "(^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$)", + "description": "The flow content version. Specify using a 4-digit format, e.g., 1.0.0.0\n\nYour version stamp for the definition, \"1.0.0.0\" by default. It is metadata: the platform does\nnot use it to order or reject deployments. Worth setting so a deployed workflow can be matched\nback to a commit." + }, + "parameters": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/properties/outputs/additionalProperties/allOf/0" + }, + { + "properties": { + "defaultValue": { + "description": "The default parameter value.\n\nUsed when no value is supplied at deployment. Lowest precedence of everything that can set a\nparameter, so treat it as a fallback rather than as configuration.\n\nNever put a secret here. A `defaultValue` on a SecureString still lives in the definition file\nand therefore in source control." + }, + "allowedValues": { + "type": "array", + "description": "The allowed parameter values.\n\nConstrains the accepted values. Cheap and underused: it turns a typo in a tfvars file into a\ndeployment error rather than a workflow that runs and does the wrong thing." + } + }, + "description": "The flow input template parameter." + } + ] + }, + "description": "The flow parameters.\n\nParameter DECLARATIONS, not values. This is the single most misunderstood part of deploying a\nworkflow as code.\n\nA declaration says a parameter exists, its type, and optionally a default and allowed values.\nThe VALUE lives outside the definition, in the ARM/azapi request body's `properties.parameters`.\nA portal export carries both halves, which is why an unedited export deploys.\n\nAnything declared here with no value anywhere fails at deploy with `InvalidTemplate`, \"the\nvalue for the workflow parameter ... is not provided\". Catch it at plan time instead.\n\n`$connections` is declared here like any other parameter, and its value is generated rather\nthan hand written. See the Logic App standard's connections section." + }, + "triggers": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/1" + }, + { + "type": "object", + "properties": { + "conditions": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/definitions/FlowTemplateActionUntil/properties/conditions/items" + }, + "description": "The operation conditions.\n\nGuards that must be true for the trigger to fire. Filtering HERE is cheaper than filtering in a\nfirst action, because on Consumption an action that runs is an action that bills.\n\nTypical use: only act on incident creation rather than every enrichment update, or only on a\nseverity floor." + }, + "splitOn": { + "type": "string", + "description": "The trigger split on.\n\nDebatching. Points at an array in the trigger output and starts one workflow RUN per element\nrather than one run holding the array.\n\nTwo consequences people meet the hard way. Run count, and therefore Consumption cost, becomes\na function of payload size. And `splitOn` cannot be combined with a synchronous Response: each\nelement is its own run, so there is no single response to return." + }, + "splitOnConfiguration": { + "type": "object", + "properties": { + "correlation": { + "type": "object", + "properties": { + "clientTrackingId": { + "type": "string", + "description": "The client tracking identifier." + } + }, + "description": "The correlation properties." + } + }, + "description": "The trigger SplitOn configuration." + }, + "correlation": { + "type": "object", + "properties": { + "clientTrackingId": { + "type": "string", + "description": "The client tracking identifier." + } + }, + "description": "The correlation properties.\n\nSets the client tracking id for the run, which is what lets you find every run belonging to one\nlogical transaction across workflows. Set it from the upstream id (an incident number, a ticket\nid) rather than leaving it to the platform, or cross-workflow triage becomes guesswork." + } + } + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnection" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs" + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/1", + "description": "THE CATCH-ALL TRIGGER BRANCH. This branch declares no `type` and no properties, so it accepts\nany trigger shape the eight typed branches above do not.\n\nThat is why an `ApiConnectionWebhook` trigger validates: the schema has no branch modelling it,\ndespite it being a documented managed API trigger type and the shape of the Sentinel incident\ntrigger that starts most SOAR playbooks. It passes because nothing checks it, not because it\nwas checked.\n\nPractical consequence: a typo inside an ApiConnectionWebhook trigger is not caught here. The\nplan-time guards in the azapi module cover the parts that matter (the `$connections` wiring and\nthe callback trigger name); the rest is caught at deploy." + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiManagement" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs" + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Batch" + ] + }, + "inputs": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchActionMode" + }, + "batchGroupName": { + "type": "string", + "description": "The batch group name." + }, + "configurations": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchConfiguration" + }, + "description": "The batch configurations." + } + }, + "descripton": "The batch action input.", + "definitions": { + "BatchActionMode": { + "type": "string", + "enum": [ + "Inline", + "IntegrationAccount" + ], + "description": "The batch action mode." + }, + "BatchConfiguration": { + "type": "object", + "properties": { + "releaseCriteria": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchReleaseCriteria" + } + }, + "description": "The batch configuration." + }, + "BatchReleaseCriteria": { + "type": "object", + "properties": { + "messageCount": { + "type": "integer", + "description": "The message count." + }, + "batchSize": { + "type": "integer", + "description": "The batch size in bytes." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + }, + "description": "The batch release criteria." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Http" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "The URI of the request." + }, + "method": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/method" + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "cookie": { + "type": "string", + "description": "The cookie for the request." + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "method", + "uri" + ] + } + ], + "description": "The HTTP action input." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "HttpWebhook" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs" + }, + { + "type": "object", + "properties": { + "subscribe": { + "anyOf": [ + { + "$comment": "It is likely a bug that HTTP webhooks are allowed to put an arbitrary JSON value in the \"subscribe\" property." + }, + { + "type": "string" + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + ] + }, + "unsubscribe": { + "anyOf": [ + { + "$comment": "It is likely a bug that HTTP webhooks are allowed to put an arbitrary JSON value in the \"unsubscribe\" property." + }, + { + "type": "string" + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + ] + }, + "accessKeyType": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/1/properties/inputs/allOf/1/properties/accessKeyType" + } + }, + "required": [ + "subscribe" + ], + "description": "The HTTP webhook operation input.", + "$comment": "It is likely a bug that HTTP webhooks do not have to specify the \"unsubscribe\" property." + } + ] + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Recurrence" + ] + }, + "recurrence": { + "type": "object", + "properties": { + "frequency": { + "type": "string", + "enum": [ + "Second", + "Minute", + "Hour", + "Day", + "Week", + "Month", + "Year" + ], + "description": "The flow recurrence frequency." + }, + "interval": { + "type": "integer", + "description": "The recurrence interval." + }, + "count": { + "type": "integer", + "description": "The recurrence count." + }, + "startTime": { + "type": "string", + "description": "The recurrence start time." + }, + "endTime": { + "type": "string", + "description": "The recurrence end time." + }, + "timeZone": { + "type": "string", + "description": "The recurrence time zone." + }, + "schedule": { + "type": "object", + "properties": { + "minutes": { + "type": "array", + "items": { + "type": [ + "integer", + "string" + ] + }, + "description": "The minutes on which this job should fire." + }, + "hours": { + "type": "array", + "items": { + "type": [ + "integer", + "string" + ] + }, + "description": "The hours on which this job should fire." + }, + "weekDays": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "description": "Specifies the day of the week." + }, + "description": "The days of the week on which this job should fire." + }, + "monthDays": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "The days of the month on which this job should fire." + }, + "monthlyOccurrences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "dayOfWeek": { + "type": "string", + "enum": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "description": "Specifies the day of the week." + }, + "occurrence": { + "type": "integer", + "description": "Specifies the week count of this occurrence." + } + }, + "required": [ + "dayOfWeek", + "occurrence" + ], + "description": "Indicates a day of week and a count of weeks from the beginning or end of the month on which the day occurs." + }, + "description": "The monthly occurence on which this job should fire." + } + }, + "description": "The job recurrence schedule." + } + }, + "required": [ + "frequency", + "interval" + ], + "description": "The flow recurrence." + } + }, + "required": [ + "recurrence" + ] + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Request" + ] + }, + "kind": { + "enum": [ + "Alert", + "AzureMonitorAlert", + "Button", + "EventGrid", + "Geofence", + "Http", + "PowerApp", + "SecurityCenterAlert" + ] + }, + "inputs": { + "type": "object", + "properties": { + "host": { + "type": "object", + "properties": { + "api": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host/definitions/ApiConnectionProvider" + } + }, + "description": "The host.", + "definitions": { + "ApiConnectionProvider": { + "type": "object", + "properties": { + "runtimeUrl": { + "type": "string", + "format": "uri" + } + }, + "description": "The API connection provider." + } + } + }, + "operationId": { + "type": "string", + "description": "The operation identifier." + }, + "parameters": { + "type": "object", + "additionalItems": {}, + "description": "The operation parameters." + }, + "schema": { + "description": "The schema of the manual action input." + }, + "relativePath": { + "type": "string", + "description": "The relative path." + }, + "method": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ], + "description": "The HTTP method." + } + }, + "description": "The manual action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "SlidingWindow" + ] + }, + "inputs": { + "type": "object", + "properties": { + "delay": { + "type": "string", + "description": "The delay." + } + }, + "description": "The sliding window action input." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + } + ] + } + ], + "description": "A flow template trigger." + }, + "description": "The flow triggers.\n\nWhat starts a run. Every trigger is one of the nine types below and the key you give it is its\nname, which is also the string every `@triggerBody()` and `runAfter` reference resolves\nagainst. Renaming a trigger is a breaking change to the definition.\n\nMaximum 10 triggers, though the designer authors one. Names are stored keys: keep the\ndesigner's underscore-escaped form rather than tidying it." + }, + "outputs": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Array", + "Bool", + "Float", + "Int", + "Object", + "SecureObject", + "SecureString", + "String" + ], + "description": "The parameter type.\n\nThe eight WDL types: Array, Bool, Float, Int, Object, SecureObject, SecureString, String.\n\nSecureString and SecureObject are the ones that matter operationally. Their values are masked\nin run history and, deployed through the azapi module, ride the provider's write-only\n`sensitive_body` so they never reach Terraform state or plan output. A secret typed into the\ndesigner and exported lands in a template file, so it must be moved to a secure parameter." + }, + "value": { + "description": "The parameter value." + }, + "metadata": { + "description": "The parameter metadata." + }, + "description": { + "type": "string", + "description": "The parameter description." + } + }, + "description": "The flow template parameter." + }, + { + "properties": { + "error": { + "description": "The error of the output parameter." + } + } + } + ], + "description": "The flow output template parameter." + }, + "description": "The flow outputs.\n\nValues the run exposes when it finishes. Read them from the run history or, for a Request\ntrigger, return them with a Response action.\n\nOutputs are evaluated at the END of the run, so an expression here that references an action\nwhich was skipped evaluates against nothing. Guard with `if()` rather than assuming the happy\npath ran." + }, + "description": { + "type": "string", + "description": "The definition description.\n\nFree text describing the workflow. Distinct from the `hidden-title` tag on the Azure resource,\nwhich is what the portal list shows. Set both." + } + }, + "required": [ + "$schema", + "contentVersion" + ], + "x-annotation": { + "title": "Azure Logic Apps workflow definition schema, annotated", + "upstream": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json", + "annotated_by": "Libre DevOps", + "annotations_checked": "2026-08-24", + "notes_applied": 21, + "corrections": [ + { + "id": "retry-policy-type-casing", + "pointer": "/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/type", + "op": "enum_add", + "occurrences": 39, + "why": "The schema declares the enum PascalCase as None, Fixed and Exponential. The designer, every Microsoft example and every real definition use lowercase. Both cases are accepted by the platform, so the enum is widened rather than replaced." + }, + { + "id": "retry-policy-count-expression", + "pointer": "/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/count", + "op": "type_union", + "occurrences": 5, + "why": "Declared `integer`, which rejects `\"count\": \"@parameters('retry_count')\"`. Any WDL value may be an expression string, so a typed scalar that does not also accept `string` is wrong wherever an expression is legal. This is the general defect; `count` is where it bites." + }, + { + "id": "authentication-managed-identity", + "pointer": "/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/authentication", + "op": "oneof_add", + "occurrences": 28, + "why": "The `authentication` oneOf carries Basic, ClientCertificate, None, ActiveDirectoryOAuth and Raw, but not ManagedServiceIdentity, which is the recommended and most common auth type for an Http action calling Azure. 28 real actions in this workspace are rejected by it." + }, + { + "id": "variable-type-casing", + "pointer": "/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType", + "op": "enum_add", + "occurrences": 3, + "why": "Same casing defect as the retry policy, on InitializeVariable and SetVariable. The schema declares Array, Boolean, Float, Integer, Object, String; the designer emits lowercase." + }, + { + "id": "initialize-variable-multiple", + "pointer": "/properties/actions/additionalProperties/allOf/2/oneOf/34/properties/inputs/properties/variables", + "op": "remove_key", + "occurrences": 1, + "why": "The schema caps `variables` at one item. The designer only offers one, but a portal code view export taken from a live workflow in this workspace carries three, so the platform both emits and accepts more. `minItems` is left in place." + } + ], + "generated_by": "schema/generate.py", + "warning": "Generated file. Edit schema/annotations.yaml and regenerate; edits here are lost. Validation differs from upstream ONLY by the corrections listed above, each of which widens what is accepted so that definitions Azure itself emits stop being rejected." + } +} diff --git a/schema/workflowdefinition.annotated.schema.yaml b/schema/workflowdefinition.annotated.schema.yaml new file mode 100644 index 0000000..bbab674 --- /dev/null +++ b/schema/workflowdefinition.annotated.schema.yaml @@ -0,0 +1,1869 @@ +# Azure Logic Apps workflow definition schema, annotated. +# +# Upstream: https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json +# Annotations by Libre DevOps, checked 2026-08-24. +# 21 annotations applied. +# +# CORRECTED: the upstream schema rejects definitions Azure itself emits. See +# x-annotation.corrections at the end of this file for each change and why. +# +# GENERATED FILE. Edit schema/annotations.yaml and run schema/generate.py. +# +# This is the SCHEMA in YAML, for readability and for tools that accept a YAML schema. +# A workflow definition itself is JSON: Workflow Definition Language has no YAML dialect. +# +# Validation differs from upstream only by those corrections, each of which WIDENS what +# is accepted. Nothing here makes the schema stricter. +--- +$id: https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json# +$schema: http://json-schema.org/draft-04/schema# +title: Logic App Template Schema +description: |- + The workflow. + + A Logic Apps workflow definition, schema version 2016-06-01. + + THE SHAPE. Six properties carry everything: `triggers` starts the run, `actions` do the work, + `parameters` declares what varies between environments, `outputs` exposes results, + `contentVersion` stamps the definition, and `$schema` points here. + + WHAT THIS DOCUMENT IS NOT. This schema describes the JSON. It does NOT describe the `@{...}` + runtime expression layer inside those strings. A definition can be schema-valid and still fail + at run time because an expression referenced a missing property or evaluated an operand it + should not have. See the expression functions reference, and the pitfalls section of the + Libre DevOps Logic App standard. + + THERE IS NO YAML DIALECT. A workflow definition is JSON. The YAML rendering of THIS SCHEMA + exists for readability and for tools that accept YAML schemas; it does not mean a definition + may be written in YAML. + + PLATFORM LIMITS the schema does not encode: maximum 250 actions, maximum 10 triggers. The + designer authors a single trigger; more than one is expressible only in the language itself. + + DOCUMENTED BUT ABSENT: `staticResults`, referenced by `runtimeConfiguration.staticResult.name` + on an action, is documented as a definition-level attribute and is NOT declared in this + schema's root `properties`. Using it validates only because the root does not forbid unknown + properties. +type: object +properties: + actions: + type: object + additionalProperties: + allOf: + - type: object + properties: + runAfter: + type: object + additionalProperties: + type: array + items: + type: string + enum: + - Aborted + - Cancelled + - Failed + - Faulted + - Ignored + - Paused + - Running + - Skipped + - Succeeded + - Suspended + - TimedOut + - Waiting + description: The status of a flow. + description: |- + The operation run after. + + The dependency edge: a map of predecessor action name to the list of statuses that let this + action run. + + `"runAfter": {}` means "run first". An action whose predecessor finishes in a status NOT listed + is Skipped, not failed, and its own successors then evaluate against Skipped. + + THIS IS HOW TRY/CATCH IS BUILT. A catch action lists `["Failed", "TimedOut"]` on the scope it + guards; a finally action lists every terminal status. Getting the status list wrong produces a + workflow that silently skips its own error handling and reports success. + + Statuses: Succeeded, Failed, Skipped, TimedOut, Cancelled, Aborted, Faulted, Ignored, Paused, + Running, Suspended, Waiting. In practice a hand-authored definition uses the first five. + trackedProperties: + description: |- + The tracked properties. + + Key/value pairs emitted with the action's diagnostic record, so they are queryable in Log + Analytics without opening run history. This is the cheapest observability in Logic Apps and it + is almost always skipped. + + Track the correlating ids (incident number, ticket id, tenant) rather than payloads: tracked + properties land in logs, so anything sensitive here is a data protection problem. + - type: object + properties: + metadata: + description: The operation metadata. + type: + type: string + enum: + - ApiConnection + - ApiConnectionWebhook + - ApiManagement + - AppendToArrayVariable + - AppendToStringVariable + - Batch + - Compose + - DecrementVariable + - Expression + - FlatFileDecoding + - FlatFileEncoding + - Foreach + - Function + - Http + - HttpWebhook + - If + - IncrementVariable + - InitializeVariable + - IntegrationAccountArtifactLookup + - Join + - Liquid + - ParseJson + - Query + - Recurrence + - Request + - Response + - Scope + - Select + - SendToBatch + - SetVariable + - SlidingWindow + - Switch + - Table + - Terminate + - Until + - Wait + - Workflow + - XmlValidation + - Xslt + description: |- + The type of the flow operation. + + The action type, one of 38. Grouped by what they are for: + + CONTROL FLOW: If, Switch, Foreach, Until, Scope, Terminate. + DATA: Compose, ParseJson, Query, Select, Table, Join, Expression. + VARIABLES: InitializeVariable, SetVariable, AppendToArrayVariable, AppendToStringVariable, + IncrementVariable, DecrementVariable. + CALLING OUT: Http, HttpWebhook, ApiConnection, ApiConnectionWebhook, ApiManagement, Function, + Workflow, SendToBatch, Batch. + REQUEST/RESPONSE: Request, Response. + INTEGRATION ACCOUNT: Liquid, Xslt, XmlValidation, FlatFileEncoding, FlatFileDecoding, + IntegrationAccountArtifactLookup. + OTHER: Wait, Recurrence, SlidingWindow. + + `Workflow` dispatches to another workflow BY RESOURCE ID, and ARM validates that target exists + at PUT time (`NestedWorkflowNotFound`). Deploying a dispatcher therefore has to happen after + its target: the azapi module expresses that with `deploy_tier`. + kind: + type: string + enum: + - AddToTime + - Alert + - ApiConnection + - AzureMonitorAlert + - Button + - ConvertTimeZone + - CurrentTime + - EventGrid + - Geofence + - GetFutureTime + - GetPastTime + - Http + - JsonToJson + - JsonToText + - PowerApp + - SecurityCenterAlert + - SubtractFromTime + - XmlToJson + - XmlToText + description: The kind of the flow operation. + description: + type: string + description: The operation description. + operationOptions: + type: string + description: |- + The operation options. + + Per-action behaviour switches. The two worth knowing: + + `DisableAsyncPattern` makes an action that would return 202 and poll wait for the real result + instead, which is usually what you meant. + + `SuppressWorkflowHeaders` stops Logic Apps injecting its own headers into an outbound request, + which some strict endpoints reject. + runtimeConfiguration: + type: object + properties: + paginationPolicy: + $ref: '#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowPaginationPolicy' + contentTransfer: + $ref: '#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferConfiguration' + concurrency: + $ref: '#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowConcurrencyConfiguration' + description: |- + The flow template operation runtime configuration. + + Per-action runtime settings, and the home of the retry policy. + + `retryPolicy` defaults to `exponential`, 4 retries over roughly 20 seconds to 1 hour, on 408, + 429 and 5xx ONLY. A 4xx that is not 408 or 429 never retries, so an auth failure fails + immediately, which is correct. + + SET IT EXPLICITLY on anything that calls out. The default is rarely the right budget, and an + inherited default is a decision nobody made. `"type": "none"` is the honest way to say a call + must not be retried, which matters for anything non-idempotent. + + `staticResult` names an entry in the definition-level `staticResults` object to return mock + outputs, for testing. Note that `staticResults` itself is not declared in this schema. + + `concurrency` caps parallel iterations on Foreach and Until. Leaving it unset means the + platform picks, and a debatched trigger plus unbounded concurrency is how a downstream API + gets rate limited by your own workflow. + definitions: + FlowConcurrencyConfiguration: + type: object + properties: + repetitions: + type: integer + description: The repetitions. + runs: + type: integer + description: The runs. + maximumWaitingRuns: + type: integer + description: The maximum waiting runs. + description: The flow concurrency configuration. + FlowContentTransferConfiguration: + type: object + properties: + transferMode: + $ref: '#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferMode' + description: The flow content transfer configuration. + FlowContentTransferMode: + type: string + enum: + - Chunked + description: The flow content transfer mode. + FlowPaginationPolicy: + type: object + properties: + minimumItemCount: + type: integer + description: The minimum item count. + description: The flow pagination policy. + required: + - type + - oneOf: + - type: object + properties: + type: + enum: + - ApiConnection + inputs: + allOf: + - type: object + properties: + host: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host' + method: + type: string + default: POST + description: The method of the request. + path: + type: string + description: The path for the request. + queries: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries' + body: + description: The body of the request. + headers: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers' + required: + - host + - path + - type: object + properties: + operationOptions: + $ref: '#/properties/actions/additionalProperties/allOf/1/properties/operationOptions' + retryPolicy: + type: object + properties: + type: + type: string + enum: + - None + - Fixed + - Exponential + - none + - fixed + - exponential + description: |- + The type of retry policy to use. + + CORRECTED BY LIBRE DEVOPS (retry-policy-type-casing): The schema declares the enum PascalCase as None, Fixed and Exponential. The designer, every Microsoft example and every real definition use lowercase. Both cases are accepted by the platform, so the enum is widened rather than replaced. Rejected 39 real action(s) upstream. + interval: + type: string + description: The interval between retries. + count: + type: + - integer + - string + description: |- + The number of times a retry should be attempted. + + CORRECTED BY LIBRE DEVOPS (retry-policy-count-expression): Declared `integer`, which rejects `"count": "@parameters('retry_count')"`. Any WDL value may be an expression string, so a typed scalar that does not also accept `string` is wrong wherever an expression is legal. This is the general defect; `count` is where it bites. Rejected 5 real action(s) upstream. + minimumInterval: + type: string + description: The minimum time delay for the exponential retry. + maximumInterval: + type: string + description: The maximum time delay for the exponential retry. + description: The retry policy. + authentication: + oneOf: + - type: string + description: A Logic Apps expression. + - type: object + properties: + type: + type: string + enum: + - Basic + description: The HTTP authentication type. + username: + type: string + description: The username. + password: + type: string + description: The password. + description: The HTTP basic authentication. + - type: object + properties: + type: + type: string + enum: + - ClientCertificate + description: The HTTP authentication type. + password: + type: string + description: The password. + pfx: + type: string + description: The PFX. + description: The HTTP client certificate authentication. + - type: object + properties: + type: + type: string + enum: + - None + description: The HTTP authentication type. + additionalProperties: false + description: No HTTP authentication. + - type: object + properties: + type: + type: string + enum: + - ActiveDirectoryOAuth + description: The HTTP authentication type. + authority: + type: string + description: The authority. + tenant: + type: string + description: The tenant ID. + audience: + type: string + description: The audience. + clientId: + type: string + description: The client ID. + secret: + type: string + description: The secret. + pfx: + type: string + description: The PFX. + password: + type: string + description: The password used to decrypt the PFX. + description: The HTTP OAuth authentication. + - type: object + properties: + type: + type: string + enum: + - Raw + description: The HTTP authentication type. + scheme: + type: string + description: The raw authentication scheme. + parameter: + type: string + description: The raw authentication parameter. + value: + type: string + description: The raw authentication value. + description: The HTTP raw authentication. + - type: object + properties: + type: + type: string + enum: + - ManagedServiceIdentity + description: The HTTP authentication type. + identity: + type: string + description: The resource id of a user-assigned managed identity. Omit for the + system-assigned identity. + audience: + type: string + description: The audience the token is requested for, for example https://management.azure.com. + description: 'Managed identity authentication. Added by Libre DevOps: the 2016-06-01 + schema predates it and has no branch for it, so the standard way to authenticate + an Http action to an Azure endpoint fails validation upstream.' + description: |- + The HTTP authentication. + + CORRECTED BY LIBRE DEVOPS (authentication-managed-identity): The `authentication` oneOf carries Basic, ClientCertificate, None, ActiveDirectoryOAuth and Raw, but not ManagedServiceIdentity, which is the recommended and most common auth type for an Http action calling Azure. 28 real actions in this workspace are rejected by it. Rejected 28 real action(s) upstream. + description: The retryable action input. + description: The ApiConnection operation input. + - type: object + properties: + type: + enum: + - ApiConnectionWebhook + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs' + - type: object + properties: + schema: + description: The schema of an API connection webhook operation. + accessKeyType: + type: string + enum: + - Primary + - Secondary + description: The access key type. + description: The API connection webhook operation input. + - type: object + properties: + type: + enum: + - ApiManagement + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + api: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/ApiManagementApiReference' + method: + type: string + description: The method of the request. + pathTemplate: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/PathTemplate' + queries: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries' + body: + description: The body of the request. + subscriptionKey: + type: string + description: The subscription key. + headers: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers' + required: + - api + - pathTemplate + description: The API Management operation input. + definitions: + ApiManagementApiReference: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0' + description: The API Management API reference. + PathTemplate: + description: The path template for the request. + - type: object + properties: + type: + enum: + - SendToBatch + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + host: + type: object + properties: + workflow: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host/definitions/FlowReference' + triggerName: + type: string + description: The trigger name. + required: + - triggerName + - workflow + description: The workflow host. + definitions: + FlowReference: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0' + - required: + - id + description: The flow reference. + batchName: + type: string + description: The batch name. + partitionName: + type: string + description: The partition name. + messageId: + type: string + description: The message identifier. + content: + description: The content. + required: + - host + - batchName + - content + description: The Send to Batch action input. + - type: object + properties: + type: + enum: + - Compose + inputs: + description: The Compose action input. + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - AddToTime + inputs: + type: object + properties: + baseTime: + type: string + description: The base time. + interval: + type: integer + description: The interval of time. + timeUnit: + type: string + description: The unit of time specified. + required: + - baseTime + - interval + - timeUnit + description: The inputs for the add to time or subtract from time operation kinds. + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - ConvertTimeZone + inputs: + type: object + properties: + baseTime: + type: string + description: The base time. + sourceTimeZone: + type: string + description: The time zone to convert from. + destinationTimeZone: + type: string + description: The time zone to convert to. + formatString: + type: string + description: The date time format string. + required: + - baseTime + - sourceTimeZone + - destinationTimeZone + description: The convert time zone operation kind input. + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - CurrentTime + inputs: + type: object + additionalProperties: false + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - GetFutureTime + inputs: + type: object + properties: + interval: + type: integer + description: The interval of time. + timeUnit: + type: string + description: The unit of time specified. + required: + - interval + - timeUnit + description: The inputs for the get future time and get past time operation kinds. + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - GetPastTime + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/8/properties/inputs' + - type: object + properties: + type: + enum: + - Expression + kind: + enum: + - SubtractFromTime + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/5/properties/inputs' + - type: object + properties: + type: + enum: + - FlatFileDecoding + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + content: + description: The content. + integrationAccount: + type: object + properties: + schema: + type: object + properties: + name: + type: string + description: The name. + required: + - name + description: The artifact information. + required: + - schema + description: The integration account schema information. + required: + - content + - integrationAccount + description: The content and schema action input. + - type: object + properties: + type: + enum: + - FlatFileEncoding + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs' + - type: object + properties: + emptyNodeGenerationMode: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/12/properties/inputs/definitions/EmptyNodeGenerationMode' + description: The flat file encoding action input. + definitions: + EmptyNodeGenerationMode: + type: string + enum: + - ForcedDisabled + - ForcedEnabled + - HonorSchemaNodeProperty + description: The empty node generation mode. + - type: object + properties: + type: + enum: + - Function + inputs: + type: object + allOf: + - properties: + function: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference' + - properties: + functionApp: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionAppReference' + uri: + type: string + description: The operation URI as defined in the function app Swagger. + properties: + method: + type: string + description: The method of the request. + queries: + type: object + additionalProperties: + anyOf: + - type: boolean + - type: integer + - type: 'null' + - type: number + - type: string + description: The queries for the request. + body: + description: The body of the request. + headers: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers' + description: The function action input. + definitions: + FunctionAppReference: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0' + description: The function app reference. + FunctionReference: + allOf: + - type: object + properties: + id: + type: string + description: The resource reference identifier. + name: + type: string + description: The resource reference name. + type: + type: string + description: The resource reference type. + description: The base resource reference. + description: The function reference. + - type: object + properties: + type: + enum: + - Http + inputs: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs' + - $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/5' + - type: object + properties: + type: + enum: + - IntegrationAccountArtifactLookup + inputs: + type: object + properties: + artifactType: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/16/properties/inputs/definitions/ArtifactType' + artifaceName: + type: string + description: The name of the artifact. + description: The integration account artifact lookup input. + definitions: + ArtifactType: + type: string + enum: + - Schema + - Map + - Partner + - Agreement + description: The type of artifact. + - type: object + properties: + type: + enum: + - Join + inputs: + type: object + properties: + from: + type: + - array + - string + description: The source. + joinWith: + type: string + description: The separator. + required: + - from + description: The Join action input. + - type: object + properties: + type: + enum: + - Liquid + kind: + enum: + - JsonToJson + - JsonToText + - XmlToJson + - XmlToText + inputs: + type: object + properties: + content: + description: The content. + integrationAccount: + type: object + properties: + map: + '#ref': common/ArtifactInformation.json + required: + - map + description: The integration account map information. + transformedContentSchema: + $schema: http://json-schema.org/draft-04/schema# + required: + - content + - integrationAccount + description: The liquid action input. + - type: object + properties: + type: + enum: + - ParseJson + inputs: + type: object + properties: + content: + description: The content. + schema: + $schema: http://json-schema.org/draft-04/schema# + description: The Parse JSON action input. + - type: object + properties: + type: + enum: + - Query + inputs: + type: object + properties: + from: + type: + - array + - string + description: The source. + where: + type: string + description: The where condition. + required: + - from + description: The query action input. + - type: object + properties: + type: + enum: + - Response + inputs: + type: object + properties: + statusCode: + type: + - integer + - string + description: The status code for the response. + headers: + oneOf: + - type: string + - type: object + additionalProperties: + anyOf: + - type: boolean + - type: integer + - type: 'null' + - type: number + - type: string + description: The headers for the request. + body: + description: The body of the response. + schema: + $schema: http://json-schema.org/draft-04/schema# + required: + - statusCode + description: The response action input. + - type: object + properties: + type: + enum: + - Foreach + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + foreach: + type: + - array + - string + description: The For Each expression. + - type: object + properties: + type: + enum: + - If + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + else: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfElseProperty' + expression: + anyOf: + - type: string + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfExpressionObjectProperty' + description: The If expression. + definitions: + IfElseProperty: + type: object + properties: + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + IfExpressionObjectProperty: + description: The If object expression property. + $comment: 'TODO(joechung): Find out what the schema is for If expression objects.' + - type: object + properties: + type: + enum: + - Scope + inputs: + type: object + properties: + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + - type: object + properties: + type: + enum: + - Switch + cases: + type: object + additionalProperties: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/definitions/FlowTemplateActionCaseBranch' + description: The Switch action case branches. + default: + type: object + properties: + actions: + type: object + additionalProperties: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + description: The actions. + description: The flow template action branch. + expression: + type: + - number + - string + description: The Switch expression. + definitions: + FlowTemplateActionCaseBranch: + type: object + properties: + case: + description: The case. + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + required: + - case + description: The flow template action case branch. + - type: object + properties: + type: + enum: + - Until + actions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default' + expression: + type: string + description: The Until expression. + limit: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/26/definitions/UntilLimitProperty' + definitions: + UntilLimitProperty: + type: object + properties: + count: + type: + - number + - string + description: The until count limit. + timeout: + type: string + description: The until timeout limit. + description: The Until limits. + - type: object + properties: + type: + enum: + - Select + inputs: + type: object + properties: + from: + type: + - array + - string + description: The select source. + select: + description: The select transform. + required: + - from + - select + description: The Select action input. + - type: object + properties: + type: + enum: + - Table + inputs: + type: object + properties: + from: + type: + - array + - string + description: The source. + format: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableFormat' + columns: + type: array + items: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableColumn' + required: + - from + description: The table action input. + definitions: + TableColumn: + type: object + properties: + header: + type: string + description: The header. + value: + description: The value. + description: The table column. + TableFormat: + type: string + enum: + - CSV + - HTML + description: The table format. + - type: object + properties: + type: + enum: + - Terminate + inputs: + type: object + properties: + runStatus: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/0/properties/runAfter/additionalProperties/items' + - enum: + - Cancelled + - Failed + - Succeeded + runError: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/29/properties/inputs/definitions/TerminateActionRunError' + description: The Terminate action input. + definitions: + TerminateActionRunError: + type: object + properties: + code: + type: + - number + - string + description: The code. + message: + type: string + description: The message. + description: The run error. + - type: object + properties: + type: + enum: + - AppendToArrayVariable + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs' + - type: object + properties: + type: + enum: + - AppendToStringVariable + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs' + - type: object + properties: + type: + enum: + - DecrementVariable + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs' + - type: object + properties: + type: + enum: + - IncrementVariable + inputs: + type: object + properties: + name: + type: string + description: The name. + type: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType' + value: + description: The variable value. + description: The variable action input. + definitions: + FlowVariableDataType: + type: string + enum: + - Array + - Boolean + - Float + - Integer + - Object + - String + - array + - boolean + - float + - integer + - object + - string + description: |- + The flow variable data type. + + CORRECTED BY LIBRE DEVOPS (variable-type-casing): Same casing defect as the retry policy, on InitializeVariable and SetVariable. The schema declares Array, Boolean, Float, Integer, Object, String; the designer emits lowercase. Rejected 3 real action(s) upstream. + - type: object + properties: + type: + enum: + - InitializeVariable + inputs: + type: object + properties: + variables: + type: array + items: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs' + minItems: 1 + description: 'CORRECTED BY LIBRE DEVOPS (initialize-variable-multiple): The schema caps + `variables` at one item. The designer only offers one, but a portal code view export + taken from a live workflow in this workspace carries three, so the platform both emits + and accepts more. `minItems` is left in place. Rejected 1 real action(s) upstream.' + description: The Initialize Variable action input. + - type: object + properties: + type: + enum: + - SetVariable + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs' + - type: object + properties: + type: + enum: + - Wait + inputs: + type: object + properties: + interval: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/TimeInterval' + until: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/WaitUntil' + maxProperties: 1 + description: The Wait action input. + definitions: + TimeInterval: + type: object + properties: + unit: + allOf: + - description: The wait unit. + - type: string + enum: + - Second + - Minute + - Hour + - Day + - Week + - Month + - Year + count: + type: integer + description: The wait count. + description: The wait interval. + WaitUntil: + type: object + properties: + timestamp: + type: string + description: The timestamp. + description: The Until. + - type: object + properties: + type: + enum: + - Workflow + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + host: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host' + body: + description: The body of the request. + headers: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers' + required: + - host + description: The flow action input. + - type: object + properties: + type: + enum: + - XmlValidation + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs' + - type: object + properties: + type: + enum: + - Xslt + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + content: + description: The content. + parameters: + type: object + additionalProperties: + type: string + description: The XSLT (Extensible Stylesheet Language Transformations) parameters. + integrationAccount: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/18/properties/inputs/properties/integrationAccount' + function: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0' + description: The function reference. + transformOptions: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/39/properties/inputs/definitions/XsltTransformOptions' + required: + - content + description: The XSLT (Extensible Stylesheet Language Transformations) action input. + definitions: + XsltTransformOptions: + type: string + description: The XSLT options flag. + description: A flow template action. + definitions: + FlowTemplateActionBranch: + type: object + properties: + actions: + type: object + additionalProperties: + $ref: '#/properties/actions/additionalProperties' + description: The actions. + description: The flow template action branch. + FlowTemplateActionCaseBranch: + allOf: + - $ref: '#/properties/actions/additionalProperties/definitions/FlowTemplateActionBranch' + - type: object + properties: + case: + description: The case. + required: + - case + description: The flow template action case branch. + FlowTemplateActionUntil: + type: object + properties: + limit: + description: The do-until limit. + conditions: + type: array + items: + type: object + properties: + expression: + type: string + description: The expression. + dependsOn: + type: string + description: The dependency. + description: The template action expression condition. + description: The do-until conditions. + description: The do-until policy. + description: |- + The flow run actions. + + The work, and the execution graph. The key is the action name and it is a stored key: it is + what `runAfter` and `@body('name')` reference, and what appears in run history. + + ORDERING IS `runAfter` AND NOTHING ELSE. There is no top-level sequence and the order keys + appear in the JSON is irrelevant. Deploying a definition whole keeps that as the only ordering + graph. Assembling the same workflow from per-resource Terraform resources creates a second + graph that can disagree with it. + + Maximum 250 actions. The designer escapes spaces to underscores in names; keep its form. + metadata: + description: |- + The definition metadata. + + Arbitrary key/value metadata carried with the definition. The designer writes its own entries + here. Leave what the designer put there alone: rewriting it is how a template stops diffing + cleanly against a fresh export. + $schema: + enum: + - https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json# + type: string + description: |- + The definition schema. + + The schema location. Required by this document, and the string that makes an editor validate + the file as you type. Keep it as exported. + contentVersion: + type: string + pattern: (^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$) + description: |- + The flow content version. Specify using a 4-digit format, e.g., 1.0.0.0 + + Your version stamp for the definition, "1.0.0.0" by default. It is metadata: the platform does + not use it to order or reject deployments. Worth setting so a deployed workflow can be matched + back to a commit. + parameters: + type: object + additionalProperties: + allOf: + - $ref: '#/properties/outputs/additionalProperties/allOf/0' + - properties: + defaultValue: + description: |- + The default parameter value. + + Used when no value is supplied at deployment. Lowest precedence of everything that can set a + parameter, so treat it as a fallback rather than as configuration. + + Never put a secret here. A `defaultValue` on a SecureString still lives in the definition file + and therefore in source control. + allowedValues: + type: array + description: |- + The allowed parameter values. + + Constrains the accepted values. Cheap and underused: it turns a typo in a tfvars file into a + deployment error rather than a workflow that runs and does the wrong thing. + description: The flow input template parameter. + description: |- + The flow parameters. + + Parameter DECLARATIONS, not values. This is the single most misunderstood part of deploying a + workflow as code. + + A declaration says a parameter exists, its type, and optionally a default and allowed values. + The VALUE lives outside the definition, in the ARM/azapi request body's `properties.parameters`. + A portal export carries both halves, which is why an unedited export deploys. + + Anything declared here with no value anywhere fails at deploy with `InvalidTemplate`, "the + value for the workflow parameter ... is not provided". Catch it at plan time instead. + + `$connections` is declared here like any other parameter, and its value is generated rather + than hand written. See the Logic App standard's connections section. + triggers: + type: object + additionalProperties: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/1' + - type: object + properties: + conditions: + type: array + items: + $ref: '#/properties/actions/additionalProperties/definitions/FlowTemplateActionUntil/properties/conditions/items' + description: |- + The operation conditions. + + Guards that must be true for the trigger to fire. Filtering HERE is cheaper than filtering in a + first action, because on Consumption an action that runs is an action that bills. + + Typical use: only act on incident creation rather than every enrichment update, or only on a + severity floor. + splitOn: + type: string + description: |- + The trigger split on. + + Debatching. Points at an array in the trigger output and starts one workflow RUN per element + rather than one run holding the array. + + Two consequences people meet the hard way. Run count, and therefore Consumption cost, becomes + a function of payload size. And `splitOn` cannot be combined with a synchronous Response: each + element is its own run, so there is no single response to return. + splitOnConfiguration: + type: object + properties: + correlation: + type: object + properties: + clientTrackingId: + type: string + description: The client tracking identifier. + description: The correlation properties. + description: The trigger SplitOn configuration. + correlation: + type: object + properties: + clientTrackingId: + type: string + description: The client tracking identifier. + description: |- + The correlation properties. + + Sets the client tracking id for the run, which is what lets you find every run belonging to one + logical transaction across workflows. Set it from the upstream id (an incident number, a ticket + id) rather than leaving it to the platform, or cross-workflow triage becomes guesswork. + - oneOf: + - type: object + properties: + type: + enum: + - ApiConnection + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs' + recurrence: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence' + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/1' + description: |- + THE CATCH-ALL TRIGGER BRANCH. This branch declares no `type` and no properties, so it accepts + any trigger shape the eight typed branches above do not. + + That is why an `ApiConnectionWebhook` trigger validates: the schema has no branch modelling it, + despite it being a documented managed API trigger type and the shape of the Sentinel incident + trigger that starts most SOAR playbooks. It passes because nothing checks it, not because it + was checked. + + Practical consequence: a typo inside an ApiConnectionWebhook trigger is not caught here. The + plan-time guards in the azapi module cover the parts that matter (the `$connections` wiring and + the callback trigger name); the rest is caught at deploy. + - type: object + properties: + type: + enum: + - ApiManagement + inputs: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs' + recurrence: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence' + - type: object + properties: + type: + enum: + - Batch + inputs: + type: object + properties: + mode: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchActionMode' + batchGroupName: + type: string + description: The batch group name. + configurations: + type: object + additionalProperties: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchConfiguration' + description: The batch configurations. + descripton: The batch action input. + definitions: + BatchActionMode: + type: string + enum: + - Inline + - IntegrationAccount + description: The batch action mode. + BatchConfiguration: + type: object + properties: + releaseCriteria: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchReleaseCriteria' + description: The batch configuration. + BatchReleaseCriteria: + type: object + properties: + messageCount: + type: integer + description: The message count. + batchSize: + type: integer + description: The batch size in bytes. + recurrence: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence' + description: The batch release criteria. + - type: object + properties: + type: + enum: + - Http + inputs: + allOf: + - $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1' + - type: object + properties: + uri: + type: string + description: The URI of the request. + method: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/method' + queries: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries' + cookie: + type: string + description: The cookie for the request. + body: + description: The body of the request. + headers: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers' + required: + - method + - uri + description: The HTTP action input. + recurrence: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence' + - type: object + properties: + type: + enum: + - HttpWebhook + inputs: + allOf: + - $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs' + - type: object + properties: + subscribe: + anyOf: + - $comment: It is likely a bug that HTTP webhooks are allowed to put an arbitrary + JSON value in the "subscribe" property. + - type: string + - $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs' + unsubscribe: + anyOf: + - $comment: It is likely a bug that HTTP webhooks are allowed to put an arbitrary + JSON value in the "unsubscribe" property. + - type: string + - $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs' + accessKeyType: + $ref: '#/properties/actions/additionalProperties/allOf/2/oneOf/1/properties/inputs/allOf/1/properties/accessKeyType' + required: + - subscribe + description: The HTTP webhook operation input. + $comment: It is likely a bug that HTTP webhooks do not have to specify the "unsubscribe" + property. + - type: object + properties: + type: + type: string + enum: + - Recurrence + recurrence: + type: object + properties: + frequency: + type: string + enum: + - Second + - Minute + - Hour + - Day + - Week + - Month + - Year + description: The flow recurrence frequency. + interval: + type: integer + description: The recurrence interval. + count: + type: integer + description: The recurrence count. + startTime: + type: string + description: The recurrence start time. + endTime: + type: string + description: The recurrence end time. + timeZone: + type: string + description: The recurrence time zone. + schedule: + type: object + properties: + minutes: + type: array + items: + type: + - integer + - string + description: The minutes on which this job should fire. + hours: + type: array + items: + type: + - integer + - string + description: The hours on which this job should fire. + weekDays: + type: array + items: + type: string + enum: + - Friday + - Monday + - Saturday + - Sunday + - Thursday + - Tuesday + - Wednesday + description: Specifies the day of the week. + description: The days of the week on which this job should fire. + monthDays: + type: array + items: + type: integer + description: The days of the month on which this job should fire. + monthlyOccurrences: + type: array + items: + type: object + properties: + dayOfWeek: + type: string + enum: + - Friday + - Monday + - Saturday + - Sunday + - Thursday + - Tuesday + - Wednesday + description: Specifies the day of the week. + occurrence: + type: integer + description: Specifies the week count of this occurrence. + required: + - dayOfWeek + - occurrence + description: Indicates a day of week and a count of weeks from the beginning or + end of the month on which the day occurs. + description: The monthly occurence on which this job should fire. + description: The job recurrence schedule. + required: + - frequency + - interval + description: The flow recurrence. + required: + - recurrence + - type: object + properties: + type: + enum: + - Request + kind: + enum: + - Alert + - AzureMonitorAlert + - Button + - EventGrid + - Geofence + - Http + - PowerApp + - SecurityCenterAlert + inputs: + type: object + properties: + host: + type: object + properties: + api: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host/definitions/ApiConnectionProvider' + description: The host. + definitions: + ApiConnectionProvider: + type: object + properties: + runtimeUrl: + type: string + format: uri + description: The API connection provider. + operationId: + type: string + description: The operation identifier. + parameters: + type: object + additionalItems: {} + description: The operation parameters. + schema: + description: The schema of the manual action input. + relativePath: + type: string + description: The relative path. + method: + type: string + enum: + - DELETE + - GET + - HEAD + - OPTIONS + - PATCH + - POST + - PUT + - TRACE + description: The HTTP method. + description: The manual action input. + - type: object + properties: + type: + type: string + enum: + - SlidingWindow + inputs: + type: object + properties: + delay: + type: string + description: The delay. + description: The sliding window action input. + recurrence: + $ref: '#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence' + description: A flow template trigger. + description: |- + The flow triggers. + + What starts a run. Every trigger is one of the nine types below and the key you give it is its + name, which is also the string every `@triggerBody()` and `runAfter` reference resolves + against. Renaming a trigger is a breaking change to the definition. + + Maximum 10 triggers, though the designer authors one. Names are stored keys: keep the + designer's underscore-escaped form rather than tidying it. + outputs: + type: object + additionalProperties: + allOf: + - type: object + properties: + type: + type: string + enum: + - Array + - Bool + - Float + - Int + - Object + - SecureObject + - SecureString + - String + description: |- + The parameter type. + + The eight WDL types: Array, Bool, Float, Int, Object, SecureObject, SecureString, String. + + SecureString and SecureObject are the ones that matter operationally. Their values are masked + in run history and, deployed through the azapi module, ride the provider's write-only + `sensitive_body` so they never reach Terraform state or plan output. A secret typed into the + designer and exported lands in a template file, so it must be moved to a secure parameter. + value: + description: The parameter value. + metadata: + description: The parameter metadata. + description: + type: string + description: The parameter description. + description: The flow template parameter. + - properties: + error: + description: The error of the output parameter. + description: The flow output template parameter. + description: |- + The flow outputs. + + Values the run exposes when it finishes. Read them from the run history or, for a Request + trigger, return them with a Response action. + + Outputs are evaluated at the END of the run, so an expression here that references an action + which was skipped evaluates against nothing. Guard with `if()` rather than assuming the happy + path ran. + description: + type: string + description: |- + The definition description. + + Free text describing the workflow. Distinct from the `hidden-title` tag on the Azure resource, + which is what the portal list shows. Set both. +required: +- $schema +- contentVersion +x-annotation: + title: Azure Logic Apps workflow definition schema, annotated + upstream: https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json + annotated_by: Libre DevOps + annotations_checked: '2026-08-24' + notes_applied: 21 + corrections: + - id: retry-policy-type-casing + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/type + op: enum_add + occurrences: 39 + why: The schema declares the enum PascalCase as None, Fixed and Exponential. The designer, every Microsoft + example and every real definition use lowercase. Both cases are accepted by the platform, so the + enum is widened rather than replaced. + - id: retry-policy-count-expression + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/retryPolicy/properties/count + op: type_union + occurrences: 5 + why: 'Declared `integer`, which rejects `"count": "@parameters(''retry_count'')"`. Any WDL value may + be an expression string, so a typed scalar that does not also accept `string` is wrong wherever + an expression is legal. This is the general defect; `count` is where it bites.' + - id: authentication-managed-identity + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1/properties/authentication + op: oneof_add + occurrences: 28 + why: The `authentication` oneOf carries Basic, ClientCertificate, None, ActiveDirectoryOAuth and Raw, + but not ManagedServiceIdentity, which is the recommended and most common auth type for an Http action + calling Azure. 28 real actions in this workspace are rejected by it. + - id: variable-type-casing + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType + op: enum_add + occurrences: 3 + why: Same casing defect as the retry policy, on InitializeVariable and SetVariable. The schema declares + Array, Boolean, Float, Integer, Object, String; the designer emits lowercase. + - id: initialize-variable-multiple + pointer: /properties/actions/additionalProperties/allOf/2/oneOf/34/properties/inputs/properties/variables + op: remove_key + occurrences: 1 + why: The schema caps `variables` at one item. The designer only offers one, but a portal code view + export taken from a live workflow in this workspace carries three, so the platform both emits and + accepts more. `minItems` is left in place. + generated_by: schema/generate.py + warning: Generated file. Edit schema/annotations.yaml and regenerate; edits here are lost. Validation + differs from upstream ONLY by the corrections listed above, each of which widens what is accepted + so that definitions Azure itself emits stop being rejected. diff --git a/schema/workflowdefinition.schema.json b/schema/workflowdefinition.schema.json new file mode 100644 index 0000000..fbb9369 --- /dev/null +++ b/schema/workflowdefinition.schema.json @@ -0,0 +1,2461 @@ +{ + "$id": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Logic App Template Schema", + "description": "The workflow.", + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "runAfter": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Aborted", + "Cancelled", + "Failed", + "Faulted", + "Ignored", + "Paused", + "Running", + "Skipped", + "Succeeded", + "Suspended", + "TimedOut", + "Waiting" + ], + "description": "The status of a flow." + } + }, + "description": "The operation run after." + }, + "trackedProperties": { + "description": "The tracked properties." + } + } + }, + { + "type": "object", + "properties": { + "metadata": { + "description": "The operation metadata." + }, + "type": { + "type": "string", + "enum": [ + "ApiConnection", + "ApiConnectionWebhook", + "ApiManagement", + "AppendToArrayVariable", + "AppendToStringVariable", + "Batch", + "Compose", + "DecrementVariable", + "Expression", + "FlatFileDecoding", + "FlatFileEncoding", + "Foreach", + "Function", + "Http", + "HttpWebhook", + "If", + "IncrementVariable", + "InitializeVariable", + "IntegrationAccountArtifactLookup", + "Join", + "Liquid", + "ParseJson", + "Query", + "Recurrence", + "Request", + "Response", + "Scope", + "Select", + "SendToBatch", + "SetVariable", + "SlidingWindow", + "Switch", + "Table", + "Terminate", + "Until", + "Wait", + "Workflow", + "XmlValidation", + "Xslt" + ], + "description": "The type of the flow operation." + }, + "kind": { + "type": "string", + "enum": [ + "AddToTime", + "Alert", + "ApiConnection", + "AzureMonitorAlert", + "Button", + "ConvertTimeZone", + "CurrentTime", + "EventGrid", + "Geofence", + "GetFutureTime", + "GetPastTime", + "Http", + "JsonToJson", + "JsonToText", + "PowerApp", + "SecurityCenterAlert", + "SubtractFromTime", + "XmlToJson", + "XmlToText" + ], + "description": "The kind of the flow operation." + }, + "description": { + "type": "string", + "description": "The operation description." + }, + "operationOptions": { + "type": "string", + "description": "The operation options." + }, + "runtimeConfiguration": { + "type": "object", + "properties": { + "paginationPolicy": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowPaginationPolicy" + }, + "contentTransfer": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferConfiguration" + }, + "concurrency": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowConcurrencyConfiguration" + } + }, + "description": "The flow template operation runtime configuration.", + "definitions": { + "FlowConcurrencyConfiguration": { + "type": "object", + "properties": { + "repetitions": { + "type": "integer", + "description": "The repetitions." + }, + "runs": { + "type": "integer", + "description": "The runs." + }, + "maximumWaitingRuns": { + "type": "integer", + "description": "The maximum waiting runs." + } + }, + "description": "The flow concurrency configuration." + }, + "FlowContentTransferConfiguration": { + "type": "object", + "properties": { + "transferMode": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/runtimeConfiguration/definitions/FlowContentTransferMode" + } + }, + "description": "The flow content transfer configuration." + }, + "FlowContentTransferMode": { + "type": "string", + "enum": [ + "Chunked" + ], + "description": "The flow content transfer mode." + }, + "FlowPaginationPolicy": { + "type": "object", + "properties": { + "minimumItemCount": { + "type": "integer", + "description": "The minimum item count." + } + }, + "description": "The flow pagination policy." + } + } + } + }, + "required": [ + "type" + ] + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnection" + ] + }, + "inputs": { + "allOf": [ + { + "type": "object", + "properties": { + "host": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host" + }, + "method": { + "type": "string", + "default": "POST", + "description": "The method of the request." + }, + "path": { + "type": "string", + "description": "The path for the request." + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "host", + "path" + ] + }, + { + "type": "object", + "properties": { + "operationOptions": { + "$ref": "#/properties/actions/additionalProperties/allOf/1/properties/operationOptions" + }, + "retryPolicy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "None", + "Fixed", + "Exponential" + ], + "description": "The type of retry policy to use." + }, + "interval": { + "type": "string", + "description": "The interval between retries." + }, + "count": { + "type": "integer", + "description": "The number of times a retry should be attempted." + }, + "minimumInterval": { + "type": "string", + "description": "The minimum time delay for the exponential retry." + }, + "maximumInterval": { + "type": "string", + "description": "The maximum time delay for the exponential retry." + } + }, + "description": "The retry policy." + }, + "authentication": { + "oneOf": [ + { + "type": "string", + "description": "A Logic Apps expression." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Basic" + ], + "description": "The HTTP authentication type." + }, + "username": { + "type": "string", + "description": "The username." + }, + "password": { + "type": "string", + "description": "The password." + } + }, + "description": "The HTTP basic authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ClientCertificate" + ], + "description": "The HTTP authentication type." + }, + "password": { + "type": "string", + "description": "The password." + }, + "pfx": { + "type": "string", + "description": "The PFX." + } + }, + "description": "The HTTP client certificate authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "None" + ], + "description": "The HTTP authentication type." + } + }, + "additionalProperties": false, + "description": "No HTTP authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "ActiveDirectoryOAuth" + ], + "description": "The HTTP authentication type." + }, + "authority": { + "type": "string", + "description": "The authority." + }, + "tenant": { + "type": "string", + "description": "The tenant ID." + }, + "audience": { + "type": "string", + "description": "The audience." + }, + "clientId": { + "type": "string", + "description": "The client ID." + }, + "secret": { + "type": "string", + "description": "The secret." + }, + "pfx": { + "type": "string", + "description": "The PFX." + }, + "password": { + "type": "string", + "description": "The password used to decrypt the PFX." + } + }, + "description": "The HTTP OAuth authentication." + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Raw" + ], + "description": "The HTTP authentication type." + }, + "scheme": { + "type": "string", + "description": "The raw authentication scheme." + }, + "parameter": { + "type": "string", + "description": "The raw authentication parameter." + }, + "value": { + "type": "string", + "description": "The raw authentication value." + } + }, + "description": "The HTTP raw authentication." + } + ], + "description": "The HTTP authentication." + } + }, + "description": "The retryable action input." + } + ], + "description": "The ApiConnection operation input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnectionWebhook" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs" + }, + { + "type": "object", + "properties": { + "schema": { + "description": "The schema of an API connection webhook operation." + }, + "accessKeyType": { + "type": "string", + "enum": [ + "Primary", + "Secondary" + ], + "description": "The access key type." + } + } + } + ], + "description": "The API connection webhook operation input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiManagement" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "api": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/ApiManagementApiReference" + }, + "method": { + "type": "string", + "description": "The method of the request." + }, + "pathTemplate": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs/definitions/PathTemplate" + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "body": { + "description": "The body of the request." + }, + "subscriptionKey": { + "type": "string", + "description": "The subscription key." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "api", + "pathTemplate" + ] + } + ], + "description": "The API Management operation input.", + "definitions": { + "ApiManagementApiReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The API Management API reference." + }, + "PathTemplate": { + "description": "The path template for the request." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "SendToBatch" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "host": { + "type": "object", + "properties": { + "workflow": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host/definitions/FlowReference" + }, + "triggerName": { + "type": "string", + "description": "The trigger name." + } + }, + "required": [ + "triggerName", + "workflow" + ], + "description": "The workflow host.", + "definitions": { + "FlowReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + }, + { + "required": [ + "id" + ] + } + ], + "description": "The flow reference." + } + } + }, + "batchName": { + "type": "string", + "description": "The batch name." + }, + "partitionName": { + "type": "string", + "description": "The partition name." + }, + "messageId": { + "type": "string", + "description": "The message identifier." + }, + "content": { + "description": "The content." + } + }, + "required": [ + "host", + "batchName", + "content" + ] + } + ], + "description": "The Send to Batch action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Compose" + ] + }, + "inputs": { + "description": "The Compose action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "AddToTime" + ] + }, + "inputs": { + "type": "object", + "properties": { + "baseTime": { + "type": "string", + "description": "The base time." + }, + "interval": { + "type": "integer", + "description": "The interval of time." + }, + "timeUnit": { + "type": "string", + "description": "The unit of time specified." + } + }, + "required": [ + "baseTime", + "interval", + "timeUnit" + ], + "description": "The inputs for the add to time or subtract from time operation kinds." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "ConvertTimeZone" + ] + }, + "inputs": { + "type": "object", + "properties": { + "baseTime": { + "type": "string", + "description": "The base time." + }, + "sourceTimeZone": { + "type": "string", + "description": "The time zone to convert from." + }, + "destinationTimeZone": { + "type": "string", + "description": "The time zone to convert to." + }, + "formatString": { + "type": "string", + "description": "The date time format string." + } + }, + "required": [ + "baseTime", + "sourceTimeZone", + "destinationTimeZone" + ], + "description": "The convert time zone operation kind input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "CurrentTime" + ] + }, + "inputs": { + "type": "object", + "additionalProperties": false + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "GetFutureTime" + ] + }, + "inputs": { + "type": "object", + "properties": { + "interval": { + "type": "integer", + "description": "The interval of time." + }, + "timeUnit": { + "type": "string", + "description": "The unit of time specified." + } + }, + "required": [ + "interval", + "timeUnit" + ], + "description": "The inputs for the get future time and get past time operation kinds." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "GetPastTime" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/8/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Expression" + ] + }, + "kind": { + "enum": [ + "SubtractFromTime" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/5/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "FlatFileDecoding" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "integrationAccount": { + "type": "object", + "properties": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name." + } + }, + "required": [ + "name" + ], + "description": "The artifact information." + } + }, + "required": [ + "schema" + ], + "description": "The integration account schema information." + } + }, + "required": [ + "content", + "integrationAccount" + ] + } + ], + "description": "The content and schema action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "FlatFileEncoding" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs" + }, + { + "type": "object", + "properties": { + "emptyNodeGenerationMode": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/12/properties/inputs/definitions/EmptyNodeGenerationMode" + } + } + } + ], + "description": "The flat file encoding action input.", + "definitions": { + "EmptyNodeGenerationMode": { + "type": "string", + "enum": [ + "ForcedDisabled", + "ForcedEnabled", + "HonorSchemaNodeProperty" + ], + "description": "The empty node generation mode." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Function" + ] + }, + "inputs": { + "type": "object", + "allOf": [ + { + "properties": { + "function": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference" + } + } + }, + { + "properties": { + "functionApp": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionAppReference" + }, + "uri": { + "type": "string", + "description": "The operation URI as defined in the function app Swagger." + } + } + } + ], + "properties": { + "method": { + "type": "string", + "description": "The method of the request." + }, + "queries": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "description": "The queries for the request." + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "description": "The function action input.", + "definitions": { + "FunctionAppReference": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The function app reference." + }, + "FunctionReference": { + "allOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The resource reference identifier." + }, + "name": { + "type": "string", + "description": "The resource reference name." + }, + "type": { + "type": "string", + "description": "The resource reference type." + } + }, + "description": "The base resource reference." + } + ], + "description": "The function reference." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Http" + ] + }, + "inputs": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + } + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/5" + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "IntegrationAccountArtifactLookup" + ] + }, + "inputs": { + "type": "object", + "properties": { + "artifactType": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/16/properties/inputs/definitions/ArtifactType" + }, + "artifaceName": { + "type": "string", + "description": "The name of the artifact." + } + }, + "description": "The integration account artifact lookup input.", + "definitions": { + "ArtifactType": { + "type": "string", + "enum": [ + "Schema", + "Map", + "Partner", + "Agreement" + ], + "description": "The type of artifact." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Join" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "joinWith": { + "type": "string", + "description": "The separator." + } + }, + "required": [ + "from" + ], + "description": "The Join action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Liquid" + ] + }, + "kind": { + "enum": [ + "JsonToJson", + "JsonToText", + "XmlToJson", + "XmlToText" + ] + }, + "inputs": { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "integrationAccount": { + "type": "object", + "properties": { + "map": { + "#ref": "common/ArtifactInformation.json" + } + }, + "required": [ + "map" + ], + "description": "The integration account map information." + }, + "transformedContentSchema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "required": [ + "content", + "integrationAccount" + ], + "description": "The liquid action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ParseJson" + ] + }, + "inputs": { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "description": "The Parse JSON action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Query" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "where": { + "type": "string", + "description": "The where condition." + } + }, + "required": [ + "from" + ], + "description": "The query action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Response" + ] + }, + "inputs": { + "type": "object", + "properties": { + "statusCode": { + "type": [ + "integer", + "string" + ], + "description": "The status code for the response." + }, + "headers": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + } + } + ], + "description": "The headers for the request." + }, + "body": { + "description": "The body of the response." + }, + "schema": { + "$schema": "http://json-schema.org/draft-04/schema#" + } + }, + "required": [ + "statusCode" + ], + "description": "The response action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Foreach" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "foreach": { + "type": [ + "array", + "string" + ], + "description": "The For Each expression." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "If" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "else": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfElseProperty" + }, + "expression": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/23/definitions/IfExpressionObjectProperty" + } + ], + "description": "The If expression." + } + }, + "definitions": { + "IfElseProperty": { + "type": "object", + "properties": { + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + } + }, + "IfExpressionObjectProperty": { + "description": "The If object expression property.", + "$comment": "TODO(joechung): Find out what the schema is for If expression objects." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Scope" + ] + }, + "inputs": { + "type": "object", + "properties": { + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Switch" + ] + }, + "cases": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/definitions/FlowTemplateActionCaseBranch" + }, + "description": "The Switch action case branches." + }, + "default": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "description": "The actions." + } + }, + "description": "The flow template action branch." + }, + "expression": { + "type": [ + "number", + "string" + ], + "description": "The Switch expression." + } + }, + "definitions": { + "FlowTemplateActionCaseBranch": { + "type": "object", + "properties": { + "case": { + "description": "The case." + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + } + }, + "required": [ + "case" + ], + "description": "The flow template action case branch." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Until" + ] + }, + "actions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/25/properties/default" + }, + "expression": { + "type": "string", + "description": "The Until expression." + }, + "limit": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/26/definitions/UntilLimitProperty" + } + }, + "definitions": { + "UntilLimitProperty": { + "type": "object", + "properties": { + "count": { + "type": [ + "number", + "string" + ], + "description": "The until count limit." + }, + "timeout": { + "type": "string", + "description": "The until timeout limit." + } + }, + "description": "The Until limits." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Select" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The select source." + }, + "select": { + "description": "The select transform." + } + }, + "required": [ + "from", + "select" + ], + "description": "The Select action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Table" + ] + }, + "inputs": { + "type": "object", + "properties": { + "from": { + "type": [ + "array", + "string" + ], + "description": "The source." + }, + "format": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableFormat" + }, + "columns": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/28/properties/inputs/definitions/TableColumn" + } + } + }, + "required": [ + "from" + ], + "description": "The table action input.", + "definitions": { + "TableColumn": { + "type": "object", + "properties": { + "header": { + "type": "string", + "description": "The header." + }, + "value": { + "description": "The value." + } + }, + "description": "The table column." + }, + "TableFormat": { + "type": "string", + "enum": [ + "CSV", + "HTML" + ], + "description": "The table format." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Terminate" + ] + }, + "inputs": { + "type": "object", + "properties": { + "runStatus": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/0/properties/runAfter/additionalProperties/items" + }, + { + "enum": [ + "Cancelled", + "Failed", + "Succeeded" + ] + } + ] + }, + "runError": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/29/properties/inputs/definitions/TerminateActionRunError" + } + }, + "description": "The Terminate action input.", + "definitions": { + "TerminateActionRunError": { + "type": "object", + "properties": { + "code": { + "type": [ + "number", + "string" + ], + "description": "The code." + }, + "message": { + "type": "string", + "description": "The message." + } + }, + "description": "The run error." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "AppendToArrayVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "AppendToStringVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "DecrementVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "IncrementVariable" + ] + }, + "inputs": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name." + }, + "type": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs/definitions/FlowVariableDataType" + }, + "value": { + "description": "The variable value." + } + }, + "description": "The variable action input.", + "definitions": { + "FlowVariableDataType": { + "type": "string", + "enum": [ + "Array", + "Boolean", + "Float", + "Integer", + "Object", + "String" + ], + "description": "The flow variable data type." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "InitializeVariable" + ] + }, + "inputs": { + "type": "object", + "properties": { + "variables": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + }, + "maxItems": 1, + "minItems": 1 + } + }, + "description": "The Initialize Variable action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "SetVariable" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/33/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Wait" + ] + }, + "inputs": { + "type": "object", + "properties": { + "interval": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/TimeInterval" + }, + "until": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/36/properties/inputs/definitions/WaitUntil" + } + }, + "maxProperties": 1, + "description": "The Wait action input.", + "definitions": { + "TimeInterval": { + "type": "object", + "properties": { + "unit": { + "allOf": [ + { + "description": "The wait unit." + }, + { + "type": "string", + "enum": [ + "Second", + "Minute", + "Hour", + "Day", + "Week", + "Month", + "Year" + ] + } + ] + }, + "count": { + "type": "integer", + "description": "The wait count." + } + }, + "description": "The wait interval." + }, + "WaitUntil": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "description": "The timestamp." + } + }, + "description": "The Until." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Workflow" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "host": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/3/properties/inputs/allOf/1/properties/host" + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "host" + ] + } + ], + "description": "The flow action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "XmlValidation" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/11/properties/inputs" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Xslt" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "content": { + "description": "The content." + }, + "parameters": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The XSLT (Extensible Stylesheet Language Transformations) parameters." + }, + "integrationAccount": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/18/properties/inputs/properties/integrationAccount" + }, + "function": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/definitions/FunctionReference/allOf/0" + } + ], + "description": "The function reference." + }, + "transformOptions": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/39/properties/inputs/definitions/XsltTransformOptions" + } + }, + "required": [ + "content" + ] + } + ], + "description": "The XSLT (Extensible Stylesheet Language Transformations) action input.", + "definitions": { + "XsltTransformOptions": { + "type": "string", + "description": "The XSLT options flag." + } + } + } + } + } + ] + } + ], + "description": "A flow template action.", + "definitions": { + "FlowTemplateActionBranch": { + "type": "object", + "properties": { + "actions": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/actions/additionalProperties" + }, + "description": "The actions." + } + }, + "description": "The flow template action branch." + }, + "FlowTemplateActionCaseBranch": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/definitions/FlowTemplateActionBranch" + }, + { + "type": "object", + "properties": { + "case": { + "description": "The case." + } + }, + "required": [ + "case" + ], + "description": "The flow template action case branch." + } + ] + }, + "FlowTemplateActionUntil": { + "type": "object", + "properties": { + "limit": { + "description": "The do-until limit." + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "expression": { + "type": "string", + "description": "The expression." + }, + "dependsOn": { + "type": "string", + "description": "The dependency." + } + }, + "description": "The template action expression condition." + }, + "description": "The do-until conditions." + } + }, + "description": "The do-until policy." + } + } + }, + "description": "The flow run actions." + }, + "metadata": { + "description": "The definition metadata." + }, + "$schema": { + "enum": [ + "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#" + ], + "type": "string", + "description": "The definition schema." + }, + "contentVersion": { + "type": "string", + "pattern": "(^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$)", + "description": "The flow content version. Specify using a 4-digit format, e.g., 1.0.0.0" + }, + "parameters": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/properties/outputs/additionalProperties/allOf/0" + }, + { + "properties": { + "defaultValue": { + "description": "The default parameter value." + }, + "allowedValues": { + "type": "array", + "description": "The allowed parameter values." + } + }, + "description": "The flow input template parameter." + } + ] + }, + "description": "The flow parameters." + }, + "triggers": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/1" + }, + { + "type": "object", + "properties": { + "conditions": { + "type": "array", + "items": { + "$ref": "#/properties/actions/additionalProperties/definitions/FlowTemplateActionUntil/properties/conditions/items" + }, + "description": "The operation conditions." + }, + "splitOn": { + "type": "string", + "description": "The trigger split on." + }, + "splitOnConfiguration": { + "type": "object", + "properties": { + "correlation": { + "type": "object", + "properties": { + "clientTrackingId": { + "type": "string", + "description": "The client tracking identifier." + } + }, + "description": "The correlation properties." + } + }, + "description": "The trigger SplitOn configuration." + }, + "correlation": { + "type": "object", + "properties": { + "clientTrackingId": { + "type": "string", + "description": "The client tracking identifier." + } + }, + "description": "The correlation properties." + } + } + }, + { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiConnection" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs" + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/1" + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "ApiManagement" + ] + }, + "inputs": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/2/properties/inputs" + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Batch" + ] + }, + "inputs": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchActionMode" + }, + "batchGroupName": { + "type": "string", + "description": "The batch group name." + }, + "configurations": { + "type": "object", + "additionalProperties": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchConfiguration" + }, + "description": "The batch configurations." + } + }, + "descripton": "The batch action input.", + "definitions": { + "BatchActionMode": { + "type": "string", + "enum": [ + "Inline", + "IntegrationAccount" + ], + "description": "The batch action mode." + }, + "BatchConfiguration": { + "type": "object", + "properties": { + "releaseCriteria": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/3/properties/inputs/definitions/BatchReleaseCriteria" + } + }, + "description": "The batch configuration." + }, + "BatchReleaseCriteria": { + "type": "object", + "properties": { + "messageCount": { + "type": "integer", + "description": "The message count." + }, + "batchSize": { + "type": "integer", + "description": "The batch size in bytes." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + }, + "description": "The batch release criteria." + } + } + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Http" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/0/properties/inputs/allOf/1" + }, + { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "The URI of the request." + }, + "method": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/method" + }, + "queries": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/13/properties/inputs/properties/queries" + }, + "cookie": { + "type": "string", + "description": "The cookie for the request." + }, + "body": { + "description": "The body of the request." + }, + "headers": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/21/properties/inputs/properties/headers" + } + }, + "required": [ + "method", + "uri" + ] + } + ], + "description": "The HTTP action input." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "HttpWebhook" + ] + }, + "inputs": { + "allOf": [ + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs" + }, + { + "type": "object", + "properties": { + "subscribe": { + "anyOf": [ + { + "$comment": "It is likely a bug that HTTP webhooks are allowed to put an arbitrary JSON value in the \"subscribe\" property." + }, + { + "type": "string" + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + ] + }, + "unsubscribe": { + "anyOf": [ + { + "$comment": "It is likely a bug that HTTP webhooks are allowed to put an arbitrary JSON value in the \"unsubscribe\" property." + }, + { + "type": "string" + }, + { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/4/properties/inputs" + } + ] + }, + "accessKeyType": { + "$ref": "#/properties/actions/additionalProperties/allOf/2/oneOf/1/properties/inputs/allOf/1/properties/accessKeyType" + } + }, + "required": [ + "subscribe" + ], + "description": "The HTTP webhook operation input.", + "$comment": "It is likely a bug that HTTP webhooks do not have to specify the \"unsubscribe\" property." + } + ] + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Recurrence" + ] + }, + "recurrence": { + "type": "object", + "properties": { + "frequency": { + "type": "string", + "enum": [ + "Second", + "Minute", + "Hour", + "Day", + "Week", + "Month", + "Year" + ], + "description": "The flow recurrence frequency." + }, + "interval": { + "type": "integer", + "description": "The recurrence interval." + }, + "count": { + "type": "integer", + "description": "The recurrence count." + }, + "startTime": { + "type": "string", + "description": "The recurrence start time." + }, + "endTime": { + "type": "string", + "description": "The recurrence end time." + }, + "timeZone": { + "type": "string", + "description": "The recurrence time zone." + }, + "schedule": { + "type": "object", + "properties": { + "minutes": { + "type": "array", + "items": { + "type": [ + "integer", + "string" + ] + }, + "description": "The minutes on which this job should fire." + }, + "hours": { + "type": "array", + "items": { + "type": [ + "integer", + "string" + ] + }, + "description": "The hours on which this job should fire." + }, + "weekDays": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "description": "Specifies the day of the week." + }, + "description": "The days of the week on which this job should fire." + }, + "monthDays": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "The days of the month on which this job should fire." + }, + "monthlyOccurrences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "dayOfWeek": { + "type": "string", + "enum": [ + "Friday", + "Monday", + "Saturday", + "Sunday", + "Thursday", + "Tuesday", + "Wednesday" + ], + "description": "Specifies the day of the week." + }, + "occurrence": { + "type": "integer", + "description": "Specifies the week count of this occurrence." + } + }, + "required": [ + "dayOfWeek", + "occurrence" + ], + "description": "Indicates a day of week and a count of weeks from the beginning or end of the month on which the day occurs." + }, + "description": "The monthly occurence on which this job should fire." + } + }, + "description": "The job recurrence schedule." + } + }, + "required": [ + "frequency", + "interval" + ], + "description": "The flow recurrence." + } + }, + "required": [ + "recurrence" + ] + }, + { + "type": "object", + "properties": { + "type": { + "enum": [ + "Request" + ] + }, + "kind": { + "enum": [ + "Alert", + "AzureMonitorAlert", + "Button", + "EventGrid", + "Geofence", + "Http", + "PowerApp", + "SecurityCenterAlert" + ] + }, + "inputs": { + "type": "object", + "properties": { + "host": { + "type": "object", + "properties": { + "api": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/7/properties/inputs/properties/host/definitions/ApiConnectionProvider" + } + }, + "description": "The host.", + "definitions": { + "ApiConnectionProvider": { + "type": "object", + "properties": { + "runtimeUrl": { + "type": "string", + "format": "uri" + } + }, + "description": "The API connection provider." + } + } + }, + "operationId": { + "type": "string", + "description": "The operation identifier." + }, + "parameters": { + "type": "object", + "additionalItems": {}, + "description": "The operation parameters." + }, + "schema": { + "description": "The schema of the manual action input." + }, + "relativePath": { + "type": "string", + "description": "The relative path." + }, + "method": { + "type": "string", + "enum": [ + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ], + "description": "The HTTP method." + } + }, + "description": "The manual action input." + } + } + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "SlidingWindow" + ] + }, + "inputs": { + "type": "object", + "properties": { + "delay": { + "type": "string", + "description": "The delay." + } + }, + "description": "The sliding window action input." + }, + "recurrence": { + "$ref": "#/properties/triggers/additionalProperties/allOf/2/oneOf/6/properties/recurrence" + } + } + } + ] + } + ], + "description": "A flow template trigger." + }, + "description": "The flow triggers." + }, + "outputs": { + "type": "object", + "additionalProperties": { + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "Array", + "Bool", + "Float", + "Int", + "Object", + "SecureObject", + "SecureString", + "String" + ], + "description": "The parameter type." + }, + "value": { + "description": "The parameter value." + }, + "metadata": { + "description": "The parameter metadata." + }, + "description": { + "type": "string", + "description": "The parameter description." + } + }, + "description": "The flow template parameter." + }, + { + "properties": { + "error": { + "description": "The error of the output parameter." + } + } + } + ], + "description": "The flow output template parameter." + }, + "description": "The flow outputs." + }, + "description": { + "type": "string", + "description": "The definition description." + } + }, + "required": [ + "$schema", + "contentVersion" + ] +}