Skip to main content

Tasks

The manifest YAML reference — every field, how it's validated, and how placeholders and progress work.

An install.yaml has two levels: the manifest (top-level) and its tasks, grouped into named lifecycle actions.

Minimal example​

The smallest valid manifest installs a single MSI:

ReleaseId: ID.MyApp@1.4.0
Type: Deploy/V2
Actions:
install:
Tasks:
- Type: Execute/v2
DeployType: MSI
ExeFile: my-app.msi

A legacy manifest with a top-level Tasks: list (no Actions:) is still accepted — its tasks become the install action.

Manifest-level fields​

ReleaseId: ID.MyApp@1.4.0     # required — must match the release being deployed
Type: Deploy/V2 # required — always exactly "Deploy/V2"
MinAgentVersion: 2.0.0 # optional — minimum agent semver required to run this manifest
Actions: # required — named actions, each with its own task tree
install:
Tasks:
- ...
FieldRequiredDescription
ReleaseId✅The release this manifest installs. Must equal the catalog id of the release being deployed (guards against a stale/mismatched install.yaml). The all-caps ReleaseID spelling is also accepted.
Type✅The manifest kind. Must be the literal Deploy/V2.
MinAgentVersion❌A semver string. If the running agent is older, the deploy fails before any task runs. Omit to skip.
Actions✅A map of action name → { Tasks, Repeatable?, Description? }. Must contain at least one action. See Lifecycle Actions.
Tasks—Deprecated legacy form: a top-level task list, used as the install action. Not allowed together with Actions.
Field-name casing

Manifest keys are PascalCase (ReleaseId, Type, Actions, Tasks). The release identifier also accepts the all-caps ReleaseID spelling — both ReleaseId and ReleaseID are valid, at the manifest level and on a Deploy/v2 / FleetDeploy/v2 task. Action names and placeholder sources (Device, Env, Config, ConfigJson, ConfigPath, DeviceConfig, Release) are matched case-insensitively, but write manifest keys as shown.

Task-level fields​

Tasks:
- Type: Execute/v2 # required — the kind of task
Name: install-app # optional — label used in the log and status lines
DeployType: MSI # required — the method used to run it
ExeFile: my-app.msi # the delivered artifact to run
Rule: { ... } # optional — device must satisfy this or the deploy fails
Arguments: "/qn PORT=8080" # optional — CLI arguments, may contain {placeholders}
Weight: 60 # optional — relative share of the progress bar
LaunchTimeoutSec: 60 # optional — seconds allowed to start the process
ExecutionTimeoutMin: 15 # optional — minutes allowed to finish

Task types and what they do live on Action. Deploy methods:

GroupValuesUsed by
InstallMSI, RPM, DEB, Script, APIExecute
Uninstall / removalMSI_Uninstall, RPM_Uninstall, DEB_Uninstall, Script, APIExecute, Revert
VerifyAPI (2xx = pass), Script (exit 0 = pass), SSE (wait for a matching frame)Verification
ReservedDockerCompose, Helm, Command—

A dependency task looks different — it has Type: Deploy/v2, an Action to run, and an optional ReleaseId (omitted = this release), carrying no ExeFile/DeployType (see Orchestrator and Lifecycle Actions). A group task has Type: Group/v2 and a Tasks list, carrying no DeployType/ExeFile of its own. A fleet rollout task has Type: FleetDeploy/v2, an Action, an optional ReleaseId, and a required Rule (plus optional Scope and CompletionPolicy) — it runs that action across the managed fleet, carrying no ExeFile/DeployType (see Fleet deploy).

"Command" is reserved, not runnable today

Command is a planned deploy method — a raw command line, alongside API, without a delivered script file. It isn't runnable yet: a raw command line today is what Script already covers. On the dashboard's release-authoring side there's also a separate, not-yet-live concept with the same name (command, alongside import/api) reserved as a future way to source a component beyond uploading a file — see Attach an Artifact. The two aren't wired together yet.

What to enter, per method​

