My Launchpad Development Workflow Warts : HALP!

November 19, 2009

A few times during UDS, we've talked about setting up a Launchpad development environment. I think it'd be great if the community really got involved in making Launchpad better, and I don't think I'm alone on the Launchpad team thinking that. However, setting up the development environment is kinda scary. Among other things, the script that sets up a Launchpad development environment (rocketfuel-setup), deletes all postgres databases to set up its own, edits yours /etc/hosts and your apache configs, and adds some PPAs that may interfere with your system packages (although it's been a while since it did that to me.)

To combat this, and allow me to fart around on my system on the weekends without breaking my environment, I do all my development in chroot environment. This means Launchpad can eat my system, and my system can't eat my Launchpad. I've been working this way for almost 8 months now, and have found it to be much better than sharing spaces.

The one thing that I have had a problem with is the relationship between my desktop and the chroot. I figured that maybe I'd reach out to the community and see if they can recommend a path for putting some Compound W for some development warts I have.

When I start up my computer to work on Launchpad, I open two terminals and a gvim. Both terminals become chroot terminals by my typing schroot which then promptly get navigated to have my current branch's tree as the working directory. This means that these terminals are now utterly useless for anything but work in the chroot, which can be good for focus, but if I need to do anything else, I have to open another terminal to do it. Having lots of terminal windows open is generally a bad thing for focus as well.

Also, I run lots of Windmill tests. Windmill needs a browser, which needs an X display. I've been using Xnest -ac :1 &!; metacity &! outside of the chroot, and then setting export DISPLAY=:1 in my chroot in order to get X forwarded over. This is really sub-optimal, since it's a lot of crap to set up to run Windmill (which in and of itself is a lot of other crap to set up).

I would love nothing more than to modify rocketfuel-setup to be created in a chroot if I could find an easy way to work outside the chroot and just forward certain commands over to the chroot. I'm sure some server sysadmin has a great method for doing this. If you have a solution, a bribe can be arranged. If you're at UDS right now, even better.

Comments | Tagged as: launchpad

Launchpad Under AGPLv3

July 20, 2009

Launchpad is open source today. All of Launchpad is open source as well, where it was before announced that some parts would remain proprietary. It's all there.

This makes me happy. That is all.

Comments | Tagged as: launchpad

Tarmac 0.2 released!

July 11, 2009

The Tarmac team is more than pleased to announce the release of Tarmac 0.2. Tarmac has received many improvements and features in the last few months, and, thanks to the efforts of many who sprinted yesterday, Tarmac 0.2 has had some great polish applied to it as well.

Tarmac now supports the ability to run a command on merge previous to commit, and, should that command fail, reverts the change and alerts the user to the failure. Tarmac supports this through its new plugin system. Tarmac 0.2 is also packaged with a Commit Message Template plugin to enforce a standard commit message on merge, and a plugin for notifying the CIA.vc service of new merges.

Other notable features include a web interface for checking the status of Tarmac, improved conflict handling, updated documentation and preliminary Windows support. Also, Tarmac now properly attributes the author of the merge commit to the author of the last merged revision. For a list of all bugs fixed, see the Tarmac 0.2 bug list.

Comments | Tagged as: launchpad tarmac

Why Tarmac Won't Ever Be Part Of Launchpad

July 8, 2009

So I counted my fingers and toes (including thumbs) and I still can't count how many people have asked me about the possibility of having the functionality of Tarmac (automatic merging) built into Launchpad. The short answer is "No." The long answer is also "No."

There are many reasons for this. The first one I can come up with is the test suite. Sure, you can automate the merging of branches, but c'mon, what's the point of automating it if it's just going to propagate breakage? So the running of tests is relatively essential in automated merging. Elliot got a patch into Tarmac the day after 0.1 to do just this, and I have recently refactored it to work as a plugin. So, for instance, Entertainer can have approved merges, and Tarmac will check out a fresh copy trunk, merge in the branch, and run the tests. If the tests pass, it lands, if not, then the test output is added to the merge proposal. The problem with this is that many test suites take a very long time to run. Others may be quite CPU intensive. As one can imagine, that can require a lot of hardware.

Now, think of test suite you're running. Who wrote it? Not the Launchpad folk. PQM has put a lot of effort into making sure that the tests are run in a sandbox, and not in an environment that would have security implications. In fact, I've put a lot of thought into how to run the tests in a chroot environment for the Tarmac instances I maintain. This is quite a complicated setup.

Lastly, you may need a build environment. Maybe you're working in Windows, or you need a database, etc. These things are pretty specific to an environment. The possibilities are endless. This also has huge hardware implications.

Bottom line: Provide your own test environment, run Tarmac on a cron, make your development team happy.

Side note: I'd love to see if Tarmac would run on Windows. I don't have any Windows machines around, so (for bonus points) would someone please volunteer to try it there? Update: John Meinel was awesome enough to hack on Tarmac enough to get it running on Windows, and the branches have been submitted for review. This means that Tarmac 0.2 will have Windows compatibility as well. Woot!

Comments | Tagged as: launchpad tarmac

Tarmac sprint this Friday (10 Jul 2009)

July 7, 2009

Want to hack on Tarmac? Want to learn how to use the Launchpad API (or want to use your existing knowledge)? Want to learn to use bzr's functionality programmatically? There is a Tarmac mini-sprint scheduled for Friday, 10 Jul 2009 in #tarmac on Freenode. Tarmac 0.2 will also be released this weekend based on the work completed on Tarmac on Friday.

Also, if you'd like to know more about Tarmac, or would like to participate, please join the Tarmac Launchpad group and subscribe to the mailing list.


Fun With The Launchpad API : Software Licenses

April 26, 2009
Launchpad License Breakdowns

In a nod to Michael Bernstein's F/OSS License App for Web App Wednesday, I threw together some code that does a similar thing for Launchpad. Things rolled downhill from there to do some other really fun things, but I thought I'd stop and blog about the first result before hacking on the rest of the data.

The above image is the result of this hacking. I used the Google Charts API to create the pie chart. It's obvious that GPLv2 is the most popular license, being that 35% of all Launchpad projects are licensed that way.


bzr-autoreview - Yet Another Launchpad Review Method

March 9, 2009

I'm pleased to announce the first version of bzr-autoreview, a Bazaar plugin for automating Launchpad merge proposal reviews.

The concept is simple. Go to your local mirror of a branch on Launchpad, and simply type bzr autoreview. The plugin will do the rest. It finds every merge proposal against your public branch that doesn't yet have a review, gives you an editor pre-populated with the diff, and then, after your review, allows you to also vote.

I have many planned features, but I've been trying this year to release code instead of just writing it. The code's a mess because I was spanning hemispheres while writing it. I plan on cleaning it up in the next few days and releasing again.

Please see the README. You can download the tarball or get the branch. If you're really ambitious, I'd appreciate any patches, so please see the HACKING file. A special thanks goes to Elliot for giving me the idea in the first place.


Introducing Tarmac - The Launchpad Branch Lander

March 4, 2009

I'd like to announce the release of Tarmac, the robotic landing bot for Launchpad. The idea is simple. You have a development focus branch that constantly needs to have branches landed on it, but you're too busy writing your own code to manually land them in trunk. Tarmac takes the difficulty out of this by checking your development focus branch for approved merge proposals, and merging them automatically.

You can read the README file, grab the Tarmac 0.1 tarball or just get the bzr branch with bzr branch lp:tarmac. This first release is just a little more than "the simplest thing that could possibly work" because I wasn't exactly sure what features were the most important to other potential users. This means feature requests and patches are most certainly welcome (it's why I use Launchpad). Please feel free to file bugs with the features you'd like to see.

