2011-09-25

The daily team development checklist

Have you ever seen software development team members around five in the afternoon commit their changes for the day into the source code management system and go home, happily whistling, just before the Continuous Integration build finishes with errors that they introduced? And you had to stay and correct their errors before you could commit your own changes and go home yourself? I have seen this more than once and have devised a checklist to help avoid it.

The checklist is based on the premise that the code base on the main line of development should always be stable, compiling and working correctly, as demonstrated by a set of automated tests that succeed one hundred percent. Most of the items in the list may seem self-evident, but every single one of them I have seen violated again and again. Not following the list mostly has the effect of leaving the more tedious and unpleasant parts of the work of developing software as a team to others.
  1. Checkout the newest version of the code base from the source code repository.
    It is useless to build on stale code. Sooner or later your work will have to be integrated with the work of your team members, and the longer you wait, the more difficult it is.
  2. Build the code and run all automated tests.
    This step is to make sure that you start with clean code and that all errors that you will encounter later on are the results of your own changes. If you know the cause of errors, they are much easier to find. Use the same automated build procedure that the Continuous Integration build uses. That is the one that is controlled by version management and is the same for every developer. Usually this will be a set of ant or maven (or make) scripts. Especially do not rely on Eclipse building your code, because the result will be dependent on which (versions of) plugins you have installed and other team members do not, and on your settings and preferences.

    If the build fails before you have changed anything, try to find out who introduced the errors, almost always the last one to commit code, and ask him to correct them. If that person is unavailable (see the first paragraph of this post), there is nothing left but to try to correct the errors yourself, while trying to suppress your anger.
  3. Edit/compile/test to implement your features.
    This is what is traditionally is seen as the main part of your work, which of course it is. Do not make too many changes at once, but try to break them up into working sub-features. The more changes you commit at once, the more difficult it is for your teammates to integrate them with theirs. And don't forget to write automated tests. You will see in the next step why this is in your own best interest, in addition to being necessary to maintain a high level of software quality.
  4. Build the code and run all automated tests.
    This step is the same as step 2, but this time it is executed to make sure that (1) you do not introduce faulty code, and (2) your changes do not break existing features. Features that have no automated tests run a risk of being accidentally broken or removed. I have seen developers who refused to write automated tests, because they found that 'too much work'. When they protested that their features were broken or disappeared in later versions, the legitimate reply was: 'if you had written tests, we would have known when we broke your features and kept them intact, so don't whine'.
  5. Get hold of the semaphore.
    Find the object that is used as a semaphore and put it on your desk next to your keyboard.
    This step is explained later when we come to the last step.
  6. Pull new changes from the source code repository.
    Quite probably your teammates have been committing changes while your were busy developing your features, and you are the one responsible for integrating them with yours. Most source code management systems can automatically merge the new changes with yours and that is a useful feature. Sometimes this results in conflicts where you changed the same lines in the same file as others. Of course you have to resolve these, but the logical conflicts are usually more subtle. The version management system cannot detect those, but hopefully they are brought to light by failing automated tests. Therefore:
  7. Build the code and run all automated tests.Again the same as step 1, but now with the purpose of making sure that your changes work well with those of other developers. Resolving logical conflicts may involve talking to other developers or the Product Owner (if you use Scrum) or analyst to find out what is the intended behavior. This is why many developers do not like this step. Apart from having to actually talk to people, it means you have to leave your own private train of thought and try to understand others. And worse, try to understand other developers code!
  8. Commit your changes.
    Now, if all tests succeed, you may finally commit your changes, of course with associated remarks explaining the purpose of your changes. And with the id's referring to the issues in your issue tracking system that you addressed with your changes, if that is the policy in your team. Especially do not forget to add new files that you created. When this checklist is followed and when a Continuous Integration build is in place, forgetting to add new files to the source code repository remains the most common cause of failed builds.
  9. Release the semaphore.Put the object used as a semaphore back to its neutral territory.

    When using this checklist, it is possible that several developers keep themselves busy in an endless cycle of commits. The scenario that could lead to this is as follows: developer number one executes step 6 of this checklist and starts integrating the changes with his own. But before he is ready for step 8, developer number two has committed his changes first. When those changes occur in the same files that developer number one has changes, most source code management systems will warn him and refuse to commit the changes. Another more dangerous possibility is that the other changes are in different files, in which case the source code management system is not aware of the possible logical conflict. In this case, the result of the commit may be a broken build, exactly the thing that we are trying to avoid all the time. Of course you can pull any new changes again, but if you have bad luck, and the other developers are very productive, you could be busy like this forever.

    This scenario can be avoided by introducing a semaphore, for example a physical object that can be put on your desk next to your computer. The associated rule is that only one developer at a time, the one that has the semaphore on his desk, is allowed to commit code. The other ones have to wait until the semaphore is released.

    In the past I have used objects that make sounds, like a horn with a rubber ball or a hotel bell. In that case an extra sub step is introduced just before step 9: Sound the semaphore, to celebrate the progress. And of course to notify other developers that the semaphore is free again.
This checklist has a natural tendency to promote regular commits. Each developer is responsible for integrating his changes with the changes that everybody else has been making since his last update. Nobody likes this chore, because it interferes with building new functionality. If you commit early, your own changes are less, and the other's changes are less too, so this work is easier.

It also has a tendency to promote quality, because it makes it transparent who causes the build to fail. Social pressure does the rest.