Death or Glory vs. Continuous Integration
But I believe in this and it's been tested by research
Thanks to Norbert's efforts, the LibreOffice project now has a Jenkins setup that not only gives us visibility on how healthy our master branch is, with the results being reported to the ESC regularly: In addition it allows everyone easily testing commits and branches on all major LibreOffice platforms (Linux, OS X, Windows) just by uploading a change to gerrit. Doing so is really easy once you are set up:
./logerrit submit # a little helper script in our repo git push logerrit HEAD:refs/for/master # alternative: plain old git git review # alternative: needs to install the git-review addon
Each of the above commands alone send your work for review and testbuilding to gerrit. The last one needs an additional setup, that is however really helpful and worth it for people working with gerrit from the command-line regulary.
So, what if you have a branch that you want to testbuild? Well, just pushing the branch to gerrit as suggested above still works: gerrit then will create a change for every commit, mark them as depending on each other and testbuild every commit. This is great for a small branch of a handful of commits, but will be annoying and somewhat wasteful for a branch with more than 10-15 commits. In the latter case you might not want a manual review for each commit and also not occupy our builders for each of them. So what's the alternative, if you have a branch ${mybranch}
and want to at least test the final commit to build fine everywhere?
git checkout -b ${mybranch}-ci ${mybranch} # switch to branch ${mybranch}-ci git rebase -i remotes/logerrit/master # rebase the branch on master interactively
Now your favourite editor comes up showing the commits of the branch. As your favourite editor will be vim, you can then type:
:2,$s/^pick/s/ | x
To squash all the commits of the branch into one commit. Then do:
git checkout - # go back to whatever branch we where on before git push logerrit ${mybranch}-ci:refs/for/master # push squashed branch to gerrit for testbuilding git branch -D ${mybranch}-ci # optional: delete squashed branch locally
Now only wait for the builder on Jenkins to report back. This allowed me to find out that our compiler on OS X didnt think of this new struct as a POD-type, while our compilers on Linux and Windows where fine with it (see: "Why does C++ require a user-provided default constructor to default-construct a const object?" for the gory details). Testbuilding on gerrit allowed me to fix this before pushing something broken on a platform to master, which would have spoiled the nifty ability to test your commit before pushing for everyone else: Duly testing your commit on gerrit only to find that the master you build upon was broken by someone else on some platform is not fun.
The above allows you to ensure the end of your branch builds fine on all platforms. But what about the intermediate commits and our test-suites? Well, you can test that each and every commit passes tests quite easily locally:
git rebase -i remotes/logerrit/master --exec 'make check'
This rebases your branch on master (even if its already up to date) and builds and runs all the tests on each commit along the way. In case there is a test breakage, git stops and lets you fix things (just like with traditional troubles on rebases like changes not applying cleanly).
Note: gerrit will close the squashed branch change if you push the branch to master: The squashed commit message ends with the Change-Id of the final commit of the branch. So once that commit is pushed, the gerrit closes the review for the squashed change.
Another note: If the above git commands are too verbose for you (they are for me), consider using gitsh and aliases. Combined they help quite a lot in reducing redundant typing when working with git.
Originally published on 2015-05-26 08:39:20 on wordpress.