ALM Series – Part II: Follow the Yellow Brick Road
This is the 2nd plug post in a series about ALM. If you missed the first one, I encourage you to skip over there, have a quick read, then come back. I’ll be waiting for you.
In the last post, I described the three main pillars of ALM: Visibility, Traceability and Automation. This post will describe in more detail the systems and processes you can put in place to build these pillars and improve your chances of success.
Some Background and Context
At Mercury New Media we use Scrum, so many of the systems and processes we use facilitate this mode of operation. We like to deliver software early and often, so an environment that provides automated builds, a Sprint Backlog dashboard and can surface useful data for meaningful reports is vital for our day-to-day operations.
Establish your ALM Platform
By its very definition, ALM applies to all stages of the application lifecycle; all the way from requirements gathering to a successful production deployment. There are dozens of platform choices out there, and this post is not concerned with helping you find a specific one. All I care about is that you find one that works for you and your team. At Mercury New Media, we use Visual Studio Online (VSO) and its related offerings, because:
- It’s a single solution, so everything integrates. User stories and sprint tasks link to code check-ins which link to automated builds which link to deployments which link to the reporting on VSO. There are no manual steps (see Automation, folks!) or complicated configurations, it all works out of the box.
- Pretty much everything we do here is based on .NET, so we’re comfortable in the Land of Microsoft.
Just find one that works for you and go with it.
Step 1: Use a Source Code Repository
The first step is to set up your source code repository. This will be at the center of your ALM. It’s how developers will share their code, and the conduit through which your automated builds (see step 4) will perform their magic.
Step 2: Establish a Branching and Merging Strategy
How efficiently you can branch and merge your code will determine how efficiently your team can deliver code without getting into all sorts of bother.
My advice is to take the simplest approach that meets your project’s needs. If anything in the world is in need of KISS, it’s your branching and merging strategy. There’s nothing more awful than constantly running into merge conflicts due to an overcomplicated approach.
At Mercury, we use master as our integration branch. When we release code, our release build pulls from master and we throw a tag on there so we have information about where in our source code history the deployment occurred. Our support staff fix issues and make tweaks in a dev branch, and we do sprint work in a branch that’s typically named after the set of features we’re working on.
In this scenario, it’s important that we merge up from master regularly. The more time that passes, the further the code bases move away from each other and the more troublesome merging can be. When work is ready to be released to production, the code is merged down from the corresponding branch back into master. If you’ve been taking my advice (and merging from master regularly), this process should be relatively uneventful.
Step 3: Sandbox Your Developers
At its core, a developer (let’s say, for the sake of example, his name is Adam) needs to be able to make fundamental, potentially late-breaking architectural changes without fear of putting the kibosh on the rest of the team. Adam, however, should not have to wait to make his changes until his team is ready to receive them. Conversely, each team member should only receive Adam’s changes when they’re ready for them.
We achieve this Nirvana by sandboxing our developers. In the safety of their sandboxes, no team member has reliance on any shared resources. This mainly applies to, but is not limited to, the application database. It can also apply to other services used by the application, such as 3rd party web services not in the team’s control. I know Adam and…I wouldn’t like to be in his sandbox for fear of what lies beneath the sand ;).
Whether you use database-, model- or code-first strategies, it’s vital that each team member has their own database server for development. Now, if Adam needs to rename a column (which if he did that on a shared application database, the rest of the team would be instantly broken) he can do it in his own time frame. Now, schema changes and the code changes that go along with them can be committed into your source control repository as a single unit. When a team member has committed their latest work and is ready to receive changes, they will get both the schema updates and appropriate code at the same time – no breakage.
Ultimately, this approach will avoid bottlenecks, which are the destroyers of productivity. It isolates team members from each other’s changes until they’re ready for them.
Step 4: Set up your Builds
Every source code branch should have a Continuous Integration (CI) build that runs on every check-in. The build should retrieve the latest source code from that branch in the source code repository, build the code, deploy the application database and run unit tests.
When you’re in an Agile environment, it’s also vital to have a Nightly build. The Nightly build should be running off your active development branch. The build should do everything that the CI build does, plus deploy the application so that the Product Owner and Stakeholders can get their fingers in there and use it.
You should also have a Release build. This will be a manual trigger build that is pushed by the team when the application is ready. It’s important that this is an automated process so that institutional knowledge about how to perform the deployment is in the build definition, not in the team members’ heads or on scratches of paper. Your deployment processes should be repeatable and automated.
If there’s an application database (and there typically will be), each build should be deploying to a different location, and you can use web.config transforms to adjust the connection strings for each deployment.
Step 5: Configure Check-in Policies
In order to sate the 2nd pillar of ALM (traceability), you should define check-in policies. You can use this to mandate, for example, that all code check-ins are commented appropriately, and associated with a Sprint task. By storing this data you will be able to surface all kinds of interesting and useful information, such as tracing code changes all the way back to the User Story for which they were made.
In this post I have talked about how to set up your project development environment in order to effectively support the 3 pillars of ALM.
If you succeed at building these foundations, then you can safely follow the Yellow Brick Road to Emerald City.
If not, you might find yourself getting harassed by the wicked witch instead.
In the third and final post, I’m going to get down and dirty with specifics. I’m going to be writing code, people, so get plenty of sleep. See you next time.