Understanding states in Release Management

Trying to code against release management APIs? This post will try to demystify the various states that are present in the release object and explain what each of them signify.

First, we need to understand the structure of the release object. The release object is a wrapper to a bunch of artifacts and environments. Each environment is what actually gets deployed - and the artifact gives away the details of what got deployed (the bits). The properties that we are mainly concerned with are shown here with the hierarchy -

Release
- Environments (List of ReleaseEnvironment)
          <ReleaseEnvironment>
               - DeploySteps (List of DeploymentAttempt)
                    <DeploymentAttempt>
                         - ReleaseDeployPhases
                              - ManualInterventions (if any)
                    </DeploymentAttempt>
               - PreDeploy Approvals
               - PostDeploy Approvals
          </ReleaseEnvironment>

A release contains a list of release environments. Each release environment has some static information around what is to be run- the list of tasks and settings. The environment in turn has a list of deploy steps, one per deployment attempt. A deployment attempt is the run time entity which will contain the results of execution of each task. Lets look at the states of each of these layers and figure out what each of them means.

Release(release.status)

  • Draft - The release was created as a draft and no deployment has started yet. You can edit the release object just like you would edit the release definition and then start the release. Any edits made to the release will not impact the release definition.
  • Active - Once a release has been started it enters the active state. Either deployments are going on the environments or they are waiting to start through an external trigger like a manual deploy action or completion of the previous environment. A release needs to be in active state for users to perform actions on it. An active release has an aritfact linked to it which cannot be modified.
  • Abandoned - This is the terminal state of the release. No more actions are allowed on abandoned releases.

Release Environment (environment.status)

  • NotStarted - No deployment has been queued on this environment. Some external signal needs to come in to start the deployment, be it a manual trigger or the completion of some previous environment.
  • InProgress - The environment has moved out of the pipeline queue. The execution has begun. Do note: the enviroment is in either of the 3 states - pre deployment approval, deploying, post deployment approval.
  • Succeeded - All good!
  • Canceled - The deployment on the environment has been canceled by some user.
  • Rejected - An apporoval was rejected.
  • Queued - If the queuing policy on the environment is configured in a way that deployment has to wait, the environment state would be marked as queued.
  • Scheduled - A deployment is scheduled for some later time. (environment.nextScheduledTime will tell you when)

ReleaseEnvironment gives you some information as to where exactly is the deployment as of now. These states are too broad and you would still need to parse the object if you need meaningful info like - "environment is in progress, but is it safe to cancel the deployment now or are the tasks executing already?". To answer questions like these you need to look at the deploymentAttempt object. The deployment attempt object list contains all the run time information about the attempts that were made to deploy to an environment within a release. Every time you click on the deploy/redeploy button the environment a new deploymentAttempt is created.

DeploymentAttempt (status, operationStatus)

This object has a status and an operationStatus. The status will be like the environment status (broad classification) and the operationStatus will tell you why the deployment is in that state. This is to be read in <status, operationStatus> pairs -

  • <NotDeployed, Queued> - Queued because of the queueing policy (eg. For "one deployment should be active at a time" policy, the newer deployments will be in this state)
  • <NotDeployed, Scheduled> - Environment is scheduled for deployment at a later time.
  • <NotDeployed, Pending> - Pre deployment approval is pending. environment.predeployApprovals will tell you who is blocking it.
  • <NotDeployed, Approved> - Pre deployment approval just got approved. The deployment should not be stuck here for long and will move forward automatically.
  • <NotDeployed, Rejected> - This is when the pre depoyment approval got rejected by the user. Again, environment.predeployApprovals will tell you who rejected it.
  • <NotDeployed, Deferred> - The approver did approve the deployment but deferred it to a later time.
  • <NotDeployed, QueuedForAgent> - The deployment is ready to run but there is no free agent and it is stuck in the agent queue.
  • <NotDeployed, QueuedForPipeline> - Oops, you ran out of licenses. The deployment will proceed when a pipeline gets freed up.
  • <NotDeployed, Canceled> - The deployment got canceled before the task execution ran. deployStep.LastModifiedBy will tell you who canceled the deployment.

Do note, the deployment status is marked as InProgress only when the agent picks up task execution. The environment.state on the other hand is marked as inprogress as soon as the pre-approval is created.

  • <InProgress, PhaseInProgress> - The deployment got picked up by the agent. Task execution has started.
  • <InProgress, ManualInterventionPending> - You had a manual intervention task and the deployment now tells you that. deployStep.releaseDeployPhases[x].ManualInterventions collection will have more details on the manual intervention.
  • <InProgress, PhaseSucceeded> - The deploy phase passed. The next deploy phase would begin execution or a post deployment approval will be created.
  • <InProgress, Pending> - All deploy phases have completed execution. The deployment is waiting on a post-deployment approval.
  • <InProgress, QueuedForAgent/QueuedForPipeline> - The difference between this and <NotDeployed, Queued...> is that this will be the state for all phases after the first one has finished execution.
  • <Succeeded, Approved> - Yay! All good, tasks passed and approvers approved the release.
  • <PartiallySucceeded, PhasePartiallySucceeded> - A task that was marked as ContinueOnError failed. The subsequent tasks executed successfully.
  • <Failed, PhaseFailed> - Task failed, or the manual intervention got rejected.
  • <Failed, Canceled> - Someone canceled the deployment after the task execution started and before the deployment could go green. If tasks were executing when this happened environment.PostDeployApprovals should be empty, and if the deployment got canceled when it was pending an approval the collection would have an entry. deployStep.LastModifiedBy will give away details on who canceled the deployment.
  • <Failed, Rejected> - A post deploy approval got rejected.

[Update]

There were a few more states introduced in RM so i'm updating the blog to reflect those as well.

  • <InProgress, Cancelling> - This is the intermediate state between <inProgress, PhaseInProgress> and <Failed, Cancelled> and happens when a user issues the cancel signal when tasks are executing. The deployment is most likely completing some pending operations before the terminal failed state can be reached. (eg. finish tasks marked as alwaysRun)

States related to RM gates functionality

  • <NotStarted, EvaluatingGates>  - Pre deployment gates being evaluated.
  • <NotStarted, GatesFailed>  - Pre-deployment gates evaluation failed. Whether this is a terminal state or not depends on the gates options (ask for approval always setting will move the release forward)
  • <InProgress, EvaluatingGates>  - Post-deployment gates being evaluated.
  • <InProgress, GatesFailed> OR <Failed, GatesFailed> - Post-deployment gates evaluation failed. Whether this is a terminal state or not (InProgress or Failed status) depends on the gates options (ask for approval always setting will move the release forward).