How to Add an Automated Cycle Time to Azure Devops Boards

Simon Wraight
Version 1
Published in
10 min readSep 15, 2022

An alternative to Story Points and Velocity, and one that I am a strong advocate for is measuring flow with Cycle Time and Throughput. Azure Devops has a nice dashboard widget, shown below, that displays these but only after the work has been completed.

Kanban, Scrum, and even more traditional delivery teams can get value from seeing the Cycle Time on their work item ticket as it is in progress. We use the Cycle Time in our daily calls to quickly see and discuss which work items are moving slower than expected. Currently, you cannot calculate Cycle Time from Azure Devops alone, but you can integrate with power Automate, which is often bundled in with your Office 365 subscription.

In this article I’m going to show the steps I took to get Cycle Time automatically added and updated each day, I estimate it will take an hour to complete these steps, after you have set up your access.

Firstly, you will need:

  • Administrator access in Azure Devops for modifying the process templates
  • A Power Automate subscription for designing the flows(mine is included with the Office 365 licence)

I will assume that you understand Azure Devops process templates. I’ll also assume you are using the same field names and values as me, but you can adapt these for your needs.

Add your new fields in Azure Devops

You will need two fields, Cycle Time and Start Date. Our Start Date field will be populated when a work item is moved into our first work column. For me that is “In Development”.

Go to Organization Settings and then Process which is under Boards on the left-hand menu. As mentioned above, editing process templates can only be done by Administrators.

Select the Process Template that you are going to edit. Then navigate to the work item type that you will be adding Cycle Time to. I am using “Task”.

Cycle Time

Select [New field]

Create a field and name it, I use “Cycle Time”.

Select “Integer” for the type.

Start Date

Select [New field]

Create a field and name it, I use “Start Date”.

Select “Date/Time” for the type.

When finished you should end up with something like below. I created a new group to add my flow fields into.

Azure Devops Process Template

Create you Power Automate flows

First thing here is to set up your Power Automate account at https://powerautomate.microsoft.com/ you will need a premium license for these flows, mine is included with my Office 365 subscription.

Next, create a connection to Azure Devops. Do this via [Data] — [Connections] on the left menu.

Select [New Connection] and enter “azure devops” into the search to filter the connections.

Setting your connection

Add the connection and fill out the required values.

When you are ready you can click on [Create] on the left menu or [New Flow] from your “My flows” page.

You will need two flows:

  • one triggered by an Azure DevOps Work Item update
  • one scheduled to run at your chosen frequency.

Work Started Flow

Create a new flow and choose “Automated cloud flow”

Type “azure” into the search box and select “When a work item is updated”

Choosing the trigger

After creating you can add values to the “When a work item is updated box”

When a work item is updated

We are adding the Cycle Time to our tasks in this example, choose the type you are adding the Cycle Time for.

With that done, click on [New step] and type “condition” into the filter. Select condition from the results and your flow should look like this:

Using condition logic

Now we add in the condition that we want Power Automate to look out for. That is a work item with no Start Date and the State that you want to measure the Cycle Time from. For us, it is “In Development”

To select your fields, click into the “Choose a value” box. You will get a list of available fields from your work item. Use the search filter to help you find your field. Then select Start Date.

Setting the conditon field

Now you need to “Choose a value” for Start Date. Select the field and when the dialog opens, select the Expression tab, type in “null” and click ok.

Setting the condition value

In the Condition box, add a group and add each active state. Then enter in the state you are looking for.

Note: Since creating this flow, I observed some tasks being moved straight to a review state, so I’ve included all active states in my logic.

Your condition box should now look like this:

Condition box

We check the Start Date is null so that we only set it once. Without this, each time a user moves their work item between an active state, we would reset the date and reset the Cycle Time.

Ok, now we have our logic we need to update the work item in the Yes condition. Click on [Add an action] in the Yes box. Type “azure devops” into the search filter and click on [Update a work item]

Setting Yes condition operation

Now, in the “Update a work item” box, add in your organization name again. Also, add your Project name. For work item id, click in the field and select [Id] from the dynamic content. This Id has been passed from the previous step “When a work item is updated”.

Select the work item type you are using, “Task” in this example.

Then select [advanced options]. In “Other fields”, click into “Enter key” and type “Start Date” as the key. In the “Enter value” box, search for “Changed Date”, using the dialog box.

Your Yes box should now look like this:

Updating the work item

That is the first flow complete. Now click save and we can test that it works.

Before we can test, we check that the flow is switched on. Go to “My Flows” and see if the flow displays the disabled icon on it. To switch it on, click on the 3 dots and select “Turn On”

Disabled flow