DeployTypeWhat you must supplyOptional
MSI / RPM / DEBExeFile — the delivered installer packageArguments
Script (install)ExeFile — the delivered scriptArguments
API (install/verify)Target — the endpoint URLMethod, Header, Body, Params
SSE (verify)Target — the event-stream endpoint, Message — the frame to matchGraceTimeSec
*_UninstallExeFile or Target — the package/product-code handleForce, Arguments
Script (revert)ExeFile — the cleanup scriptArguments, Force
API (revert)Target — the removal endpointMethod, Header, Body, Params, Force

Full field reference​

FieldApplies toDescription
TypeallThe task kind — see Action.
NameallAn optional label for the task, shown in the deploy log and status lines instead of its file/target.
DeployTypeExecute, Verification, RevertThe method that runs the task (table above). Must be compatible with Type.
ExeFileExecute, Revert (file/uninstall methods)The delivered artifact to run — an installer, a script, or an uninstaller/package.
TargetExecute/Verification/Revert (API/SSE/uninstall)A non-file handle: an endpoint URL (API/SSE) or a removal handle — product code / package name (uninstall). May contain {placeholders}.
ReleaseIdDeploy, FleetDeployThe release whose action a Deploy/v2 runs on this device or a FleetDeploy/v2 runs across the fleet. Optional — omitted (or equal to the manifest's own) means this release. The all-caps ReleaseID spelling is also accepted.
ActionDeploy, FleetDeployThe lifecycle action of the target release to run (e.g. install, restart, uninstall). Omitted means install — deprecated, always set it.
TasksallA nested list of child tasks this task binds and awaits (see Orchestrator).
RuleallA rule-engine condition evaluated on the device right before the task runs. YAML object or inline JSON string.
ArgumentsExecute, RevertA single CLI argument string for the process. May contain {placeholders}.
MessageVerification (SSE)The expected object a stream frame must match to pass; string values may be {placeholders}.
MethodExecute/Verification (API)HTTP method for an API call (default GET).
HeaderAPI / SSERequest headers map.
BodyAPI / SSERequest body.
ParamsAPI / SSEURL query parameters, percent-encoded; may contain {placeholders}.
WeightallThe task's share of the progress bar within its sibling list (see Progress & weights).
CausesRebootExecuteDeclares the task reboots the device. Requires a nested Verification child — see Action.
ForceExecute/Revert (uninstall methods)Forces the removal — e.g. treat "not installed" as success, ignore dependencies.
GraceTimeSecVerification (and any retryable task)Grace window within which a failed run is retried before the task fails.
RetryCountretryable tasksMaximum attempts before failing.
RetryBackoffSecretryable tasksDelay between retries.
LaunchTimeoutSecExecuteTime to launch before failing. Literal or {placeholder}. Default 60; falls back to Release.metadata.timeoutLaunch.
ExecutionTimeoutMinExecute, Verification, Revert, Deploy; FleetDeploy (local target)Completion timeout for the handler or the entire delegated local action. Literal or {placeholder}. Default 15; falls back to Release.metadata.timeoutInstallation. A handler timeout prevents its children from starting; a delegated-action timeout signals cancellation to its task tree. Ignored on Group/v2. See Orchestrator.
ScopeFleetDeployWhich slice of the managed fleet to target — Platform (default), Reactive, or All.
CompletionPolicyFleetDeployHow success/failure propagates across matched devices — AllConnected (default), Partial, or AllReachable.

Reserved fields (parsed but ignored today):

FieldFuture task typePurpose
ConfigGroupConfigThe config group name to apply.
TryRollbackToPreviousRevertReinstall the previous version before uninstalling.

Validation & requirements​

Before any task runs, the manifest is validated for the action being run. A failure at any stage marks that action Error and writes the reason to the deploy log — an action either runs cleanly or is rejected up front; it never half-applies. Only the invoked action (and every action it runs through Deploy/v2) is checked, so a flaw in an unrelated action never blocks this one.

StageWhat it checks
readinstall.yaml can be read from disk.
parseValid YAML that deserializes into a manifest.
structure + task rulesReleaseId not empty, Type is Deploy/V2, at least one action. For the invoked action: every task individually valid, task ordering valid (each Verification/Revert has a target), every Group non-empty, and every rebooting task has a nested Verification.
main-releaseThe manifest's ReleaseId equals the release being deployed.
agent-versionRunning agent semver ≥ MinAgentVersion (skipped if absent/unparsable).
artifactsAcross the whole tree the action runs: every release's delivery is Done (download status and lifecycle state) with all its artifacts present on the agent's disk; every task's ExeFile exists; every Deploy/v2 target action exists and is itself validated — another release must be a registered dependency of its parent, delivered and ready, and itself a V2 component. A FleetDeploy/v2 target is checked for existence only (each remote device validates its own tree).
device contextDevice metadata gathered for rule evaluation and placeholder resolution.
normalize weightsWeights of the invoked action scaled so each sibling list sums to 100.

Per-task input rules​

  • Execute — needs the input for its DeployType: a delivered ExeFile for MSI/RPM/DEB/Script; a Target (endpoint URL) for API; a removal handle — ExeFile or Target — for *_Uninstall
  • Verification — needs a verify DeployType (API/Script/SSE); an SSE verification additionally requires a Message object; an API call's Method, if given, must be a valid HTTP verb
  • Revert — needs a removal DeployType (*_Uninstall/Script/API) and its handle
  • Deploy — a self-targeted Action (no ReleaseId, or the manifest's own) must exist in this manifest; another release's action is checked when the tree is walked
  • FleetDeploy — needs a Rule that selects the target fleet; a self-targeted Action must exist in this manifest; Scope and CompletionPolicy are optional
  • Group — must bind a non-empty Tasks list
  • DeployType must be compatible with Type (table above)
  • A Rule, if present, must contain at least one condition (and/or/none)

Task-ordering rules​

A Verification or Revert only makes sense when it has something to act on — see Action for what triggers each and how nesting works. Validation checks this within each Tasks list and reports the offending chain path (e.g. Task[1.0.2]).

Requirements checklist​

For a manifest to deploy successfully on a device:

  • ReleaseId matches the deployed release exactly, and Type is Deploy/V2
  • Agent version ≥ MinAgentVersion (if set)
  • Every release in the tree has a Done delivery (status and state) with all its artifacts present on disk
  • Every task supplies its method's input (ExeFile / Target / Action / non-empty Tasks)
  • Every Verification/Revert has a target; every Group is non-empty; every rebooting task has a nested Verification
  • Every Deploy/v2 target action exists; another release is a registered dependency of its parent, ready, and ships its own install.yaml
  • Every task's Rule passes on the target device, and every {placeholder} resolves to a value that fits its slot

Placeholders — dynamic values at runtime​

Placeholders of the form {Source.Path} are resolved on the device, just before the task runs, in Arguments, Target, Header and Params values, the Body, a verification Message, and both timeout fields.

Syntax: {Source.Path} — Source is one of the sources below (case-insensitive); Path is a dotted path into that source (letters, digits, _ and .).

SourceResolves fromExampleResolves to
DeviceThe device metadata/context tree — see Context{Device.type}, {Device.os.name}Namer, windows
ReleaseThe release record; metadata under Release.metadata.*{Release.version}, {Release.metadata.timeoutInstallation}1.4.0, 20
ConfigThe device's synced config groups (GetConfig) — a group, or a value inside it{Config.network.proxy.host}10.0.0.5
ConfigJsonThe same node as Config, always as compact JSON text{ConfigJson.network}{"proxy":{"host":"10.0.0.5"}}
ConfigPathThe absolute path of a config group's YAML file on the device{ConfigPath.network}C:\…\network.yaml
DeviceConfigThe agent's own runtime settings (config.yaml), dotted by zone{DeviceConfig.device.meta_data.name}the configured value
EnvAn OS environment variable{Env.COMPUTERNAME}the env value
Tasks:
- Type: Execute/v2
DeployType: MSI
ExeFile: my-app.msi
Arguments: "/qn PORT={Config.app.port} DEVICE={Device.id} SITE={DeviceConfig.device.meta_data.name}"

On a device with id dev-42, an app config group whose port is 8080, and device name north, the resolved command line becomes /qn PORT=8080 DEVICE=dev-42 SITE=north.

Config changed meaning

{Config.*} reads the device's synced config groups. Manifests that used {Config.*} for the agent's runtime config.yaml settings must switch to {DeviceConfig.*}.

Config groups in depth​

  • Group vs. value — {Config.<group>} is the whole group; {Config.<group>.<key.path>} is the value at that path (scalar, object or array).
  • Dotted group names — a path resolves by the shortest prefix that names a group: {Config.getmap.delivery} is the delivery key of the getmap group when that group exists, and falls back to a group named getmap.delivery when it doesn't.
  • Nested placeholders — a {…} placeholder stored inside a config value is resolved too.
  • Fit to the slot — a text slot (Arguments, Target, a header or query-param value, or a placeholder inside longer text) needs a scalar; a group or object there is an error. To embed a whole group or object, make it the only content of a Body (or Message) value — config: "{Config.network}" — and it is inserted as real JSON. To pass it as text on purpose, use {ConfigJson.*}.
  • Hand a tool the file — {ConfigPath.<group>} gives the group's file path, so a script or service can read the whole group itself.
- Type: Execute/v2
DeployType: API
Method: POST
Target: "http://localhost:9000/config/import"
Params:
cfg: "{ConfigJson.network}" # text slot → the group as JSON text
Body:
site: "{Config.network.site}" # a scalar value
config: "{Config.network}" # the whole group, embedded as an object

Rules & gotchas

  • Outside Config / ConfigJson in a Body or Message, a placeholder must resolve to a scalar (string, number, bool) — an object/array is an error
  • An unresolvable placeholder (missing key, unknown source, missing config group) fails the task — it's never left unresolved in the string
  • Timeout fields accept a literal or a placeholder: ExecutionTimeoutMin: "{Release.metadata.timeoutInstallation}"; if it doesn't resolve to a number, the default is used
  • When a timeout field is omitted, the engine uses, in order: the release-metadata default, then the built-in default (60 s to launch, 15 min to complete)

Weights & progress​

Each task can carry a Weight — its share of the progress bar. Weights are normalized per sibling list, so each Tasks list sums to 100:

  • If no task in a list sets a weight, that list's progress is distributed evenly
  • If weights are set but don't sum to 100, they're scaled proportionally (the last task absorbs rounding)

A leaf's real share of the whole bar is its weight × the weight of each ancestor on the way up.

How a parent splits its share​

How a parent divides its share between its own step and its children depends on the parent's type:

  • A Group/v2 runs no step of its own — it is a pure container, so its children take its entire share.
  • An actionable parent (an Execute that also binds children) runs its own install and its children, so it reserves one slot for itself: with N children the parent's own step takes 1/(N+1) of the node's share and the children split the remaining N/(N+1).

So an Execute with one nested Verification splits that node 50/50 — the install is half, the check is half.

What counts as progress​

Progress is the sum, across the tree, of each leaf's share × how far that leaf has got:

  • A leaf that reached a terminal-complete state (Done or Skipped) counts in full.
  • A leaf still running a sub-deploy — a Deploy/v2 dependency or a FleetDeploy/v2 rollout — counts partially, folding in its children's live progress rather than jumping from 0 to 100. For a fleet, each target device contributes an even split of its delivery and deploy phases, and the task's progress is the mean across the devices it is acting on.
  • Any other leaf counts as 0 until it completes.
Tasks:
- Type: Execute/v2
DeployType: MSI
ExeFile: big-package.msi
Weight: 80 # 80% of this list
- Type: Execute/v2
DeployType: Script
ExeFile: quick-config.ps1
Weight: 20 # 20%

Weights are cosmetic (progress reporting only) — they don't affect ordering or success.

See also​