(Not to be confused with SmallReleases.)
Isn't FrequentReleases a clarification of the intent for having SmallReleases?
On C3, we do not practice CodeOwnership. This means that developers can go very fast, since if they need something, they just implement it.
It also means that there is the potential that several developers will edit the same class. How do you manage that, C3?
Thanks for asking. We call our solution ContinuousIntegrationRelentlessTesting. Imagine how nice it would be if, the second that you made a correct change to the system, it appeared in everyone's config. Generally speaking, it would be transparent and everyone would always be in sync.
We accomplish this by each developer releasing his/her code to the config about once a day, more often if possible. ENVY warns us if we are about to release a version that isn't based on the one currently released: that means that someone has edited and released the class ahead of us. That's rare, but when it happens, we just integrate our changes into the new version. If it looks tricky, we get the previous editor to partner with us.
How do you avoid breaking things, C3?
- We have about 2500 UnitTests, testing some 20,000 different things in the system. All the unit tests must run at 100%. None may fail. If they do, we fix them before we release.
But testing cannot find all defects, we all know that. How could this possibly work?
- From time to time, something will slip through. When things slip through, we beef up the UnitTests to cover that case and anything else it reminds us of. This means that the UnitTests become a finer and finer web, reducing the chance of bad releases nearly to nil.
But wait a minute! Sometimes you have to break something in order to fix it. What about big changes that take a long time to get done?
- It turns out that you don't have to do that as often as I originally thought. One time ChetHendrickson and I did something that actually took us a couple of weeks. Even now I'm not sure we couldn't have done it incrementally.
- Since that horrible experience, we have never again found something that couldn't be evolved from where it was to where it needed to be. The effect is wonderful: the system always improves and never goes backward. Believe me, we aren't geniuses who get everything right the first time: but we have learned how to refactor from where we are to where we need to be without passing through Broken on the way back to Go. {Finding the IncrementalPath requires a developmental sense that starts with believing that there is one.}
Developers are encouraged to load the config frequently, at least daily. By doing this, they do small integrations often, avoiding the big integrations with their hard-to-find problems. Using this approach, integration is almost free.
But it seems that a fixed amount of integration has to be done. This is just spreading it out instead of doing it in a nice efficient batch.
- Well, that turns out not to be the case. If you have three changes to make to the system, and make them all, it will likely take you longer than making and testing them one at a time. This is because of the increase in complexity in the interactions between the changes.
- Integration works the same way: if you do it in little bites, it goes quickly, but if you do it in big bites you get IntegrationHell.
Our development system is
VisualWorks, while our production system is
GemStone. We decided to make the two completely compatible: the entire system works in VW as well as in GS. When we first started production, we changed our process to run all the tests in GS as well as VW and then push the code. This was a mistake: the tests are so much slower in GS that developers would put off releasing until it was "worth it", and then would have a big integration bite to swallow.
So we changed the process. Now we release only to VW. Weekly we run all the UnitTests and FunctionalTests in GS, and then push the code. This works quite well. When it fails, it will fail because of an incompatibility between GS and VW: we fix the incompatibility, making the entire process more bulletproof.
This process all came about because we thought "wouldn't it be nice if everyone's image was always current with the best possible code", and then came up with a simple process that came as close as practical to that ideal. --RonJeffries
Another way through this is IncrementalIntegration
CategoryExtremeProgramming