Left on the Web

Agile PHP: How do we do it?

Since a few weeks we've really truely implemented some agile methods in our biggest project (Jongeren in Beeld). Since others may benefit from knowing how we have approached this, I want to share our implementation of the agile approach of software development in a PHP project with the world.

Since a few weeks we've really truely implemented some agile methods in our biggest project (Jongeren in Beeld). Since others may benefit from knowing how we have approached this, I want to share our implementation of the agile approach of software development in a PHP project with the world.

First of all, I actually wrote a document to outline these guidelines, as in our company (and I guess a lot of other companies) as long as it's not documented, it won't be followed. So I guess you could call that tip #1 ;)

Iterations

An iteration is a certain set period of time during which the developers work on implementation a set of features and/or fixing bugs. An iteration always results in a release. The definition of "release" here is a stable enough codebase in the development branch to deploy safely on the testserver. More on this later. The length of iterations for us is three weeks, where one week overlaps. So the last week of iteration 1 is the first week of iteration 2. During the first two weeks of an iteration, the developers work on implementing the features. The third week is for testers to test the release, and (when the choice is made to do this) deploy the release to the production environment. So basically, the developers are always busy with implementing new features, but once the testers are working on testing the application, they may need to fix minor bugs so as to get a truely stable version that can be deployed to the production environment.

Meetings

There are two very important meetings during an iteration, and aside from that every morning has a short morning stand-up meeting. Let's first have a look at the important meetings:

  • On the first monday of an iteration at 9:30, all stakeholders gather for the planning meeting. During this meeting, all stakeholders gather around a PC on which our Trac installation is open, and discuss which features should be planned for the upcoming iteration. The list of planned features should be a little too long to be realistic. Since the rule is to always be able to deliver a stable version, it is not bad if some features won't actually be done this iteration. It's better to have too much planned than too little planned, or the developers might be sitting around doing nothing ;)
  • On the second thursday afternoon, at 15:00, the closing progress meeting is being held. During this meeting, all stakeholders should gather to have a look at what progress is actually made during the past two weeks. Also, based on the list of implemented features, the testers may now be able to write their test plans. Based on the list of implemented features, during this meeting already the decision may be made that this release should end up on production.  

The short morning stand-up meetings are just that: A max of 15 minutes is set for this meeting, and during this meeting, everybody will tell what has been done since the last stand-up meeting, what is planned until the next stand-up meeting, and if there are any issues that might block the developer from making that planning. This meeting is held while standing, so as not to get comfortable and have endless meetings talking on things that are not relevant. Save that for the coffee machine ;)

Whiteboards, sticky notes and Trac

The list of tickets to work on is being tracked in several ways. In our room, we have a whiteboard that is divided into sections very similar to the drawing on the cover of this book. Each ticket is then written on a sticky note: That is, it's ticket number and short description. Aside from that, all tickets are in Trac. For each new version, a "Version" in Trac is created that is named [version number]-TODO. All tickets that are being planned for a certain version are assigned this version number. As someone is working on a feature, the sticky note is moved to the "In Progress" section of the whiteboard, and the ticket is "accepted" in Trac. As a feature is done, the sticky note is moved to the "Finished" section of the whiteboard, and the ticket is closed.

Version and Release Control

First, let's talk about the procedures concerning version and release control, and after that have a look at the technical infrastructure supporting these procedures. A developer should test his own code while developing. At this point, we are not (yet) too strict on the existence of unit tests or functional tests, but the developer should definitely try out the new functionality he implements. In theory, ONLY STABLE CODE SHOULD END UP IN OUR VERSION MANAGEMENT SYSTEM. The reason for this is simple: Since the holy aim of an iteration is to have a stable release after two weeks of development, you never ever want to have unstable code in your repository. If you have, you may not have the time to fix this before the end of the two week period. And at the end of such a two week period, the release should be stable enough for testing. So, ONLY COMMIT STABLE CODE.

