GullFOSS
OpenOffice.org Engineering at Sun
 
 
 
 
More Flickr photos tagged with openoffice

Today's Page Hits: 865

Locations of visitors to this page
« New: OOo-DEV 3.1... | Main | QUASTe: Easier verif... »
Monday, 16 Mar 2009
Continuous integration – is it possible?
Mathias Bauer

When I came across Martin Hollmichel's blog about “Continuous integration”, it immediately attracted my attention because I'm thinking about the same thing for some weeks now. On a first glance, and with the way we are doing our milestone and release builds now in mind, you might think that Martin is a loony. If that was true, it was quite unfortunate for me, as it would make me a loony too because I share his ideas. Sure, taking the current way of doing builds it's hard to believe that this integration model could work. But let's look on it from another side: what is it what Martin (if I understand him correctly!) and I want to achieve and what must be changed to make that possible?

Before you read on – please be aware that I just describe a (possible) goal. Fortunately it can be reached in several steps, so don't get discouraged by the fact that of course not everything can be done at once and now. But I hope that you can discover the advantages that “continuous integration” can bring to us.

Here are the problems I would like to see solved:

  1. The integration of several CWS in one step that we do currently is prone to inter-CWS conflicts and can lead to a source tree

    • with merge conflicts

    • without conflicts but with build errors

    • that builds but has bugs not present in any of the integrated CWS

    Avoiding this will make integration smoother and will improve the quality of the master builds.

  2. As a new milestone build usually is started only after a certain number of CWS has been integrated, the “time to master” for a CWS can be several days or even weeks. A worst case scenario is that an integrated CWS created a huge number of conflicts that delays the build and any further integrations and needs developers to fix them, preferably on Friday evening. Faster “ time to master” is important for developers, as they need it for the creation of follow-up CWS, but in an indirect way also for quality: the earlier a CWS is integrated, the more it can get real life testing by users. Users only rarely use CWS builds, but at least some of them give our milestone builds a try.

  3. Integration of CWS needs too much work done by release engineers that either could be automated or done by developers. IMHO conflicts always should be fixed by the CWS developers, not by anybody else. But this should never hinder the integration process, so it must happen outside of the integration step. Doing everything else in an automated way enables us to work on integrations 24/7. And the release engineers will have more time for other things.

The problems described in (1) can't happen if a CWS to be integrated is resynced to the current master and has got sufficient testing (working tools and processes assumed).

A “Deluxe” solution that addresses all points could be the following:

  • Take the first CWS.

  • Resync it to the most current master on the desired code line.

  • If that doesn't work, set the CWS back to “new”.

  • If the resync worked fine, integrate the CWS; now merge conflicts shouldn't happen.

  • The CWS is backed out again and reset to “new” if one of the following things happens:

    • the build breaks on at least one platform,

    • the smoke test is not passed on at least one platform,

    • from a to be defined number of other tests (could be performance, test tool, convwatch etc., everything we want) at least one has not been passed on at least one platform.

  • If everything went fine, the current source tree is made a milestone, the new most current master on this code line.

  • If either we have a new milestone or the CWS has been backed out, the next CWS is taken and the process starts again.

  • There are other things to be discussed, especially for the people working in the build environment in Hamburg (like e.g. for which milestones we would want to have pre-compiled binaries), but that shouldn't bother the rest of the community.

This process would give us much more control over the quality of the master builds and it would shorten the “time to master” for all well-behaving CWS considerably. And it also addresses the third point: each step is basically an automatic one and, if no problems happen, everything can be carried out without manual interaction and it can be done “around the clock”. Problems are kept away from the master and are moved into the CWS. All CWS that don't create any problems can be integrated continuously, the “naughty” ones are skipped and queued again after fixing the problems.

It depends on the speed of each single step how fast this integration moves forward and if the overall speed is acceptable. Let's have a look on the current performance and let's also do a rough estimation for what we might need.

Currently resyncing this is awfully slow. With svn it would be even faster to extract a patch from the CWS to be integrated, create a new CWS on the current master and apply and commit the patch to it, treat this CWS according to my list and either then merge it into the master (what should work fine) or throw it away (no reason to back anything out). Maybe we could do it that way, but my hope is that our planned move to a DSCM will make resyncing considerably faster, so that the process could be done without creating an intermediate CWS. This needs verification.

