Share →
Buffer

One of our awesome clients came up with a clever solution to the problem of queries for the “current” iteration in TFS. When we saw it, we couldn’t wait to share it with all of you, and who better to explain it than the person who devised it? Andrew, take it away!

Since upgrading from TFS 2010 to 2013, one of my favorite additions has been the date attributes on iterations. Now our reports can use these dates instead of parsing titles and within Team Web Access these date ranges are used to make iteration planning and reporting more powerful. However, there remains a lingering issue. Without a WIQL variable such as @currentIteration, everyone needs to modify all of their queries every iteration if we want to have any individual or shared queries looking at the current iteration.

Or do we?

If you look at the iteration nodes along the left pane of Team Web Access’s backlog page, you’ll note that iterations are grouped according to whether they occurred in the Past, will occur in the Future, or are the Current iteration. But these groups exist only on the screen, not saved with the work item, so they can’t be queried.

Group iterations together with custom nodes

That being the case, what if we also organize our iterations with Past, Future, and Current nodes? The backlog page structure is created regardless of how deeply nested our iterations path actually is, so an extra level won’t change that behavior. And with Past, Future, and Current reflected in the iteration path itself, those designations become queryable.

“But now I’ll need to come in here and shuffle these nodes every iteration in order to maintain this pattern!”

Fair enough, but trust me, it’s overwhelmed by the value you’ll get for the modest investment of time.

Create queries that update themselves when you update the iteration

“Value? It would make my iteration paths match the backlog page, but I don’t see what it’s going to help me accomplish.”

With this pattern, you can create work item queries using the “Under” keyword to return all children of the iteration path [team project][other nodes]Current. This way, as each iteration ends and the next begins, you need only move one iteration node to be a child of the Current iteration node and move the iteration that just ended to be a child of the Past iteration node.

No matter how many “current iteration” queries you have, you only need to edit iteration path once for all of them to continue to deliver accurate results! A bit of a nuisance, yes, but far less costly than manually editing every current iteration-based query to point to the new current iteration.

Take a look below to see what this looks like on the iteration admin page:

During Iteration 8 During Iteration 9
Current-Iteration-Admin-Before Current-Iteration-Admin-After

It’s safe for the work items themselves

“That’s all fine and good, but won’t it make a mess of all my work items’ iteration paths?”

I’m glad you asked! A subtle bit about how work items link to iteration paths, is that they point to the iteration node and not the full path. As the iteration node gets moved around all work item’s immediately reflect the iteration path’s new location.  In case you don’t believe me, take a look at the pictures below:

During Iteration 8 During Iteration 9
Current-Iteration-Current Current-Iteration-Past

It’s safe for the warehouse

“Sure, that’s hunky dory for the current state, but we rely on the history for all of our reporting from the warehouse. Won’t changing the iteration configuration so often make a mess of all that history?”

Have no fear! The history of the iteration tree is not fully tracked in the warehouse. Thus, the current placement of an iteration node looks as though it has always been there. As a result, any historical reporting will simply make it look as though all of our previously completed work items have always been under the Past iteration node.

Here’s what the warehouse returns for the history of an individual work item. Notice that the revision and ID values have not changed. The iteration path just reflects the new location and name as if it had always been that way:

During Iteration 8 During Iteration 9
System_Rev System_Id IterationPath
1 530 IT\ALM\Current\8 – Go or No Go
System_Rev System_Id IterationPath
1 530 IT\ALM\Past\8 – Go or No Go

And here’s what the warehouse history looks like for the iteration setup itself:

During Iteration 8 During Iteration 9
StartDate FinishDate IterationPath
IT\ALM\Current
Mar 24, 2014 Mar 30, 2014 IT\ALM\Current\8 – Go or No Go
IT\ALM\Future
Mar 31, 2014 Apr 6, 2014 IT\ALM\Future\9
Apr 7, 2014 Apr 20, 2014 IT\ALM\Future\10
IT\ALM\Past
Feb 24, 2014 Mar 9, 2014 IT\ALM\Past\6 – Startup
Mar 10, 2014 Mar 23, 2014 IT\ALM\Past\7 – Ramp-up
StartDate FinishDate IterationPath
IT\ALM\Current
Mar 31, 2014 Apr 6, 2014 IT\ALM\Current\9 – Go
IT\ALM\Future
Apr 7, 2014 Apr 20, 2014 IT\ALM\Future\10
IT\ALM\Past
Feb 24, 2014 Mar 9, 2014 IT\ALM\Past\6 – Startup
Mar 10, 2014 Mar 23, 2014 IT\ALM\Past\7 – Ramp-up
Mar 24, 2014 Mar 30, 2014 IT\ALM\Past\8 – Go or No Go

It’s safe over multiple revisions

“OK, that looks good for the latest version, but what about work items with multiple revisions?”

Moving the iteration node does indeed impact all revisions of the work item, not just the latest.  In the screenshots below you’ll see the same work item after a few changes were made.  These revisions included changing the iteration path so that the history of the work item included at least two different iteration paths.  After this was done I moved the iteration 8 node from under the Past to under Prehistoric node. As you can see, all revisions of the work item reflect the new placement of the iteration 8 node.

Iteration 8 Under “Past” Iteration 8 Under “Prehistoric”
Multi-Revision-Pre Multi-Revision-Post

Give it a try and see what you think

“Wow, that’s awesome and I’m definitely going to do this!”

That’s great! Now you and your teammates can create persistent queries that will always look at the current iteration, and keep them up-to-date with much less effort than editing every query every time.

One last safety check: you may also want to also create a query to identify work items that accidentally get assigned directly to any of the Current, Future, or Past nodes, so you can reassign them to a real iteration path, so they don’t get lost.

Print Friendly
  • Chris Binkerd

    I’ve been managing TFS queries this way for a few years now and can vouch for its ability to greatly reduce the overhead of managing queries each cycle. I’ve used similar terms “Current Development”,”Future Development”, “Released” and have added one called “Backlog”. This extra category helped to distinguish work pre-scheduled for future iterations from the un-scheduled backlog. For us this has been helpful as it provides a buffer for incoming requests throughout the cycle and provides an area for triaging requests etc. I do have an “Invalid iteration Paths” query to catch when folks forget to set to a real iteration as well. I’m excited to see how others may have extended and improved this approach Thank you for sharing this!