Tarmac is licensed under the GPLv3.


More Advanced Bazaar Concepts

January 23, 2009

So I had this idea for yet another Bazaar post about some more advanced topics, and concepts that my workflow has eventually evolved to incorporate. Among these concepts are shared repositories, lightweight checkouts, and branches with no working trees. I'll do my best to explain these concepts, and why I find them to be of benefit, but if there are questions, please feel free to leave a comment and I'll do my best to answer those questions.

Shared repositories

If you work on a project on a regular basis, you really need to create a shared repository for your project. The basic idea of a shared repository is that you keep all your revisions in a pool together. For instance, you have a local mirror of trunk, and since you share those revisions among your branches, when you create a branch from that local mirror, there's very little overhead to creating the branch, since the revisions don't need to be copied.

I keep my various shared repositories in a folder called ~/Projects/repos with each project having its own folders there. When I want to hack on a new project, like, say, Loggerhead, I have the following process:

$ mkdir ~/Projects/repos/loggerhead
$ cd ~/Projects/repos/loggerhead
$ bzr init-repo --no-trees .
$ bzr branch lp:loggerhead

Now, every time I branch from ~/Projects/repos/loggerhead/loggerhead into ~/Projects/repos/loggerhead/, I don't actually get any new revisions, just a new branch using the old revisions. I don't think this really saves on space too much, but it makes the overhead of branching much cheaper.

