I’m often asked for advice on how to improve a company’s development process. Almost without exception, the advice I provide is the same:
- Get Agile
- Get smart about branching
- Integrate changes early & often
- Automate, Automate, Automate
Then iterate around fixing the stuff that isn’t working as well as it should. Great, you say. But how exactly do you do that? What are the steps?
Here below are my 5 Steps to Development Process Nirvana for a SaaS *
1. Get Agile (or agile)
Commit to frequent releases. Adopt a process that is either formally Agile (what I call uppercase Agile) or less formally agile (lowercase agile). Train your team on how to use the process. Implement a tool or technique (I had a customer that used large, rolling whiteboards w/ colored index cards taped to it: this was the backlog) & then get to work creating your stories. Embracing an agile process is often a very difficult process for large teams, as there’s huge momentum in the Old Way. But do it anyway.
Examples of tools that assist w/ formal Agile are Rally. Informal agile can be managed very well w/ freepository or a handful of the other hosted project-management tools. You want to be able to create stories, group stories into iterations & milestones, and track everything. The online tools make this super easy.
2. Get Smart about Branching
Avoid on-going development activity on trunk. Trunk is reserved for the latest stable and pristine line of development that is currently in production.
Is this always the best approach for your team? No, but it is *almost* always the best approach. If your team is nimble enough to employ Continuous Deployment (CD), then the notion of branch-only development is pointless & will only slow you down. You have to be a *very* tightly functioning team to pull off CD; the larger the team, the less likely this will work for your organization. So stick w/ my rule instead.
Use individual unified development branches instead of feature branches. This allows for shorter release cycles; as multiple developers work on a unified development branch, not all features they are working on may be ready for this week’s release. Create a new integration branch (see next rule) and only forward merge the changes that are ready. Then if feature X is not ready, it will not move forward and you haven’t destabilized the original dev branch where feature X is in progress.
3. Integrate Early & Often
Utilize integration branches & a competent Continuous Integration (CI) server, like Cruisecontrol, Hudson or similar. If you don’t have CI yet, stop reading this & go implement it – now.
The integration branches are not meant for human consumption; their purpose is to assert stability. Release to a staging or production branch is done from the integration branch, not from individual developer branches. When developers check in to a development branch, changes are automatically merged to an integration branch (using a hook). Continuous integration and builds occurs on the integration branch. Pre-production release (after QA) is a straight-forward merge (promotion) onto trunk. Production deployment is from trunk.
The main point here is that integration branches are *only* used to support automated promotion & merging work. They’re *not* to be used as developer sandboxes or anything else that pollutes them. If you break this rule, you’ll have to sit in the corner.
4. Automate, Automate, Automate
Automate as much as possible to eliminate manual steps and points of friction. Manual steps introduce human error and time. Build automation provides immediate, quantitative feedback (did we break the build?). Automated regressions tests support qualitative feedback (did the results of a successful build still have problems?).
Candidates for automation include:
– Automatically creating development branches for developers to do work. This provides a consistent and repeatable process.
– Use commit hooks for automating manual steps, i.e. pre-commit hooks for performing merges into integration branch. Hooks can also enforce code reviews, quality reviews, and checks at various stages, essentially eliminating the noise around bad commits.
So ‘automate everything’ seems common-sensical, sure, but you have to actually *do the work*. You can’t say ‘we should automate this’ & then not follow-through. Treat the infrastructure like any other piece of development: scope it, create a story & put in on the backlog. When it gets voted into a release, do it, track, & be done w/ it.
Utilize Virtual Machines instead of dedicated hardware environments. This decouples specific hardware environments from roles and promotes faster deployment cycles and reuse.
This is another one that may seem obvious when you hear it, but it is often overlooked. Virtualization today is easy & inexpensive – there’s no reason not to use it to augment (or even replace) your dedicated QA boxes.
Some of you may be wondering how use of a distributed version control system like git impacts my process choices. The answer? Not much – I’ll get into that in another post. Til then, let me know what you think in the comments.
*partially transcribed by someone else, but they’re my words