Building the source and packing installation sets takes too long nowadays; I think that it can be made faster by

  • building on faster hardware and environment, if necessary on a local source tree,

  • building only the absolutely necessary stuff (needs changes in packaging of course),

  • not building full installation sets but using the “ PKGFORMAT=installed” output as this is enough to run tests afterwards,

  • speeding up the build environment.

Of course there will be a few CWS where the points 2 and 3 don't apply (e.g. changes in localization, extensions, installation, binfilter), but we can integrate these CWS in dedicated milestones. We can do a complete build with complete packaging as today after integration of 10 CWS or so. Then we will have a comparable output of “complete” milestones as today, but with many intermediate steps in between.

As everything described is a more or less automatic process, we are not bound to release engineers being available for integration and can do it 24/7. So for a feasibility study we shouldn't ask how many CWS per day a release engineer can integrate today, but rather how fast we can make our processes to achieve the necessary integration rate if we assume that there will always be at least one CWS that can be integrated.

According to Thorsten Ziehm we have integrated between 50 and 125 CWS per month in 2008, on average 75 per month. That would be approximately 2.5 CWS per day (in 24/7 mode!). These numbers look promising enough to consider it doable, especially if we can assume that building and testing can be accelerated as described. Without having exact numbers I expect that the number of nominated CWS per day has large peaks – but I think that can be overcome, mainly by better planing in development.

So we could get the same number of CWS integrated, but with more control over quality, shorter time to master for individual CWS and with less manual work. And the whole process can be implemented incrementally, something I always consider to be important if changes are to be applied. So we can start with the first step (always resync CWS, don't let them in the master if that conflicts, otherwise integrate) and look for ways to make this an automatic process. Next step would be to look for possible ways to do builds and tests after each integration in a reasonable time frame, but until we have found a way to manage the resources, nothing needs to be changed. I guesstimate that now at least all tests except the smoke test will take too long, I don't know if there are some possible steps to allow at least for building and smoke testing after each integration step. Perhaps this is something we can implement in a not so distinct future, so we can leave this up to a reality check.

So far I have talked about the “every day” work. Whether we can follow the same strategy when we approach the release date or if we need more complete builds then is open for discussion.

So please don't see Martin's blog and this one as strange musings of some first class loonies, they are just a look on things from a completely different viewing angle, to solve problems that we know but never tried to fix. I think we described worthwile goals and I hope that instead of comments why this can't work we get a help to make that happen. I outlined a possible goal. And each journey towards a goal starts with the first step.


tags:

Posted by Mathias Bauer on 16 Mar 2009  |  PermaLink |  Bookmark to Delicious To Delicious |  Digg this Digg this  |  Comments[9]

Comments

Stephan Bergmann said:

I like your Deluxe algorithm, but have just one nit: A CWS can "starve" and never get integrated if it always conflicts with the then-current master.

Posted by Stephan Bergmann on March 17, 2009 at 09:53 AM CET #

Mathias Bauer said:

Theoretically this could happen. It would help to integrate such a CWS immediately after nomination, when the current master is still the same it has been resynced to. Giving a requeued CWSs a higher integration priority could fix that. In case a CWS has been requeued a certain number of times and is still rejected, we could stop the automatic cycle until this CWS is resynced, fixed and integrated.

Posted by Mathias Bauer on March 18, 2009 at 05:28 PM CET #

Björn Michaelsen said:

Well, a first simple step in concept would be to do the integration merge on the cws branch and not on the trunk, while (for now) keeping the rest of the process as it currently is.
That is instead of mergeing a cws into the trunk, the trunk is merged into the cws (or "resync to trunk HEAD") and the result is synced back to the trunk. Thus, merge conflict resolution (regardless if they are done by a dev or by a releng) always "belongs" to a cws (and are committed there) and is not "ownerless" happening on the trunk.
This would have quite some interesting sideeffects and garantuees:
- no merge conflict resolution on trunk
- every change (except those rare "masterfixes") belongs to a cws - even integration
- devs have a easy way to see (on the cws branch), what and if something was happening to their cws on integration
- _every_ cws branch starts in sync with the trunk and ends in sync with the trunk

Essentially this is already "continuous integration", but simply without changing our current workflow too much.

"CWS starvation" as described by Stephan currently isnt likely, as merge conflict resolution for the "resync to trunk HEAD" step are done by RelEng. However this is not really a question of merging the cws into the trunk or merging ("resyncing") the trunk into the cws: Its a question of process and responsibilites.

Posted by Björn Michaelsen on March 18, 2009 at 11:51 PM CET #

Someone said:

Hi Björn, maybe I didn't decribe it good enough, but yes, merging only on CWS but never on master is the first step I have in mind. How we sync that changes "back to trunc" depends on the SCM, I assume. Do you suppose to copy the CWS to trunk instead of merging it? That sounds like a good idea, as it will most probably have less chances to create errors and it should be much faster than the current process (if svn is not even worse than it looks now).

Unfortunately merging trunk into the CWS ("resync") is slow with svn, so we have to find out how to make that faster as long as we are using svn.

Posted by 213.39.134.230 on March 19, 2009 at 08:44 AM CET #

Someone said:

I should have thought a little bit more before answering: as I understand it, everything else than merging to trunc will destroy its history. If that is true, that wouldn't be acceptable.

Posted by 213.39.134.230 on March 19, 2009 at 08:53 AM CET #

Bjoern Michaelsen said:

I was only trying to show that a move to "continuous integration" doesnt have to be a really a huge monolithic change from our current process. This is just because I think the move to subversion has made quite a few devs very careful of those.

As for merging with history: IIRC currently (with svn) we dont have the history from the cws on the trunk. An intregrated cws shows up as one commit containing all the changes made by a cws and the resolved conflicts.

And if/when we switch to a DSCM we would have to carefully consider how to handle this: While it might be nice to have all the history from all the cws on the trunk repository, its not easy to "strip" a repository of history (example mercurial: They call it "partial cloning", a feature that is worked upon). Since everytime one creates a cws in a DSCM, one creates a local copy of the trunk repo, having that repo containing all history might prove problematic too (for both discspace and time reasons).

BTW, Who am I talking to, 213.39.134.230? ;-) I am assuming you are Mathias.