But wait! Why --no-trees? How the heck do you work if you don't have a working tree? Ah, so now we move on to my next point.

Lightweight checkouts

So I have two branches in ~/Projects/repos/loggerhead, the mirror of trunk, and a feature branch we just created. Neither that feature branch nor the local trunk have anything in them except the .bzr folder. No working tree. So let's back up a dir to ~/Projects where I keep my working trees. So now I'm going to create a folder to house my Loggerhead working trees.

$ mkdir ~/Projects/loggerhead
$ cd ~/Projects/loggerhead
$ bzr checkout --lightweight ~/Projects/repos/loggerhead/loggerhead
$ bzr checkout --lightweight ~/Projects/repos/loggerhead/feature-branch

Now I have working trees to work with. When I commit, those committed revisions go back to my branch, and in effect, to my shared repository. Now my working tree is completely separate from the branch itself. I can easily delete the working tree when I'm done with it without losing the branch, and when I decide to delete the branch, I still have those revisions hanging around (in most cases, they've also been merged into trunk).

I can also treat that lightweight checkout of the trunk mirror to branch from, merge, commit, etc. as if it was the branch itself, but now there is a clear separation between where I work and where I store my revision data.

Using cbranch

So we've got two bzr commands to type, the branch command and the lightweight checkout command. If you use bzrtools you can do this in one easy step by setting a few bzr settings in your ~/.bazaar/locations.conf This is what I have set for my directory structure/layout:

[/home/rockstar/Projects]
cbranch_target = /home/rockstar/Projects/repos
cbranch_target:policy = appendpath

I also want to set an alias in ~/.bazaar/bazaar.conf to give me lightweight checkouts.

[ALIASES]
cbranch = cbranch --lightweight

Now, when I'm ~/Projects/loggerhead I can just bzr cbranch loggerhead new-feature-branch and bzr will automatically create a branch in ~/Projects/repos/loggerhead and then create the lightweight checkout in ~/Projects/loggerhead bound to that branch.


Launchpad and Bazaar : How To Do It

January 23, 2009

Martin Albisetti and I have just hosted a session for Ubuntu Developer Week entitled "Launchpad and Bazaar : How to do it" The logs from this session can be found here. Below are the (now cleaned up) notes that I wrote down while preparing for it.

The importance of bzr whoami

One of the really important things that lots of people forget is to start off with is setting your name is Bazaar. This can be done really easily by doing bzr whoami "Your Name <email@example.com>" It's important that you set this properly, or your revisions aren't going to get your name on them. The email address you set here also needs to be an email that Launchpad knows about (a confirmed address). This way, you get the karma for the revisions, and revision listings in a branch page will link back to your profile.

Set a Development Focus

Because we're talking about a distributed version control system, there are going to be many branches in your project. It's important to point people glancing at your project to the "trunk" of your project, where all the new fun development it. Once you've pushed up your first branch, it's good to set it as the development focus. Now, new contributors will know where to branch from when they want to, well, contribute.

Setting a development focus also tells Launchpad itself what branch is your main branch. For instance, because I have the development focus of Entertainer to lp:~entertainer-releases/entertainer/trunk, every time I do a bzr branch lp:entertainer Launchpad knows to give me the correct branch. It's an alias that can save you a lot of time. I often find myself doing bzr branch lp:randomproject just to get the most up to date source.