At the end of the two-week period, a release is made by tagging the code that is in the development branch at that time, with a '-test1' postfix. As new releases are made during the third week after bugfixing, the number at the end of the postfix may get higher. As the testers sign off the latest test-release, this latest test-release is then tagged as [version number]-final. This -final release is exported, then deployed to the production environment according to strict planning guidelines (I'll discuss this later). Development is always being done in a development branch. This branch is created from the trunk on the second friday of an iteration (basically, the last workday before a new iteration starts). This branch is named as [next version number]-dev, and all developers should commit to this development branch. These are exceptions to this: If during the planning meeting it is decided to implement a feature that will take more than the two-week span of development during an iteration, a seperate development branch for *only* this specific features is created from trunk. The new development branch is not created before the old development branch has been merged back to the trunk, the get the trunk updated with all the new functionality.

Version and Release infrastructure

For ticket tracking, we use the Trac software. Reason for this is the tight integration with our version management system, enabling us to have a simple overview of which changesets are related to which tickets, as well as easily seeing which files have been changed for which reasons. For version control we use Subversion. We heavily rely on it's branching, tagging and merging techniques.

Deployment planning

We have very simple but effective rules concerning deployment to the production machine:

  • No deployment will happen after 14:00. If something goes wrong with deploying, you may be working into the night if you start deployment after this time.
  • No deployment will happen on friday. If something goes wrong with deploying, you may be working into the weekend if you deploy on friday
  • No deployment will happen of big features if there is no extensive deployment plan and rollback scenario. For deployment of bugfix releases or minor updates, a short rollback scenario as well as a database changeset is required.
  • Deployment should always be planned at least a day ahead. The latter rule is not strictly enforced, but it is a good guideline to prevent surprises and allow for good planning and preparation.

Deployment to the test server is not affected by these rules, since the test server (even though important) is not critical to have down during a night/weekend.

That's about it

I hope this is of any use to people out there. If you have any questions, feel free to contact me. I'd gladly give some advice where needed. I know for a fact that ever since we started working in this pretty strict way, the quality of our code as well as our external communication have improved bigtime. Clients will love you for this.


Add comment

Comments

gravatar pcdinh: You develop stuff with PHP right? Why not use Streber, a Trac-like but PHP5-based project management system: http://www.streber-pm.org/5 It is a bit more advanced than minimalist Python-based Trac


gravatar Aaron Saray: I forgot to post with my e-mail address. It is attached to this post now. :)


gravatar Aaron Saray: Arg – looks like I lost my previous message.

Basically I had two questions I wanted to run past you: 1) how do you handle emergency production bug fixes and 2) how do you handle a less than 2 week project during a longer than 2 week enhancement to an existing application?

I would love to be able to speak with you further about this if you’d be so kind to e-mail me. Thanks sooo much.


gravatar Stefan: Aaron: I’ll e-mail you in a minute but want to publicly address your questions:

1. We hope to prevent emergency production bug fixes using this approach, as the tests are much better and more structural.

If a huge issue would slip to production without us noticing, though, and we could not leave this to wait until the next release, we’d take out the tag of the production release, fix it there first, and then update the production machine. A holy rule: “No direct editing on the production machine” if you ask me.
2) At this point, we’ve only implemented the Agile system for one of our projects, which is a big project with lots of development. For smaller projects though, I could suspect we would use the same approach and see the smaller projects as part of the iteration tasks. But I can’t give conclusive comment on this yet, as we haven’t applied these principles to our smaller projects yet.


gravatar Aaron Saray: Ok – thanks for the updates. When we have helpdesk tickets, its sometimes because of coding errors, sometimes because we can code faster than the system-i data side, or there is an “emergency” business user change – we must change it for them.

I also noticed we have one other step that you don’t have in your process… we provide a user-qa of 2 weeks. I’m sure we could probably shorten this to 1 week on most projects, but larger ones require 2 as per our business users.

I look forward to hearing from you on how you integrate the process in. Last time I went to ZendCon, no one had an answer for me – as they felt that our situation wasn’t the normal software production cycle. Unfortunately, the production of web applications is different than the system-i type of development (they have objects, libraries, “look ahead” and more), and our users are used to that type of development.

Keep up the good work.


gravatar Frank: Thanks Stefan for this great article. I have one question, which came back to my mind, as i read your article. How do the tests of your testing group look like? In Symfony you have unit and functional tests. No problem so far. But how how do you for example guarantee completeness of your tests (code coverage)?

What do you think about test driven development and why you don’t use it in this case?

The tip with whiteboard and sticky notes is very fine, i will try this out soon :)


gravatar Stefan: Frank: The testers at this point do pure human functional tests. They walk through the application, testing if it works as expected.

I think TDD is great, if you have the time and funding to do so. In this case, we didn’t have the experience with TDD, the time to take it on, nor the money to invest on this extra development time. I know in the end it might end up more efficient, but this was a chance we were not willing to take at that point.


© 2004 - 2008 Stefan Koopmanschap + Powered by Symfony, photos powered by Flickr, links powered by Ma.gnolia, Shanghai smilies by Iconbuffet. Feeds: rss / atom. Left on the Web v4.2.2