Posted by Bjoern Michaelsen on March 19, 2009 at 10:34 AM CET #

Mathias Bauer said:

Oops, yes, I forgot to add my name. I was used to have remembered the name on my computer, but currently I'm using a replacement computer where I didn't ask for "remember information". Fixed now.

I was talking about the *trunc* history, not the CWS history. However we sync the CWS to trunc, it must keep the trunc history. In my understanding the only way to have that in svn is merging the CWS to trunc. But I would appreciate to be wrong here. ;-)

Posted by Mathias Bauer on March 19, 2009 at 10:53 AM CET #

Bjoern Michaelsen said:

"In my understanding the only way to have that in svn is merging the CWS to trunc. But I would appreciate to be wrong here. ;-)"
Im not sure about svn, but I guess it is possible:
- checkout cws
- merge trunk into cws (resync to trunk HEAD)
- resolve conflicts
- commit to cws
- svn switch --relocate to trunk
- commit to trunk
One has to take special care about added/deleted/moved files, but we already have to have a close watch over those with svn.

With Mercurial it would look like this (This would integrate the changes from the cws into the trunk without importing all the cws history - pretty much the same behavior we have with svn on integration now):
- clone cws repo
- pull from trunk repo
- merge trunk into cws (resync to trunk HEAD)
- commit (and push to public cws repo)
- exchange the .hg directory in the repo with one from a trunk repo
- commit (and push to public trunk repo)

Not sure how that would look like with git, but I guess it would be no big difference from mercurial.

Posted by Bjoern Michaelsen on March 19, 2009 at 12:55 PM CET #

Bjoern Michaelsen said:

Just a short correction to my comment at 10:34 AM CET: I meant "shallow clones" not "partial clones".

Posted by Bjoern Michaelsen on March 19, 2009 at 01:18 PM CET #

Post a Comment:
Comments are closed for this entry.
« New: OOo-DEV 3.1... | Main | QUASTe: Easier verif... » GullFOSS