Agile Chronicles #3: Branch Workflow

The Agile Chronicles is a set of articles documenting my experiences using an Agile process (Scrum) in software development on my current Flex project.

  1. Part 1 – Stressful
  2. Part 2 – Code Refactoring
  3. Part 3 – Branch Workflow
  4. Part 4 – POC, Strategy, and Design Challenges
  5. Part 5 – Acceptance Criteria & Punting
  6. Part 6 – Tools, Extra Merge Day, and Postponed Transitions
  7. Part 7 – Bugs, Unit Testing, and Throughput
  8. Part 8 – Demo, Burnout, and Feature Juggling
  9. Part 9 – Scope Creep
  10. Part 10 – Conclusions

This entry is about utilizing branches for each developer in Subversion, Merge Day, and how while cool, it’s an ivory tower process.

Note: This isn’t a tenet of the Agile methodology itself, it’s just something that works well when you have a bunch of developers collaborating together rapidly, and a specific workflow our client requested we follow.

Branch Workflow

We’re utilizing a Branch Workflow on my current project.  What this means is that each developer creates their own branch in Subversion.  If you’re utilizing Tortoise SVN on PC or Versions on Mac, this is effectively a folder.  As you may know, Subversion has 3 default folders that you typically utilize in a repository, and hopefully each project gets its own repository.  These are branches, tags, and trunk.

Some people choose to ignore these.  Some put multiple projects into the same repo.  Both are fine because the mere fact people are utilizing source control in the first place, even if its just for disaster recovery, is great.

These folders, however, really do have a few reasons for their existence that have been well thought out.  Each source control system tries to out-do the next.  In Subversions case, the simple definitions are trunk is for the current version of your project, tags are for multiple older versions of your project, and branches are for experimental features or code that will possibly be merged back into trunk later.

Those are EXTREMELY simple definitions.  If you read the SVN book as well as other people who incorporate SVN into their workflow, the definitions and purposes can get quite complex.  For the project I’m currently on, branches take on a new meaning.  Not only are they where experimental code goes, but they each represent a user story.  Meaning, if I’m working on completing the user story where the user can modify their hardware device settings via a Flex form, that’ll go in it’s own branch.  Using source control to do this is pretty straight forward.  Instead of checking in here:

https://svn.server.com/repos/project/trunk/

You instead check-in here:

https://svn.server.com/repos/project/branches/sprint2/deviceform/

And the other developer with me would be working from:

https://svn.server.com/repos/project/branches/sprint2/registration/

Pretty easy right?  It gets even easier to check in.  No more, “Dude, have you checked your shiz in?” to another developer, or the cardinal rule of doing an update before checking in.  Now you can check in to your hearts content knowing it’s your own repo to abuse how you wish.

This has the side benefit of NOT breaking trunk… usually.  Again, the point of having frozen code you KNOW for a fact works is to use a tag, or a series of tagged builds.  A lot of developers get seriously bent out of shape if you break the trunk.  At one job, whoever broke the trunk had to use this monkey icon for their IM icon for one week.  It was funny until the 50th person asked why I had a silly monkey icon, and by that point, I was swearing I’d never break ANY trunk ever again.  This can possibly have the effect of keeping ’em happy.  At the very least, this reduces the possibility of it happening because no one is working from trunk.

Instead, you check into trunk at the end of every sprint, or for my team, from Merge Day onwards.

Merge Day

Part of Agile is to have a day a few days before your UAT where everyone merges their working user stories into the same code base and “works out the kinks”.  Since everyone was coding in a different direction, this can be good and bad.  Good because they are working on completely unrelated things, but in GUI coding, we all know some things are extremely related.  Specifically, these are your data model in the form of ValueObjects, calls to a framework such as the use of Event classes in Cairngorm and PureMVC Mediators, and modifying settings in higher level view’s or CSS.

Since this can potentially have major consequences for some portions of a user story, or set of stories, it’s important to devote a pre-scheduled time where the team knows their code will be merged with everyone else’s code.  This is called Merge Day on my project and it happens every other Wednesday.  I take my branch and my co-workers, and merge his code into mine.  Then, I fix things that explode.  This could be as simple as just merging code over, or a complex verbal discussion to work towards resolving 2 different implementations.  No code is trivial.  If another developer added a style to MXML for example, setting the background color may seem small to you, but could be the difference between working or non-working code for the other developer’s code, so its important you do these merges together.

