It has become a best practice to run a private build on the developer machine before committing a change to the central source repository to minimize broken CI builds. Despite being a sensible measure to improve the development process this practice has always bugged me, because it is an extra manual step. In my opinion automating this step is one of the missing pieces for a better CI process.
Most of us (should) have got used to the following five steps when changing/adding a piece of code:
- Save/commit your changes in your IDE
- Run the unit tests that cover the changed area
- Run a private local build
- Push your changes to the master repository
- Your CI tool automatically picks up the changes and executes your deployment pipeline
You also probably didn’t execute steps three and four every time you did step one. Mostly not because it wouldn’t make sense to do so, but because these steps are time consuming. I believe that only the first step should be manual, all others can be triggered by their previous step.
- Save/commit your changes in your IDE
- Your IDE automatically runs the necessary unit tests (e.g. with JUnit Max or Infinitest)
- Your distributed CI tool automatically pulls the latest changes from the master repository and runs a local build
- Your distributed CI tool automatically pushes the changes to the master repository
- Your central CI tool automatically picks up the changes and executes your deployment pipeline
When practicing rigorous TDD one could even argue that not even the first step needs to be manual. The first two steps could be switched around and your IDE could run the unit tests whenever the code compiles and then automatically save your changes when all unit tests are green.
- Your IDE automatically runs the necessary unit tests whenever the code compiles
- Your IDE automatically commits your changes when all unit tests are green
- Your distributed CI tool automatically pulls the latest changes from the master repository and runs a local build
- Your distributed CI tool automatically pushes the changes to the master repository
- Your CI tool automatically picks up the changes and executes your deployment pipeline
No more manual steps at all. Just pure coding. It will be a bright future.
I set up the distributed CI part by installing a Hudson instance on my developer machine and another one on my CI server. When my local Hudson detects a change to my local Git repository it runs jobs to pull the latest changes from the master repository and update my clone, then executes a commit build and finally pushes the changes to the master repository, where the other Hudson instance runs the full deployment pipeline, including acceptance tests. This seems to work fine, but is of course quite a bit to set up and even harder to keep in sync without native tool support by Hudson.
P.S. I made a visual representation of how I am envisaging the development process with distributed CI. You can find it here. I will probably explain the diagram in more detail in a follow up post.
[…] This post was mentioned on Twitter by Edward J Ciramella, Manuel Küblböck. Manuel Küblböck said: Why distributed CI is the logical next step: http://wp.me/pGnRe-6H […]
The only problem with your idea, is that running a full build/test is a time consuming step. For my project that’s easily a 10-15 minute build/test step that can keep my system heavily used.
Fair point. This process assumes that you are working on a machine that can handle the load of running a build in the background. Unfortunately, we don’t always have this luxury. Although, I do believe that the time savings permit the purchase of well equipped developer machines.
Assuming you have a deployment pipeline with several stages, you might decide to only run the first stage with your (real) unit tests on the developer machines. Since these tests don’t use any external systems, databases, file system etc, they should be reasonably fast. I would think well under 10 minutes. For a thorough discussion of deployment pipelines and CI in general I can suggest ‘Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation’ by Jez Humble and David Farley.
Running the local CI instances in the cloud might also be an option. Although I am not convinced that the performance is good enough. This is just an assumption though, I never tried it myself.
[…] Küblböck explains Why distributed CI is the logical next step: It has become a best practice to run a private build on the developer machine before committing […]
We’ve been using Hudson with Gerrit to do something similar (for the later stages at least).
Gerrit is a Git code review system.
When a developer is ready they push their changes for review to gerrit. Hudson sees that a new review request has been created, pulls the code, builds it, updates the review with whether it is verified or fails build). Once this is done a reviewer reviews the code (unit testing is only as good as the tests that have actually been written) and then tells Gerrit to push it onto the master branch.
This ensures that the code builds, passes all tests and has actually been reviewed before it is pushed into the master branch and breaks the main CI build.
Saw this on tweeter earlier
Nice blog, and private CI system trigger me some thinking.
Also, if we have nice ALM system integrated, then only finished features will be triggered as one build and push to master branch, it means half finished features are useless to main branch.
I am not sure, if I agree on only pushing finished features to the master repository. That way you are not really integrating your code with the rest of the team. Sounds a lot like having feature branches with all their disadvantages. Compare http://martinfowler.com/bliki/FeatureBranch.html
[…] Manuel’s blog why ditributed ci is the logic next step, he even gave more thinking behind it, initial a private CI build, and CI build will automatically […]
[…] dead. Long live Jenkins. Distributed CI: How it could work February 2, 2011 I think distributed CI is the logical next step in the evolution of Continuous Integration by getting rid of the manual step of running a private […]