An agreed and fixed definition of “Done” (DoD) for an iteration is a powerful thing. It sets a quality bar that applies to all the team and all the work, avoiding wasteful discussions. At the retrospective the definition can be reviewed and the bar raised to push the quality up a notch, or if the team is failing to meet the definition actions can be agreed to remedy the situation.
To be effective, the team needs to find a way to verify each piece of work against the DoD. To keep the process lean, it helps to build verification into the process in as simple a way as possible. There are different ways of setting this up in TFS, for example work items could be customised to include fields for each part of the DoD, and those fields could become mandatory when setting the status to Closed. However, this approach requires the team member who closes a work item to vouch for all the work that went into it – work that may have been done by several people over days or weeks.
Instead of using work items directly, I believe the best way to track the DoD is at two “gates”: check-in and build. Check-ins should be small and frequent, and with continuous integration builds run on every check-in, so this gets the tracking of “done” as close as possible to the execution of individual pieces of work (i.e. tasks). This way, check-in policies and the build provide automatic checking, while check-in notes can be used to verify elements of the DoD which cannot be automated. Here’s an example DoD and how it can be tracked using those mechanisms:
Example Definition of “Done”
- Code builds
- Code has been reviewed
- Code is covered by unit tests
- Code changes can be traced to requirements
- Unit tests pass
Check-in Policies
These are a great tool to maintain check-in standards. As previously posted, check-in policies can be overridden but it’s easy to set up an alert to detect that. The TFS Power Tools are a must-have here as they provide a number of check-in policies including the crucial Custom Path Policy – which scopes other policies to specific folders. I find the following policies very useful:
- Changeset Comments Policy: requires a comment for every check-in. These should be used to provide a high-level summary of what has changed rather than why (why is captured better with a work item link).
- Work Items: requires a work item to be selected on check-in. This enables traceability to requirements. The policy can be scoped to a specific set of work items using the Work Item Query Policy but I have found this to be over-engineering.
- Forbidden Patterns Policy: prohibits certain files being checked-in. Best used with the Custom Path Policy and a consistent source structure so the prohibition can be scoped to certain folders. For example, you may prohibit compiled DLLs being checked into source code folders.
Other policies such as Builds, Code Analysis and Testing Policy are in my opinion too restrictive or awkward to use, or are intended to meet requirements that are better met by automated builds.
Check-in Notes
These are simple text fields that can be customised, and made mandatory, for each team project. For example, a code (or peer) review can be verified by making the Code Reviewer field mandatory. This applies to all files in source control, so the team would need to decide if it’s OK to enter “n/a” for non-code check-ins or if all check-ins should be reviewed (including dependencies, documentation etc.) Shelvesets can be used to defer check-in and allow a team member to pick up a potential changeset for review.
Build
The TFS build system offers the greatest potential for customisation. Out of the box it will verify that code builds, and (if you use MSTest for unit tests) run the tests and calculate code coverage. There is an option in the default template to fail the build if any tests fail, but to take it further you need to customise the work flow. This could be used to fail the build if code coverage has dropped since the previous build, or bring virtually any other metric into the mix – enabling you to extend the build process as needed to match an extended DoD.
A really powerful option related to Build is Gated Check-in. This reverses the normal sequence so that build happens before check-in and if the build fails the check-in is rejected. This ensures that not only is the DoD tracked, but that code that does not meet it can never reach the code base and impede other work.