Once that is done, I merge into trunk, test again, fix explosions, and finally check in the working build.  I then upload a new build, or in the case of my current project, deploy a new build in a new sandbox utilizing Django’s web interface.  It can deploy to the web the latest bin-release that’s checked into SVN by merely clicking a button.  I’ll send an email to all members of the team identifying what’s new in the build.  This includes user stories, fixed bugs, and other things of note that are different from previous builds.

For fellow developers, this is a courtesy.  For Project Managers, it’s a necessity for them to set client expectations for Friday’s UAT.  For everyone it’s a Sprint milestone as well as reality check.  You can identify what user stories are done, which ones aren’t, what older ones you may have broken, and which current ones have issues.  You can then plan with your team what to spend the next day and a half on.  This is also where the rules can potentially break down.  What I’ll usually do is check my local copy into a new branch, and either fix partially completed or broken user stories, or just finish what I can.  The temptation here is to abandon branches since you only have a day and a half and it isn’t worth the trouble; just don’t break trunk in the meantime.

…riiiight.  The last thing you want to have happen the day before UAT is get all stressed out because trunk is broken.  To me, it’s worth the extra time in using the process to ensure your UAT prep goes smoothly.  I’m conservative.

I say that all high and mighty like, but on Sprint #2, I did just that.  Did I get lucky or was it just mad skillz?  Luck.

Conclusions

Now, all of the above processes could have been done with just utilizing trunk.  As you can hopefully see utilizing a branch for each developer, or multiple since creating a new folder is really easy, helps things go a lot smoother without surprises.  You can also plan for the chaos on Merge Day, which while extremely stressful for whoever is doing the merging, is at least expected and a concerted team effort.  I really have enjoyed the Branch Workflow so far.

…however, I don’t see it catching on.  Every Flash & Flex developer I’ve ever talked to doesn’t use branches.  Sam Robbins mentioned over Twitter they might start adopting this workflow at their place of work, and that’s great, but again, it seems to me most developers feel trunk is good enough and branches are just an unnecessary complication.

Stay tuned for #4 in the Agile Chronicles series where I talk about the POC (Proof of Concept), business strategy, and design challenges.

