// Project Steps

Update a project step

Update step name, scope, run mode, parallelism, error handling, and properties.

PUT/api/project/step

Description

Updates a step on a project. Pass only the fields to change. propertiesJson is a JSON-encoded string matching the step template's property schema.

Filters (machineIdFilter, machineTagFilter, cloudTargetTagFilter) constrain which targets the step runs on within the step's selected environments.

Parameters

NameInTypeRequiredDescription
projectStepId body string yes ID of the step.
name body string no New step name.
description body string no New description.
stepTemplateId body string no Move the step onto a step template as it stands now - another template's id to switch it, or the step's own template id to pull a newer version of it in. See below.
runOn body string no See below.
errorAction body string no See below.
disabled body boolean no Disable the step without removing it.
executeCondition body string no See below.
executeConditionScript body string no Required when executeCondition is VariableCheck: the name of the boolean variable that must resolve to true. Despite the name, it is a variable name and not a script.
parallelMachines body integer no Max machines to run on in parallel.
parallelCloudTargets body integer no Max cloud targets to run on in parallel.
workerTagId body string no Tag identifying the worker pool.
environments body array<string> no Environment IDs the step is restricted to.
machineIdFilter body array<string> no Restrict to these machine IDs.
machineTagFilter body array<object> no Tag-set filter for machines.
cloudTargetTagFilter body array<object> no Tag-set filter for cloud targets.
propertiesJson body string no JSON-encoded step property values.
onStepFailure body string no What a failed step does to the rest of the deployment. ContinueToNextStep (default) or StopDeployment. See below.
runAfterStop body boolean no Run this step even when an earlier step stopped the deployment. Defaults to false. See below.
machineOrder body string no The order the step works through an environment's machines. MachineName (default) or TagPriority. Parsed case-insensitively. See below.
machineOrderTagIds body array<string> no Tag IDs in priority order, highest first, used when machineOrder is TagPriority. Only stored while the order uses it - saving with MachineName order drops the list. See below.
onMachineFailure body string no What one machine failing does to the rest of the step. ContinueToOtherMachines (default) or StopStep. Neither ends the deployment - that is onStepFailure. See below.
waitBetweenMachineGroups body boolean no Finish every machine of one tag rank before the next rank starts. Defaults to false. See below.

Run mode

runOn accepts TargetMachine, Worker, or WorkerToCloudTargets. The value must also be included in the selected step template's supportedRunModes; otherwise the request returns 400.

Error action

errorAction accepts Stop or Continue. It chooses the level a script failure is logged at, and nothing else - neither value stops the deployment.

  • Stop - a failing script is logged at Error, so it counts towards the deployment ErrorCount.
  • Continue - a failing script is logged at Warning, so it counts towards WarningCount instead.

A failing script does not fail its step and does not fail the deployment either way. What counts as a failing script depends on the script language: PowerShell 7 (powershell) does not fail on exit codes, so exit 3 only logs a warning, while PowerShell 5.1 (powershell5) and Python treat a non-zero process exit code as a failure. See Get deployment status for the details, and for how to tell a clean run from a merely finished one.

Execute condition

executeCondition accepts Always, AllPreviousStepsSucceeded, or VariableCheck. It is the only setting that can hold a step back because of what happened earlier in the deployment.

  • Always - the step runs whatever came before it.
  • AllPreviousStepsSucceeded - the step is skipped when the error counts recorded against the preceding steps add up to more than zero. Only steps whose errorAction is Stop can contribute to that sum, and the first step in a project has nothing before it, so the condition never holds it back.
  • VariableCheck - the step runs only on the targets where the boolean variable named in executeConditionScript resolves to true.

A step held back by its condition is recorded as skipped, not failed, and adds nothing to ErrorCount.

Stopping the deployment

onStepFailure accepts ContinueToNextStep or StopDeployment and defaults to ContinueToNextStep. This is the setting that can end a run. errorAction, above, is not.

  • ContinueToNextStep - the historical behaviour. The deployment can no longer report success, but every later step is still offered, and only its own executeCondition holds it back.
  • StopDeployment - no later step runs, apart from any step whose runAfterStop is true. Those still run, so a process that has to announce its own failure has somewhere to do it from. The rest are recorded as skipped, with the reason logged against them.