The flow is now up and working and should work correctly. But you can test it faster by setting the flow in test mode. To test, edit the flow again and then click on [Test] in the top right of the screen. Select manual test and then click the [Test] button.

Now navigate to Azure DevOps and move a work item into the “In Development” state. This should trigger the flow faster and you can validate that Start Date has been populated.

With the Work Started flow now running, we can create the Cycle Time flow.

Cycle Time Flow

For this flow, we need to define a query in Azure DevOps. In my example, I need all active tasks in the states of In Development, In Review or Ready for Review. Add a check that Start Date is not blank. Our flow cannot calculate CycleTime without a Start Date and will error if it is blank. I’ll assume you understand queries, but the screenshot below shows this query. Make sure it is saved as a Shared Query and add Cycle Time and Work Started columns to the results via column options.

Azure Devops query

Now we have the query in Azure Devops, we go back to Power Automate.

You will need to create a “Scheduled cloud flow”. Name it and choose when it will run. I chose Week, selected Monday — Friday and for time I set 8am.

Creating a scheduled flow

With the flow created, click on [New step]. Search for Azure Devops and select “Get Query Results”

Get Azure Devops query results

Hopefully that is an easy step and will give you this:

Get query results parameters

Next, we initialise a new variable and call it WorkDays. This will be used to hold the number of workdays after we deduct weekends.

Add a step. Type “variable” into the search and select “Initialize Variable”. Name it “WorkDays”, select Integer as type and give it a value of 0. As shown below:

Initialize variable

Add a new step and search for “apply to each”. Select “Apply to each” and add the dynamic content of “Value” into the box.

Apply to each

This will iterate through the results of your query, applying the following actions to each result.

Add another action in the box and search again for azure devops. Select “get work item details”, add in your values as before and add the dynamic value of “ID” for Work Item Id.

Get work item details

The next step to add is “Compose”, your apply to each step should now look like below.

Compose the Cycle Time

Click on “Add dynamic content” and copy in the following formula:

div(sub(ticks(formatDateTime(utcNow(),’yyyy-MM-dd’)),ticks(formatDateTime(outputs(‘Get_work_item_details’)?[‘body/fields/Microsoft_VSTS_Scheduling_StartDate’],’yyyy-MM-dd’))),864000000000)

This formula converts the dates into ticks. There are 864000000000 ticks in 1 day. We then use sub to subtract the StartDate from utcNow(the current date), finally, we divide it into the ticks for 1 day which gives us the difference in days.

The next few steps we will put into a scope, for no other reason than to allow us to collapse/expand this section when working on the flow. Add a step and search for “scope”.

Inside the Scope add a new step — “Set variable”. Then add the dynamic content “Outputs” from CycleTime.

Dynamic outputs

Your Apply to each box will now look like this:

Apply to each logic

Now, inside Scope, add a “Decrement variable” step. Name is “WorkDays” and add the following formula as an Expression:

mul(div(sub(outputs(‘CycleTime’),1), 7), 2)

Decrement variable

Inside Scope, add another “Decrement variable” step. This step will deduct two days for a weekend if the start day is later in the week than the end day. For example Thursday — Monday would include a weekend. This will need the formula:

if(less(sub(dayofweek(formatDateTime(utcNow(),’yyyy-MM-dd’)),dayofweek(formatDateTime(outputs(‘Get_work_item_details’)?[‘body/fields/Microsoft_VSTS_Scheduling_StartDate’],’yyyy-MM-dd’))),0),2,0)

Your scope will now look like this:

Second Decrement variable

Note: I renamed some of the steps above to make it clearer what the flow is doing.

After the Scope, add a new step for Azure Devops. “Update work item”. Add the connection info as before and add CycleTime as your key and the dynamic value “WorkDays” as the value. Your last step should look like below:

Save your flow. Then go and enable the flow, using the steps described when creating the Work Started Flow.

You can now run a test flow, do this by putting the flow into edit and clicking [Test] in the top right of the screen. Select manually, then click “Run flow” to start. You can then navigate to the test page to see if the flow completes.

If you have no errors in the flow, you will now have Cycle Time populated on your work items. You can edit the appearance of the tickets on your Devops board to show Cycle Time, as we do.

Cycle Time displaying on tickets

Cycle Time helps the team to quickly see the slow-moving work items on the daily call. If you are working in Kanban, you might also want to measure how many days an item has been in a specific column. By adapting the steps above, you could easily add days since a ticket moved columns/ states. That really helps to identify bottlenecks in your way of working.

Thanks for reading! Please share any feedback you have.

About the author:
Simon Wraight is a scrum master at Version 1.

--

--