This is the 4th post in a series called “How to get started with CI”.
Previously I talked about how to choose the right CI tool. This post will assume you have chosen hardware and a CI tool and have it ready to use. It will highlight the steps required to implement a project into a CI tool. The order of the steps is only a reflection of my experience of implementation and how to communicate this with a team.
Make your build self building!
This is a very important point. This means we need to make sure that all the references of a project are not referenced from the GAC on your local system. This is important as when the CI script is running on the build server, we cannot assume that the same software is installed on that build server. We could therefore have reference problems. With package managers such as Nuget, OpenWrap, Ruby Gems etc we can configure our build script to download the packages required for our project. The other way we can take care of it is to store our 3rd party dependencies in our source control alongside the project.
- solution root
Notice how I lay my project out. Alongside the “src” (or trunk or whatever you call it – this is where the .sln file lies) I have a lib folder. This is effectively my tools folder. I am honestly not sure why I don’t call it tools – I never have though. All my project references to items that don’t come as standard with the .Net framework are added here and my solution/ project references from here.
If you do not adopt this sort of approach, then the first time a developer does a clone of the central repository, then there is a chance the project will not build for them if there are dependencies that are not installed on their machine. This has happened to me and it took me a few days to take care of – trying to find out what was needed and where I could find it. Don’t fall into this area of risk! We should be able to lone and build easily!
Automate the build – nightly
If the company is sceptical of a CI system, then the first step I take in implementing a CI system is to run a nightly build of the project. This means that when developers do a final push of the day to their source control, they will be able to come in the next morning and see if there are any issues with what they have pushed. Traditionally we do not tend to face integration with other peoples code until much later in the project lifecycle. CI helps us to integrate more frequently – in the case of a nightly build it will happen overnight and give the developers a chance to know first thing the next morning if there are any issues.
This can sometimes put developers on edge when checking in as embarrassment ensues when they break the build. I actively encourage breaking the build. When the build breaks, we can see areas we need to think of. If it is because there are missing files then there is no issues, if it is because of integration problems then better to know sooner. The entire team should learn from broken builds.
If the developers come in to a good build then confidence is gained. Anything that raises developers confidence in their code is a good thing.
If the build is in a failed state, it is important to fix that build before continuing with a current task. There is absolutely nothing gained from CI if the main repository is in a broken state. It also means fresh clones will have errors instantly.
Keep the build fast
A nightly build is a great first step, but we need to try and get a bit more instantaneous feedback as to how things are going. This is, of course, the entire point of a CI system. There is absolutely no point in increasing the frequency of builds unless the build is fast. If the build takes 1 hour to run then we are not going to get fast feedback!! The suggested build time is approximately 10 minutes. If we breach this then we really need to investigate how we reduce this time. I have a current project with 78 projects in Visual Studio (approximately 1/2 million lines of code) and it takes approx 1 minute 30 seconds to build.
Lets think of a developer who checks in and triggers a build. If that build takes 30 minutes to run and then shows errors with the integration, then there is a chance his work in the past 30 minutes may cause even further problems.
Increase the frequency of builds
No we have reduced the time taken for a build, we can now increase the frequency of our builds. I suggest that we trigger a build every time something has changed in source control. We can add rules to the triggers to exclude README files or trivial files like that. I suggest anything that can have an effect on the code should trigger a build. This means the developer can see within, (our 10 minute rule comes into play here) a short amount of time if their code has caused issues.
Give instant feedback on builds
If we are increasing the frequency of builds then we need an instant feedback mechanism. Email is all well and good for some things but we need something very fast to see. Phil Collins has written a great article on build radiators as a form of instant feedback for the entire team. If you haven’t already read this article then please do. It is a great form of communication with the team.
You can have tray monitor applications or windows gadgets for your CI tools. This all helps in the instant feedback loop. I the past I have written a custom app that hooks into Skype.exe and send me a message with the status of the build. Anything that will make things clearer will help.
The faster we know if there is a problem the better it is. Alternatively, the faster we know our code works, the faster we can get on to the next task.
The steps listed above will help to take a new (or existing) project and implement it into a CI system. It is designed to be a slow introduction to a team (unless the team is fully behind it) as it will help raise the teams confidence in the process. The steps do not have to be followed in this order. I have just suggested they follow this order naturally. The steps purposely do not talk about running unit tests just yet. That will form the next post.
The process itself may not go smoothly. I have recently been talking to Craig Berntson about the process as he was doing something similar on a new project. It took him 2 weeks in order to make the project self building. This was a struggle and is not uncommon. Please do bear this in mind when something of this magnitude happens. I do promise you it will all be worth it in the end!
Good luck with introducing your first project to CI. I would love to hear how your first CI project went – good or bad!