A step counts as failed here when its status is Failed or TimedOut, or when it recorded any errors at all. That is where errorAction comes back in. A failing script is counted as an error only when the step's errorAction is Stop, so a step left on Continue will not stop the deployment when its script fails, whatever onStepFailure says. Set the two together.

Values are parsed case-insensitively and returned in canonical casing. An unrecognised onStepFailure returns 400 with invalid step failure policy. Both fields are returned by List project steps, and both are copied into a release when it is created, so a change here applies to releases cut afterwards rather than to ones that already exist.

Step templates and pinned versions

A step runs the version of its step template that it is pinned to, not whatever the template says today. A step added to a project is pinned to the template as it stands at that moment, and it stays there until something moves it.

stepTemplateId is what moves it. Sending it points the step at that template and pulls the template in: the step's script is replaced with the template's, the property schema is reshaped to the template's, and the pinned version becomes the template's current one. Send the id of the template the step already uses to move the step onto a newer version of it. This is the API equivalent of the Pull template changes button in the editor, and it is the supported way to do it - deleting the step and adding it again is not necessary.

Property values are kept wherever the property is still in the new schema and still the same kind of control. A value whose property has gone from the template goes with it. propertiesJson sent in the same request is applied before the pull, so the values you send are merged the same way.

Nothing moves unless there is something to move. If stepTemplateId names the template the step already uses and the step is already on its current version, the step is left exactly as it is. Leave stepTemplateId out and the template side of the step is never touched, whatever else the request changes - a rename cannot put a step onto a new script.

The pinned version is not part of any response, so there is no way to ask which steps are behind their template. Sending stepTemplateId on a step that is already current does nothing, so the practical answer is to send it.

Watch runOn when moving a step to a different template. If the step's run mode is not in the new template's supportedRunModes, passing it explicitly returns 400, and leaving it out moves the step to the first run mode the template does support.

Rolling a step across its machines

These four fields shape how a standalone step works through the machines of an environment.

A step that is a member of a rolling group does not use them. The group carries its own copy of the same settings and that is what the deployment runs, so setting them on a grouped step is not an error - it simply has no effect unless the step leaves the group. Note the defaults differ: a standalone step defaults onMachineFailure to ContinueToOtherMachines, a group defaults it to StopStep.

machineOrder decides the sequence:

  • MachineName - alphabetical, case-insensitive. The default.
  • TagPriority - a machine's rank is the index of the first tag it carries from machineOrderTagIds. A machine matching none of them sorts last rather than being left out. Excluding machines is what machineIdFilter and machineTagFilter are for.

machineOrderTagIds is kept only while the order actually uses it. Saving a step whose machineOrder is MachineName drops the tag list instead of storing it, so a later switch back to TagPriority starts from an empty list. That is deliberate - a stale list left lying around would silently resurrect an order you thought you had removed.

waitBetweenMachineGroups is the barrier. With TagPriority, every machine of one rank finishes before the next rank starts, which is what makes a canary rollout a rollout rather than a fast parallel run.

onMachineFailure decides whether the next machine starts after the step has failed on one. ContinueToOtherMachines is the default and the historical behaviour. StopStep starts no further machine. Neither ends the deployment, so set it together with onStepFailure - a step that stops on the first bad machine while onStepFailure is left at ContinueToNextStep still lets every later step run.

isRolling is read-only

isRolling is not a field of this request - sending it does nothing. It is reported by List project steps and Get a release as a summary of the two settings above: it reads true when machineOrder is not MachineName, or when waitBetweenMachineGroups is on.

Configure the order and the barrier, and read isRolling back to see what they add up to. Nothing in the deployment runner reads the stored flag.

Errors

StatusMeaning
400 Invalid projectStepId or validation failure.
401 Missing or invalid Basic auth credentials, or the service account lacks the required role.
400 machineOrder is not MachineName or TagPriority - the response reads invalid machine order.
400 onMachineFailure is not ContinueToOtherMachines or StopStep - the response reads invalid machine failure policy.