A quick note about series branches. When you decide to release your software (because you're releasing software often, right?), you'll want to keep a branch of that version. That's what's called a series branch. It'll have point release milestones attached, and when you release those point releases, they'll come out of this branch. The development focus is a glorified series branch. So, in effect, if you create a series branch called myproject-1.1 in the myproject project, you can use bzr branch lp:myproject/myproject-1.1 to get your myproject-1.1 series branch.

Since branches are owned by people, you might want to consider creating a team that owns your development focus, and adding people to that team. This keeps your project moving when you go on vacation for two months. It's just a good idea.

Workflow decisions

Now, you need to decide what your workflow is like. Some projects only have one person working on them. If that's your project, then all you need is one branch, commit, push to Launchpad. That's relatively simple. I do this with a few personal projects.

If your project has more than one person, then you've got to make other arrangements. What I suggest is the concept of feature branches. Create a branch specifically for a feature or a bugfix, hack it all together, and merge it into your trunk. This is the optimal solution, and, as far as I'm concerned, the only solution.

It's a good idea to see my former post on good Launchpad/Bazaar settings This will take the hard work out of pushing, especially with feature branches. What I usually do is keep a mirror of the development focus branch on my system (with a cron job to update it at regular intervals). When I start a new branch, I branch from that mirror, and start hacking. I try to push at normal intervals, but sometimes I just space that.

Merge Proposals and Code Reviews

So now you're creating feature branches, because, well, that's the workflow you've chosen. You've written your tests (because you tested first, right?), your feature is ready to land (or so you think). At this point, you should propose it for merging into your development focus branch. No matter how your project handles reviews, it's good that someone at least blesses the revisions that are to proposed to land in trunk.

So your branch goes through the review process, comments are made, and eventually, all required reviewers approve of your changes. Now it's time to actually get your branch landed. Someone in the team that owns your development focus will need to merge your branch into their local copy of the "trunk" and then push it up. Once that's happened, Launchpad will mark the merge proposal and your feature branch is also marked as merge. Go hack on another branch!

For Reviewers

So there are a few different pages that help to know about if you're a reviewer for a project. The first is the +activereviews page. If I navigate over to the Entertainer active reviews page you'll see that I have some landing work to do. This also applies to people. If I navigate to my own active reviews page you can see all the branches that I have submitted for review.

What if, however, I want to see all the reviews I've done for someone else's branch, and what the status of those branches is. Maybe I set my review vote to "Needs Fixing" and now I need to see if that fixing has occurred. That's when you'll want to check out your +requestedreviews page (as of this writing, currently only available in beta, due out in a week). If we go take a look at mine, you'll see that I have some work to do.

Bazaar branch formats

As Bazaar features get implemented, new formats become a result (so as not to risk breaking old, tried and true formats). As of Bazaar 1.6, a feature called "stacking" was introduced, that allowed bzr branches to only have the history specific to that branch, and just keep a reference to the trunk branch. This is great if you have LOTS of history for your project, and pushing seems to take forever. If you upgrade your branch to format 1.6 by doing bzr upgrade --format=1.6 you'll now be able to push stacked branches.

If you're using the Bazaar PPA (and you really should be using it), you'll have a 1.9 format available. It's faster, supports stacking, and is awesome all around. It's not the default format, so you'll have to either create your branch with bzr init --format=1.9 or bzr upgrade --format=1.9.

Import branches

Distributed version control drastically reduces the barrier to entry for hacking on a project. With a VCS like CVS or Subversion, the project usually works as a meritocracy, and so you have to "prove yourself" before you get access. What if a project you really want to hack on won't give you commit access to their SVN/CVS repo? Create a project in lp, and import the the SVN or CVS branch into a bazaar branch. Then all you need do is branch from that branch, and hack on. When you're done, you diff between the current import and your branch, and send that in as a patch to the project itself. The difference is that you have a versioned copy of the making of that patch, instead of having a single checkout.

Comments and suggestions are welcome. I'll do my best to keep this post up to date with new things, and once it's baked, I'll publish to a wiki somewhere.


Launchpad Code Reviews Without A Browser

January 15, 2009

I do a lot of code review in Launchpad, use a lot of the code features, and have worked out some pretty good methods of making this simple and easy to work with. I thought, in lieu of my last post, and the ones I'm planning for the near future, it'd be good to detail some of the things that I do to make my workflow.

Launchpad's web UI is slow. I'll admit it. We're working on doing some really great things to speed it up, but frankly, all web applications are. You've got to load pages, parse javascript, etc. In fact, most things you shouldn't even have to wait around for. They are things that should require minimal attention for much of the time, and often things that are "fire and forget."

So let's build off the config settings I've already blogged about. If you haven't read that article yet, I highly suggest you go back and read it, or you're gonna get really confused really quick.

Creating a merge proposal with email

Looking back on the general Launchpad branch configs we used, we need to add one more line so that Bazaar knows the email address that Bazaar's "bundles" should go to. So, let's edit our ~/.bazaar/locations.conf to show the following:

[/home/rockstar/Projects/repos]
push_location = lp:~rockstar/
push_location:policy = appendpath
public_branch = lp:~rockstar/
public_branch:policy = appendpath
submit_to = merge@code.launchpad.net

The line added is the submit_to line. This means that Bazaar is going to send its bundles to merge@code.launchpad.net. This is the email address that parses the bundle, and derives the the source branch (the branch to be merged) and the target branch (the branch to merge into).

Now we need to specify the submit branch. This requires some specific configs for each project, so we'll need to add a new section. For this example, we're going to use Entertainer since Bazaar's development doesn't use Launchpad for it's review process. I'm going to add another section specific to Entertainer.

# Entertainer
[/home/rockstar/Projects/repos/entertainer]
submit_branch = lp:entertainer

This sets all branches in ~/Projects/entertainer to submit to the branch lp:entertainer which happens to be the current development focus of Entertainer. Note: The target branch MUST be a Launchpad branch. The source branch doesn't really need to be, and Launchpad is smart enought to create a Remote branch (a branch that Launchpad only keeps a reference of).

Finally, we need to tell Bazaar what your preferred email client is. So crack open ~/.bazaar/bazaar.conf and let's add one more line to the [DEFAULT] section.

mail_client = evolution

Wait. You don't want to use evolution to send your email? Well, you can choose between thunderbird, evolution, kmail, thunderbird, mutt, emacsclient (although I don't know how that emacsclient works), or editor. I use editor, but that requires some more config set up (and it's beyond the scope of this post). Also, if you want to use Gmail, see BzrSendWithGmail or use James Henstridge's bzr-imapclient plugin to use GMail to send the merge-directive (see https://lists.ubuntu.com/archives/bazaar/2009q1/051602.html. As of Bazaar 1.11, bzr also now supports claws as a mail_client as well.

Now, hacka hack on your branch, and when it's all ready, make sure it's pushed to Launchpad, and then do bzr send --no-bundle. This will create a bundle and open up your mail client for you to detail what your branch does. Fill that out, and send the email. It'll be processed, and the merge proposal will be created, using the Default Reviewer for the target branch as the reviewer.

Reviewing a branch through email

This is where things get more interesting. Those subscribed to the branch (as branch code reviewers should be) will get an email with the creation of the merge proposal, and an email with the patch (these two emails will be consolidated shortly).

So a reviewer cracks open the email and looks through the patch. They merge the branch into their local mirror of trunk and run the tests (because you have tests for code, right?). The reviewer makes their inline comments to the patch in the email reply. The To: in their reply should be something like mp+1234@code.launchpad.net.

If you (as reviewer) were to send this email now, it'll be parsed as a comment to the merge proposal. What if you want to give an official review vote? What if you want to set the merge proposal status to Approved? This is the clever part. For example, I review a branch and I think it needs to be set to Needs Fixing. Within the email, I would type:

vote needs_fixing

Note the leading space there. It's important. Now, GPG sign your email, and send it off. You've just given your vote. After someone decides to fix the issues that arose from your review, you can reply to the response email with:

vote approve
status approved

Send this with a GPG signed email, and you've updated the merge proposal to Approved as well as "voted" approve. Now, if you can merge the branch, merge it, otherwise, nudge someone who can.

Hooray! You've successfully navigated the hairy process of code review without having to hassle with the web UI at all. Now THAT'S a service worth working with. There are similar commands to work with bugs as well, and by learning to use these commands, you can create a workflow with Launchpad that works best for you.

Update: Thanks to some great comments, I've noted some of extras.

Comments | Tagged as: bzr launchpad

Using Bazaar with Launchpad : Making Pushing Easy

January 13, 2009

Many of Bazaar's dirty little secrets are hidden away in options you can set in ~/.bazaar/bazaar.conf and ~/.bazaar/locations.conf. Here are some fun things to configure to streamline your hacking with Launchpad and with other projects.

First, some background. I have a rather detailed and involved setup and workflow (which I'll detail later), so I'm going to do my best to make this as simple as possible. For the sake of this example, I'm going to lay out my folders this way:

~/
~/Projects
~/Projects/bzr
~/Projects/bzr/bzr.dev
~/Projects/bzr/foo
~/Projects/bzr/bar
~/Projects/bzr/baz
~/Projects/entertainer
~/Projects/entertainer/entertainer
~/Projects/+junk
~/Projects/private
~/Projects/private/ironlion

So I have put all my branches into a ~/Projects directory, inside a dir each for various projects I work on that are hosted on Launchpad(bzr and Entertainer for the sake of this example). I also have two other folders, one called +junk (for junk branches), a folder called private which, as you may have guessed, will be for things I don't push to Launchpad (like, say, for instance, the source for this blog, which contains db passwords all sorts of fun info... :)

To start out, let's look at my ~/.bazaar/bazaar.conf:

[DEFAULT]
email = Paul Hummer <paul@myemaildomain.com>
create_signatures = always
gpg_signing_command = /usr/bin/gpg
launchpad_username = rockstar

This where you put all the things about your general use of bzr. The email line will usually get set by doing bzr whoami which you should generally run the first time you run bzr, so that bzr knows your name and your email address. If you've ever seen your revisions on Launchpad saying something like rockstar <rockstar@megatron> it's probably because you haven't set your email config line, and so it's taking your user name and host name of the system you're working on (in this case, my system's name is megatron). I've also set my launchpad username. This is also important, and would get set when doing bzr launchpad-login rockstar Confused yet? If so, just skip down to the next block. create_signatures and gpg_signing_command are both to allow me to sign my revisions.

[ALIASES]
cbranch = cbranch --lightweight
ci = commit --strict
diff = diff --diff-options -p
diff-thread = cdiff -r thread:
ll = log --line -r-10..-1
lpsend = send --no-bundle
recentlog = log -r-20..-1 --short
sdiff = cdiff -r submit:
st = status --short
unpushed = missing --mine-only :push

These are my aliases. Think of them like shell aliases. The details you don't have to worry about too much, but when find yourself running the same commands over and over, add them to your aliases.

locations.conf is where all the fun happens. It's what tells bzr, based on the location of the branch, where to push, where to submit, etc. So let's start with a generic blanket statement that'll be used for all projects pushed to Launchpad. So let's start with:

[/home/rockstar/Projects]
push_location = lp:~rockstar/
push_location:policy = appendpath
public_branch = lp:~rockstar/
public_branch:policy = appendpath

The secret here is in the appendpath. Basically, bzr looks at the relationship of the current branch, say ~/Projects/entertainer/entertainer to this config section, and, using the appendpath policy, decides it needs to be pushed to lp:/~rockstar/entertainer/entertainer Hooray! Now, if I create a new branch at ~/Projects/entertainer/fix-bug-123465 and just call bzr push, bzr is smart enough to push it to lp:~rockstar/entertainer/fix-bug-123456 This even works with junk branches (branches that aren't attached to a project), provided you just put your branch in the +junk folder.

But wait! What if I don't want to push to Launchpad? I first ask "Why don't you? It's so great!" :) As locations.conf stands now, if you put something in your private area, Launchpad is going to tell you there is no project named private when yo utry to push. Well, let's fix that.

[/home/rockstar/Projects/private]
push_location = bzr+ssh://bzr.eventuallyanyway.com/code/
push_location:policy = appendpath
public_branch = bzr+ssh://bzr.eventuallyanyway.com/code/
public_branch:policy = appendpath

As you can see, I push my private branches to bzr.eventuallyanyway.com/code. It uses the same tricks as I showed before, so the same idea can be assumed.

It's important that I point out that there's no order required in how these config sections get put into locations.conf because bzr is smart enough to find the most specific config and use it.

This concludes this session of bzr-lp hackery. Comments welcome.

Comments | Tagged as: bzr launchpad

Also, some similarly tagged posts from the archives...