23 Replies to “Agile Chronicles #3: Branch Workflow”

  1. I’m not sure that all these branches is an agile thing. In fact looking at Martin Fowler’s article on Continuous Integration that you linked to in the first of this series of posts it seems to say not to do this. It suggests having a single branch that pretty much everyone should work off most of the time. I think Continuous Integration is about finding out about conflicts as soon as possible, rather than once every two weeks on a special day.

  2. Like I said at the top, it’s not necessarily part of the Agile methodology and was specifically requested by our client that we utilize this workflow. I haven’t done much research yet, but if you browse around looking at some of the criticisms against Agile, one in particular is that it “only works with senior-level developers”. I’ve seen some really good developers that just aren’t so hot with source control, so would re-word that to say “only works with those who are comfortable and proficient utilizing source control”.

    In my experience, many aren’t. If you take a pragmatic approach, then reducing the amount of SVN drama developers have to deal with is best.

    Secondly, utilizing branches ensures developers can stay productive, and only focus one thing; getting their piece of functionality done. There is a lot to be said about focus and helping people get in the zone. From that point of view, I support it.

    Third, the amount of code changes I’m doing couldn’t be done in a reasonable time frame if I had to involve everyone on my time for every single change, especially for sections that have very little relevance to what other developers are working on.

    Not sure yet though… this is my first time doing it.

  3. I can see the benefit of your higher ceremony approach. Because everyone knows it’s going to happen, then it guarantees it does happen regularly and predictably.

    I believe the Continuous Integration argument is that because everyone is committing every day, everyone is also updating their local copies every day. This means that there are several smaller problems over the course of the sprint, rather than one large one at the end.

    The pro Continuous Integration camp argue that the only way to get good at source control is to practice. Therefore if you are doing it every day, then you will get good at it fairly quickly.

  4. The workflow that Sam was referring to is slightly different- it’s having separate branches for each team and allowing the teams to decide when to merge back to the trunk, preferably when a specific story is done. But the teams will also be getting changes from the trunk as soon as they appear. I would find two weeks a long time to go between merges, and I’d rather just deal with everyone on trunk in that case!

  5. Yeah, good points Simon, I agree. I just re-read the old email thread and document the server-side team posted about the branch workflow. The main reasons he, the client suggesting the workflow, cited were:

    • a non-stable and constantly conflicted trunk
    • a fear that forms in developers in checking in their code to ensure they don’t negatively affect others with their potentially non-100%-complete code

    The thinking goes that if they don’t check in as often, that’s not necessarily good; they should check in to ensure they don’t lose their work. Additionally, you don’t want a constantly non-stable trunk you cannot depend on.

    You could still allow other developers to work on their own code base, and only merge in fully complete features without fear of negatively affecting the other engineers. Additionally, features that are taking a long time do not prevent the trunk from moving forward. One thing he is trying to prevent is half-written features in the trunk.

    He did cite that it tends to work better for larger teams, as well as a slower paced project.

    To me, to prevent the slowing the team down waiting for a particular feature to be comleted, I just created a branch. When the code was ready, I merged into trunk. So, I had no fear, and wasn’t negatively affecting anyone. However, this wasn’t a pattern like this workflow suggests; most of the features I was doing didn’t require days upon days to complete, and checking in incremental code towards the feature didn’t destabilize trunk. Only rarely did I create branches; it was usually for large magnitude features such as a completely new web service that was the crux of our app, or a brand new video player code base.

    Additionally, my current team is small; 2 dudes who are more than capable of talking to each other and my co-worker is easy going.

    Frankly, I feel like branches in this fashion are great for opt-in, because I totally agree with the points Simon and Brian make about getting the latest from trunk, in whatever state its in. I need another project with more people to really validate this approach as I only have 5 weeks of context.

  6. Just a wording issue, but Subversion doesn’t suggest any folder hierarchy by default. The whole trunk, branches, tags standard is a legacy one brought over from CVS. But it does seem to be the standard that is used by most shops.

  7. I think that having everyone working off the trunk is playing with dynamite. It really is about practicing with tool(s) to learn to use them effectively. I think a lot of devs get turned away because many of the toolsets are less than intuitive.

    Jesse, I’m interested in what, if any, portions of this experience you might apply to other projects where they weren’t using Agile/Scrum/Branching? Even on solo work.

  8. you can avoid ‘merge days’ entirely while still maintaining stable isolation by using a stream-based SCM system instead of one that is branch-based… Think branches with inheritance… so rather than merging down, you inherit up – thus merging sooner than later… a major tenant of agile and CI. HTH

  9. I use branches all the time when dealing with larger projects and subcontractors. I had no idea it was “normal” for most devs to use the trunk.

    For example, on an ongoing project, I created a branch for the design work and a branch for the shopping cart work. They can go on in parallel and as things finish, they’ll get merged back in.

    I’ve found that when merging back to the trunk I lose all the branch history. I’m not sure if this a “bug” in SVN or due to the software I use. I do agree that merging is stressful.

  10. Quoting from Martin Fowler’s Continuous Integration article:
    “Continuous Integration assumes a high degree of tests which are automated into the software”
    It is these tests which guard against the trunk being broken. In theory, if you are committing code which breaks the tests, then you shouldn’t have committed it in the first place. Although in practice, changes can be reverted if someone’s been lazy and hasn’t run tests before committing.

    Continuous Integration also assumes (I think) fairly small team sizes. To scale up, you’d probably need to chop things up into different components or sub-projects, which you could then deal with separately. Maybe these components could then be integration weekly/biweekly (with possibly another layer of tests existing).

  11. …that’s just it, I do NOT get how in the hell to write unit tests. I’ve read over ASUnit, FlexUnit, and fluint, and all seem to be really neat. …however, if I’m deleting code, and re-factoring like crazy, how in the heck do I write tests? It seems like a complete waste of time if I’m going to re-write them too once done re-factoring the code. Maybe they are less work than I’m making them out to be.

  12. I don’t want to pretend to be an expert, but I’ll try sharing some ideas around testing, but it really is a whole new can of worms.

    The stuff I’ve read about Test Driven Development shows testing in a different light for me. In TDD, because you are defining tests upfront, it means that your tests aren’t testing a particular implementation, but instead expressing intent of what the code should ultimately do. It also means that any implementation you write has to be testable by the tests you write. For code to be easily testable it’s pushing you towards proper encapsulation, with code broken down into testable, understandable pieces.

    In the testing side of things mock object tests have arisen from the desire to test things in isolation, and from the code side the decoupling technique of Dependency Injection is becoming fashionable. As well as decoupling the logical layers of a system, DI also decouples your tests and implementation.

    Tests up front means that the requirement must be understood so that you are able to express it as a test. It forces you to have an understanding of your goal before you start writing code, potentially helping you avoid wasted coding. TDD not only drives your development but affectively drives your design as well. Once you start writing a test, you then have to think about how you’d want to test the component and how it’s used.

    From a refactoring point of view, tests ideally should aid you, as they can provide a safety net so that you can tell if things still work when you’ve finished. Thinking about TDD again: if you are refactoring to be able to add new functionality, if you write the test first and then some code, you can interleave refactoring tests and code, rather than being a large tidyup job at the end (and hopefully being less work).

    Tests themselves still need refactoring also, because like all code, they can normally be improved. Tests themselves are an asset and ultimately can save you time as you think about your code more and hence need to refactor less. If you value tests as being almost as important as the code, then the question of the amount of work they are becomes less relevant.

    P.S. This isn’t something I personally practice, but I think the ideas are interesting.

  13. Wow, thanks a ton for taking the time to explain that Simon! That’s whack, you clearly can articulate it, yet you don’t use it? Why not?

    The only thing I don’t get is testing components. I learn the API by creating the component, not the other way around. Like, I don’t “know” a List control would have a selectedIndex, maximumScrollPosition, etc. before hand. I have to flesh out the component from the inside out. Once done, yeah, I could see writing tests for it to ensure it worked… just not writing test for a component I don’t even know how it works yet.

    Otherwise, everything else makes perfect sense.

  14. People don’t create something correctly the first time in its entirety. In TDD, it’s a case of defining an individual test and then writing code for it. Writing later tests may then mean you have to change the previous code you’ve written, but you’ve then still got the tests to tell you that everything still works.

    Writing these small bites lets you build up your idea of what how the component works and you gradually get a better idea of how the client to this component wants to use it. It’s a case of thinking about something the calling client code wants, thinking about how you initially want to design it, writing a test that calls it in that way and then writing/refactoring code as appropriate. You are incrementally building up the features of the component and iteratively improving it. Writing the tests gives you a different way of thinking about how the component works. The client ideally wants quite a simple view of the component, regardless of what’s going on inside.

    I don’t know if that’s made things any clearer, but I hope it helps.

    In regards to my specific situation, I work in a very small company that does not use agile or even have a project manager. I’m not under strict time limits to deliver and requirements aren’t always present for me to work on. Using Agile techniques is actually a pretty disciplined way of working, whilst I’m just working in a fairly laid back manner, with quite small pieces of work that aren’t very complex. Other people at my work aren’t especially interested in Agile and without a team’s enthusiasm for motivation to innovate and improve in this area; my interest has remained mainly theoretical.

  15. Simon is expressing TDD very eloquently. I want to blog about this some time, but for now, here’s a thought:
    “Test-Driven Development is a bigger paradigm shift than functional to object-oriented programming.”

    This is a quote I read somewhere and would like to track down. I have the privilege of doing TDD and pair programming and I would agree.

  16. Found the quote:

    “Jean Paul Boodhoo: So, let’s take the case of
    the lone developer who is seeing a really
    interesting TDD demonstration and is thinking to himself, well, I would really like to apply that in
    my daily development. Now, that person is — now, is honestly in for a bit of a world of hurt. Especially if he is the only developer on that team who has had exposure to Test-driven development; because the problem is, is TDD is as big if not bigger a paradigm shift as it was
    from procedural to OO programming.

    http://perseus.franklins.net/dotnetrocks_0168_jean_paul_boodhoo.pdf
    (page 7)

    I wouldn’t be so pessimistic about the “world of hurt” part. Any TDD is better than none. But of course it works a lot better when everyone working in your code is using it.

  17. Thank you very much for the excerpt and explanation, Robert! That helps a lot. After playing around with fluint, it doesn’t feel that game changing to me. It felt natural to write tests making sure my shiz works. I do that already using test harnesses to more easily test my GUI components in isolation as I work on them. It seems I just take it a step further, and write the tests even though the component doesn’t actually implement the implied API yet.

  18. Haah that Code monkey thing was like 5 years ago ;) I can’t believe you are still talking about that.

  19. hey
    did your team try mercurial instead of svn http://www.selenic.com/mercurial/wiki/ I think it has many advantages when agile developement. Well I red the comment and in previous post you wrote that business classes won’t change much so when project starts you simply write tests of this classes ( services, factories) other tests for me it’s a waste of time.
    And finally about merge day. I think important is to have project lead or small parts of the application leaders that merge the code and know what is exactly going on with the project. The continous merge when Mercurial is easier and less waste
    Keep it up nice blog :)

Comments are closed.