CI and Google App Engine, or “How to force your way in”

Feb 15, 2010

If you’re the type that skips titles, we’re using Google App Engine in our project, mostly because it’s there.

I jest. We’re using it because it’s scalable and high performance and reliable and whatever other reason you can think of that will keep me from having a boring debate on the difference between Google and Amazon and Microsoft.

Along with Google App Engine, we’re also using TeamCity for our continuous integration server. And generally speaking, these are two very disparate topics. I.e. I’m not finding App Engine to be very CI-friendly.

Deploying to App Engine from Eclipse or IntelliJ is dead simple. There are plug-ins that manage it and all you do is provide credentials. Doing it from the command line is not too bad. There’s a console utility, appcfg, that lets you upload to App Engine.

So on the surface, it appears CI and App Engine play nicely. But there are a couple of quirks that don’t sit well. We’ll start with the Ant tasks I’m using from the CI server:

The first two targets are nearly identical. In App Engine projects, there is an XML file that contains the config

Side note: Versions in App Engine either can’t start with a capital or can’t contain capital letters altogether. This was one of my more aggravating annoyances because it ain’t ‘zactly trivial to make a string lowercase in Ant. I had to import a whole new Ant add-on, Antelope, to do it. Hence the <stringutil> task in setAppEngineVersionToDayOfWeek.

uration for uploading to App Engine. One of the tags is <version /> which is the name of the version in App Engine. These two targets will configure the version name to be the name of the day of the week, and the current date (in yyyy-MM-dd format) respectively.

The update target does the actual work of executing appcfg to upload to App Engine. In TeamCity, I have two build configurations. One executes nightly and calls the setAppEngineVersionToDayOfWeek target followed by the update target. The second configuration executes weekly and calls setAppEngineVersionToCurrentDate, then update.

The first crack in the veneer appears in the update target. App Engine comes with an Ant task, <appcfg>. But it requires you to be logged in and as far as I can tell, you can’t pass in that info to the <appcfg> task. So the target calls AppCfg using the <java> task and with a hard-coded email and password.

There’s an alternative. You can log into the CI server, run appcfg from the command line, and provide your email and password. This will be cached for 24 hours. As long as you hit App Engine at least once in 24 hours, your credentials will remain cached.

Problem with that is that you have to provide the credentials while logged in with the user account that runs the TeamCity agent, which in our case is the local system account. The other problem is that it’s a nightly build. Which means it runs roughly every 24 hours. Didn’t take long for the credentials to get evicted from the cache. So we created a special account so that we could hard-code the credentials into the build file (because, y’know, no one wanted their e-mail addresses and passwords stored in the version control system).

Other suggestions are included here. I went with the least resistance approach because frankly, a nighly build on a team of two in a start-up company shouldn’t require a custom Ant task.

The next issue we hit is that App Engine has a limit of ten versions per application. Put your fingers down, I’ll do the math for you. It means that after one week of nightly builds, that leaves three slots available for weekly builds. With none left over for others.

Ideally, I’d like to keep maybe only the last three nightly builds and possibly the last three weekly builds. But as far as I can tell, there’s no automated way to delete versions from App Engine. So this has forced us to examine exactly what we want to accomplish with our automated builds in App Engine.

Finally, if anyone knows how to secure versions of the app from prying eyes, I’d love to see that feature implemented as well. You need to log in to administer the application on App Engine along with all the versions. But as far as I’ve been able to figure out, if you know the URL to a version of the app, it’s available to the public. Which has stepped up the priority of our “Customer should be able to log in” story.