Tag: idevblogaday
Setting up an Automated Build in an iOS environment – part 5
by George on Jun.19, 2011, under Coding, Project Management
I’ve recently been trying out Testflight as a method for getting beta builds out to testers. Testflight handles a number of things for you – over the air distribution of builds, notification e-mails, download stats and more. It’s a great system, but my first thought when I started experimenting with it was: “Can I incorporate it into my build system?” Fortunately the answer is yes, in fact it’s dead easy. Let’s see how it’s done…
Setting up…
I won’t go into all the details of setting up a Testflight account, it’s fairly well covered on the site. What you will need to do is set up one or more ‘teams’ for beta testing. Once you’ve done this, it’s time to investigate Testflight’s upload API.
Automated uploading
Most pages on the Testflight site have a set of links at the bottom, one of which is ‘Upload API’. This page gives details of how you can upload a build programmatically. You’ll need to find a few details – an api token and a team token. Both of these can be found by following links off the Upload API page. Once you’ve got these, we can use curl to handle the communication with Testflight .com:
curl http://testflightapp.com/api/builds.json -F file=@yourapp.ipa -F api_token='your_api_token' -F team_token='your_team_token' -F notes='This build was uploaded via the upload API' -F notify=True -F distribution_lists='Your Team Name'
And that’s all there is to it! I’d recommend trying this from the command line until you’re happy that builds are uploading correctly, then simply drop this command line into your build system as a final build step.
I’ve been using this for a while and it works well. The first time you create a build, your testers receive an email – if they read the email on their device, they’ll get instructions for setting up Testflight on their iDevice. Having done this once it becomes a one click process for testers to get new builds. Not only that, but you as the team leader will know who has downloaded the build, and on what device!
Just a few of issues…
Overall I’m really happy with Testflight as a system. There are some things to be aware of though:
- Testflight only works on newer devices / OS versions (4.0 and later, I believe).
- I’m not clever enough to interpret the results of curl to determine if an upload fails, so currently I get a ‘build succeeded’ even if the upload fails. If anyone can offer some advice on how to do this, I’d appreciate it.
I hope you find this useful – I know I do – one click to go from Source Control to having a new build in tester’s hands? Magic.
Thoughts for my younger self
by George on Apr.11, 2011, under Uncategorized
At a mobile devs meetup this week, it became apparent that I’m now one of the old guard. I’ve always been someone who enjoys passing on useful information to others. Teaching a game design course for University students also makes me realise how much they have to learn, how much I take for granted after 15 or so years in the industry.

If I had the chance, what would I tell my younger self? What has worked out well for me and what would I do differently? Here’s a few of the things I came up with. What would you add?
Failure is not the thing to be afraid of
Some of the world’s most successful people have had massive, public failures – but it hasn’t stopped them. Yes failure is painful and embarrassing. But it’s also a great teacher, making us wiser and stronger. Perhaps more importantly though, if we never fail, then we’re not taking any risks. Tackling challenges that may be too much for you are where we get a chance to excel and surprise ourself and others.
Always have a backup plan
I have spent many years working in live television, covering sports events. It was not uncommon to be adding new features to the software on site the night before the event. I’ve arrived in foreign countries with broken computers. I’ve turned up at events and lost a day because no one knew we were coming and so we had no space to work, no power to work with. I’ve had machines die at 2am the day before we’re live. This teaches you a few of things:
- Some deadlines simply can not move, so you must be adaptable.
- Always have a backup option. You may not get as much done as you hoped.
- Worry early so that you don’t have to panic late.
Plan your work to try and deliver in an iterative fashion. Planning to deliver everything at once, on deadline is just plain stupid. Working without source control is just plain stupid.
There is no better time than now
It’s taken me far too many years to realise that my dream is to work for myself, on the projects I want to work on. I’ve learnt a lot working for other people and I enjoy being part of a team. But after a while the urge to show the world what you can do, to craft something that’s all yours becomes very strong.
My point is this. It’s hard to do that once you have a mortgage and a family (and a dog, cat, rabbit, guinea pigs, chickens and goldfish). When you’re young you have a great opportunity to move quickly and try things out. Also, we live in an age where it’s never been easier to get your product in front of customers – make the most of it.
You will be wrong, often
There’s no shame in being wrong. It happens. Accept that it happens and move on. Keep your ego in check and always keep in mind that the people you work with probably aren’t stupid either. Often arguments are caused because two people are so caught up in their own opinion that they forget they’re on the same team, trying to achieve the same goal.
Mistakes will happen and you don’t always make the best choices. Learn to prototype ideas quickly. Learn to leave a buffer in a project plan to handle the unexpected. Tackle the biggest challenges first to avoid surprises.
Always learn more
Learn new languages, frameworks and techniques. Read iDevBlogADay and altDevBlogADay! Challenge yourself not to stagnate. If you find yourself criticising another platform, maybe it’s time to dive in and learn more about it. One thing I can promise you is that the work environment and tools you use today won’t be the ones you use in 10 or 20 years. Don’t end up a dinosaur.
There are difficult or petty people in this world – deal with it
Working with others is hard. It’s at least as hard as the technical challenges you deal with, so put some effort into being good at it. Working so-operatively is a skill you can develop. Some people are harder to work with than others. You might be That Guy. Learn how to communicate clearly and without letting your emotions get in the way. Work on solutions, not problems. Be polite and always treat people with respect – especially the difficult ones. You never know whio you’ll be working with or depending on in a couple of years. Life is funny that way.
There’s no silver bullet here, it’s hard work but the effort will pay off, I promise you.
You are so much more than a coder
This is the big one. Don’t believe that you’re just the tech guy. Get out of your ivory tower and learn about what your colleagues do. Know enough about Photoshop to take images from artists and get them into a usable form. Understand how artists build models so that you can teach them (in their own terms) what can and can’t be done inside a game engine. Talk to designers about flow and layout, and why moving that text two pixels to the left is so important.
Understand enough about business to know the effort that goes into giving you a pay cheque each fortnight. Practice estimating tasks and tracking time spent to better understand what you can or can’t achieve in a given time frame. Write documentation or reports to share knowledge with clients or customers. Write a blog! Speak in public.
Not only will this make you a better person, but others will enjoy working with you and helping you out when needed. And when you make that transition to management, or all-in-one Indie developer, you’ll be much better prepared.
And one more thing…
Enjoy yourself. Work hard and treat difficult problems as a fun challenge to crack. Only boring people get bored.
Setting up an Automated Build in an iOS environment – part 4
by George on Oct.24, 2010, under Coding, Project Management, Setting up
I thought it was about time to wrap up this series of articles by showing a fully working example of a build. I’ve been using Hudson both for my private work and in my day job for the last couple of months now. In that time it has save me a lot of time and effort producing AdHoc builds (now a one click process), and also occasionally catches me when I fail to commit new files to SVN. Setup is far simpler than any other CC tool I’ve used, so I’d encourage you to have a go!
The story so far…
For convenience, here’s an index for the whole series.
- Part One, Overview of what an automated build is, and why it’s so useful.
- Part Two, setting up a basic build.
- Part Three, automatically versioning and tagging your project.
- Part Four, this article. An example of a complete, working build.
Running all the time
One thing you want to set up with your build is to have it running all the time in the background. I found this very helpful article by Jérôme Renard that covers a useful technique. Read the comments, they’re very handy too! In an ideal world, Hudson would run happily under all user logins. And in fact the comments in Jérôme’s article describe how this can be done. Unfortunately, when it comes to iOS development, the code signing that is done on AdHoc and Distribution builds requires various certificates etc to be present in the user’s keychain. Setting these up for all users is a pain that keeps on hurting, especially every time you need to update a profile – when you add a new device, for example.
My advice is to just set up Hudson to run under a single user account – either your own developer account, or a special ‘build machine’ account if you have a dedicated computer available.
Hudson-wide setup
Hudson has a number of settings that can be applied to most or all projects. By following the links to Manage Hudson | Configure System, you can set things such as non-standard paths for source control, default email setup and so on. In my case, it’s a place to set up email defaults and twitter settings:

You’ll note that I’ve had to set up a non-standard port for email, and that I’ve added my email address as the system admin – if anything funny happens, Hudson will let me know through this address. While it’s possible to set these on a per project basis, doing it here once just makes sense.
One more thing. When I was talking about setting up a build from scratch, I’d typically use the ‘Build a free-style software project’ option when setting up a new job. Once you have a working build, the ‘Copy existing job’ option becomes very useful, and is a huge time saver. Typically a new build can be up and running in the five minutes it takes to change a few path variables.
The build job itself
OK, so let’s look at the setup for the actual build. First of all, version control:

There’s nothing particularly unusual here. I nominate the folder to check out the code into (‘Acorn Money’). This is not necessary, but feels a little tidier to me. The main thing to note is that I don’t trust an update and build here – an automated build should always be completely clean. While Hudson doesn’t offer this out of the box, it does have the ‘Revert’ option to ensure no modified files are included in the build. If anyone knows of a way to force Hudson to wipe and fetch the project clean from version control each time, let me know, I’d love to know how to do it.

So, no build triggers here. This is because I want to generate an AdHoc build on an ‘as required’ basis. Hudson is running on my MacBook, so the last thing I want is scheduled builds kicking off while I’m working. The ‘Poll SCM’ option is handy for Continuous Integration, while the ‘Build periodically’ option is useful for nightly builds when the machine is otherwise idle.
Right, let’s look at the guts of it now, the shell scripts that do the actual building. I use several scripts, separated into logical chunks. They could all be run in a single script, but I prefer the separation here – each script has a singular purpose. First up, we increment our build number and tag the code in SVN (see part three of this series):
cd AcornMoney agvtool -usesvn bump -all agvtool -usesvn tag -baseurlfortag http://acornsvn.no-ip.org:808/acornheroes/svn/AcornMoney/tags cd ..
Next, the easy part is actually building the code, using an AdHoc configuration:
cd AcornMoney xcodebuild -project AcornMoney.xcodeproj -target AcornMoney -configuration AdHoc cd ..
For setting up a Distribution or AdHoc configuration, I generally refer to this cheat sheet, which is great for helping me ensure I don’t miss anything. Finally, the fun part. Once a build is successful, wouldn’t it be nice to make it available to all your testers automatically? With the help of DropBox.com, it’s relatively easy. Here’s the script:
cd AcornMoney mkdir Payload cp -rp build/AdHoc-iphoneos/AcornMoney.app Payload/ zip -r AcornMoney.ipa iTunesArtwork Payload rm -rf Payload rm -rf ~/Desktop/Dropbox/Acorn\ Money\ Builds/Latest/* cp AcornMoney.ipa ~/Desktop/Dropbox/Acorn\ Money\ Builds/Latest/ cp ~/Library/MobileDevice/Provisioning\ Profiles/AcornHeroesAdHoc.mobileprovision ~/Desktop/Dropbox/Acorn\ Money\ Builds/Latest/ if [ $BUILD_NUMBER -lt 10 ] then TMP_BUILD_NAME=AcornMoney00$BUILD_NUMBER elif [ $BUILD_NUMBER -lt 100 ] then TMP_BUILD_NAME=AcornMoney0$BUILD_NUMBER else TMP_BUILD_NAME=AcornMoney$BUILD_NUMBER fi mkdir ~/Desktop/Dropbox/Acorn\ Money\ Builds/$TMP_BUILD_NAME cp AcornMoney.ipa ~/Desktop/Dropbox/Acorn\ Money\ Builds/$TMP_BUILD_NAME/ cp ~/Library/MobileDevice/Provisioning\ Profiles/AcornHeroesAdHoc.mobileprovision ~/Desktop/Dropbox/Acorn\ Money\ Builds/$TMP_BUILD_NAME/
It may look like there’s a lot going on here, but most of it is just copying files around. First of all we create an .ipa file (just a zip file with a different extension) which contains our build plus an ‘iTunesArtwork’ png image – otherwise the App icon doesn’t show up in iTunes for an AdHoc build. Next up, we remove any existing ‘Latest’ build folder in our Dropbox folder. Then we create a numbered folder for this build (e.g. AcornMoney08) and copy AcornMoney.ipa into this folder and the latest folder. We also copy the provisioning profile from ‘~/Library/MobileDevice/Provisioning Profiles’, as it will be needed by our testers.
From here, Dropbox takes care of syncing this folder with anyone who is sharing it. Our testers get a notification and a new build delivered to their own PC! The post-build actions are fairly uninteresting, all I have set currently is email notification on a failed build. Even this is slightly overkill, as for an AdHoc build I’m normally sitting at the machine watching the build anyway.
That’s it, a fully working build. With Hudson, it’s possible to set one of these up with just an hour or so tinkering around. Once you have a working build as an example, making a new build can be just a few minutes work. Give it a go and let me know how you get on!
Acorn Money update
For those of you interested in Acorn Money, our money tracking App, we’re still in review. Sam made some significant improvements to the graph rendering code and we felt the best thing to do was to pull the submitted build and re-submit. Unfortunately this sends us back to the end of the queue. Still, we’re hopeful Acorn Money will be available in the next couple of weeks.
This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two new posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.
Tips for Freelancers
by George on Sep.10, 2010, under Project Management
Almost two years ago, I found myself unexpectedly unemployed. Overnight I found myself working as a freelancer – more by necessity than choice. It’s scary. The lack of a regular pay check takes a lot of getting used to. Still, I seem to be surviving, the mortgage is covered and the kids generally get new shoes when they need them. I’ve put down a few thoughts that may help someone entering out the freelance world. I’d love to hear your thoughts / experiences in the comments below.
Finish Well
The thing that sticks in a client’s mind will not be how well you started a project, it will be how you finished it. To ensure your chances of getting more work, try to ensure that a job always finishes well. It’s a measure of your professionalism. What does this mean? Leave code in a tidy state and document design choices and non-obvious parts of the code base. As a project comes to a close, make sure you’re concentrating on and testing a working, real piece of software, as the end user will be using it. It’s all to easy to concentrate on small test cases and forget the larger picture of a cohesive, complete deliverable. Do this and you risk delivering software that falls over on day one due to unexpected loads or similar “real world” problems that don’t show up in testing.
Also, when the project you’ve worked on needs maintenance or expansion down the track, who are they likely to come back to? Repeat work is as good as it gets for a freelancer in terms of a regular ‘gig’. When you come back to this code in 4 months, do you really want to spend time sorting out the mess you left?
Iterate, Iterate, Iterate
Working as a freelancer means you come in cold to projects. It can take time to get a feel for a project’s requirements and the client’s needs. The worst thing you can do is take a client’s design brief and come back 4 weeks later with a completed piece of software that’s nothing like what they wanted. To ensure you’re on the same wave length, do everything you can to get something concrete in front of the client as soon as possible. Identify the minimum feature set that will do something useful, mock up the user interface and ensure that you are headed in a direction that will keep everyone happy. If you don’t show the client anything until delivery I will guarantee they will be disappointed, and you may lose out on future work.
By showing regular, demonstrable progress you can build up a trust with the client, everyone wins and there are no last minute surprises.
Learn to Estimate Accurately
Estimation is not a black art, it’s a skill you can acquire with practice. As developers, we tend to have a habit of estimating optimistically. We guess how long a task will take based on that first 90% of the code that we can bash out in a few hours. But to finish a job to the client’s satisfaction will require handling the last 10% that’s full of corner cases, API bugs and unknown risks.
Get used to asking yourself “What could go wrong?” and “What are the risks here that will cost time later?” when estimating time for a task. A client will be over the moon if you over deliver because your initial estimate was too conservative.
Embrace Challenges
Chances are you won’t get to work on your dream job as a freelancer – you’ll be working on someone else’s dream. Don’t let this get you down, treat it as a challenge. I would never choose to work on databases, embedded hardware programming, web services and yet I’ve done all this in the last year. The work has been varied and interesting, and I’ve learnt a lot about a wide range of disciplines.
Learn to Say No Nicely
At times there may well just be too much work to take on. You will have to say no to work. How you do this may well affect your chances of future work. Be polite and apologetic. Sometimes the client may be able to reschedule a project to fit your time table. I would have really struggled over the last two years without the goodwill of clients and friends. The effort you put into these relationships will pay big dividends down the track.
Know What Your Time is Worth
This one’s fairly straight forward. Know how much money a week you need to get by, and how much you need to be comfortable. Budget assuming you’ll get the minimum amount each week, and save the rest for a dry patch when work is not available. You won’t have a regular pay check, so you need to know where every single dollar is going. I’ve started to think of the things I buy in terms of hours work – it definitely changes the value you place on luxuries.
These guidelines are based on my experiences spending the last two years or so as a freelancer, as well as my career before that “working for the man”. Is this useful or do you disagree? Let me know in the comments below.
This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.
Setting up an Automated Build in an iOS environment – part 3
by George on Sep.03, 2010, under Coding, Project Management
In my previous articles, we’ve looked at how we can set up an automatic build, with a focus on catching issues with bad check-ins immediately. Another useful aspect of an automated build is that it can remove the chance of human error whenever we have a task that consists of a lot of manual steps.
One such example is generating a build for ad-hoc distribution to beta testers. We could create a build by hand, but if we forget to increment the version number in our project, then our testers won’t be able to update from a previous build unless they delete the old build by hand off their devices and iTunes – definitely a pain for people you don’t want to inconvenience.
Also, imagine the scenario in a couple of weeks when a tester notifies you of a serious bug they’ve found. Chances are the code you have now is quite different to the build they have. Can you get back to that point in the code easily?
Fortunately Apple provide us with a handy tool called agvtool that can handle these situations for us. It’s a command line tool, so it integrates nicely into Hudson. But first let’s look at agvtool on its own, and see what we can do with it.
agvtool
In order for agvtool to do its magic, we have a few things to set up in our project first. Most of the steps here are described in detail by Jamie Montgomerie on his blog. Briefly though, we will use two different version numbers – a release version and a build number. The release version is our “marketing” number – what our clients see (“Now updated to version 1.2!”). Our build number is for internal use, and will connect a given instance of our App to a specific tagged version of our code in source control. To test this, I created a simple OpenGL project in Xcode and added it to SVN as a starting point. The only modification I’ve made to it is to add a label on top of the GL view. We will use this later to display our build number for testers. Note that SVN is not necessary for using agvtool, but it will give us a few nice options down the track.
So, following Jamie’s instructions, we:
- Open our project’s PROJECT_NAME-Info.plist file and set the Bundle version to 1. This represents our build number.
- Ctrl (or right) click on the plist and choose Add Row. From the options presented, select Bundle versions string, short and set its initial value to (say) 0.1. This is our release version.
- Ctrl (or right) click on the project in the Groups & Files window, and select Get Info. Make sure you’ve selected All Configurations and find the Versioning section, near the bottom. Set the Current Project Version to match you build number – 1 in our case. Set the Versioning system to apple-generic.
OK, not too painful and we’ll never need to touch these bits again! Let’s test our a few things. Open up a terminal window and cd to your project directory. We can use agvtool to tell us both the current build and release version numbers (agvtool calls them version and marketing version respectively):

You should see the build number (agvtool what-version) and release version (agvtool what-marketing-version) that you entered into the project settings. Now, using agvtool we can also update our build and release version numbers. Note that doing this modifies your project, so ensure it’s either not open in XCode or everything has been saved – otherwise you may lose changes to your project such as settings or newly added files. So, to increment our build number we use:
agvtool bump -all

On the slightly rarer occasion that we want to adjust our release version, this can be done as follows:
agvtool new-marketing-version 0.21b

You can use the agvtool what- command to verify what’s going on here. Note that our build number is automatically incremented by one using the bump command. Our release version is in fact a string, and we can supply whatever we want there, in this case 0.21b.
Assuming you’re paranoid like me, now is a good time to check this into source control as we have all the basics covered.
Open the project in XCode and build it. XCode will now automatically generate a .c file as part of the build. In my case, these were found at:
build/AutoVersionTest.build/Debug-iphonesimulator/AutoVersionTest.build/DerivedSources/AutoVersionTest_vers.c
You don’t need to even open this file, or include them in your project (that happens automatically). This file declares two variables, a version string and number that correspond to our build number. We can put them to good use. In my sample project, I’ve declared the build number as an external variable in my App delegate:
extern const double AutoVersionTestVersionNumber;
And then in my application: didFinishLaunchingWithOptions method I’ve used the build number on the label I added earlier:
versionLabel.text = [NSString stringWithFormat:@"Build: %1.0f",AutoVersionTestVersionNumber, nil];
Now when testers run my App they’ll see something like this:

Now, a tester can easily identify the build they’re running when giving me feedback. By the way – if anyone know an easy way to get at our release version number in code, please let me know! What we need now is a simple way to tie that back to a specific version of our code…
Tagging in SVN
Note, this also works with CVS as well, however while there are good arguments for not moving to a more modern system like Git or Mercurial, there’s no good argument for sticking with CVS.
agvtool has the ability to update our version information and then commit the changes, simply by adding the usesvn tag like so:
agvtool -usesvn bump -all

Nice. But it gets better. We can then tag these changes to make getting back to them simple:
agvtool -usesvn tag -baseurlfortag http://URL/to/svn/AutoVersionTest/tags

The -baseurlfortag option specifies where the tag should go. After this operation, you’re SVN repository should look something like this:

Now, when you receive feedback from a tester it’s a simple matter to check out the tagged code and you can track down issues with the same code base your tester was using. Note that the folder specified by the -baseurlfortag option must already exist – agvtool will not create it for you.
And Hudson?
Hopefully it’s not too much of a stretch from here to see how we can use this in Hudson (or any other automated build system). First off, we should create a project in Hudson that will check out our code and build it. If you already have an existing Hudson project that builds periodically or with each new check-in you can simply clone it (Hudson is good that way). Configure the project to only build manually by unchecking all the build triggers:

And add in new build step(s), calling agvtool to bump our build number and (if using SVN) tag the resulting build. Note that if this project were set up to trigger a new build when check-ins are detected we have a potential race condition, with agvtool checking in changes which would trigger a new build which would make agvtool check in changes….
So, with these changes in place we can now reliably build a version of our code for testers, tag it and know that we can come back to the code for that build at any time. And it’s all done automatically. Also our version numbers will always increase, insuring that our testers don’t have trouble updating to a newer build.
And Another Thing
OK, I haven’t played with this one extensively yet, but will add it here for your consideration. Hudson allows us to add parameters to a build. When we start a build, it will ask us to supply parameters that affect the build. As an example we can add a BuildNumber parameter that will decide which tagged version of our code we want. Configuring it in Hudson will look something like this:

So what’s the use of this? Well the parameter becomes an environment variable when Hudson is building the project. So we can slip the environment variable into our source control link. This way, when we kick off a build we can specify the tag to use, making it easy to recreate our App as it was at any stage in its development.
Well that’s it for this week. If you have any questions or feedback please leave a comment below.
This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.
Setting up an Automated Build in an iOS environment – part 2
by George on Aug.18, 2010, under Coding, Project Management
After last week’s introduction, it’s time to get on with making this thing. After looking at both CruiseControl and Hudson, I went with Hudson – mainly because it’s very simple to set up and start using straight away. So without further fuss, let’s download Hudson from here. I created a build folder ~/AutomatedBuilds (there’s nothing special about this location, put it wherever suits you) and put the downloaded file hudson.war.zip in it.
Open a terminal window and cd to the build folder. The online documentation says that you should unzip hudson and run it using the command:
java -jar hudson.war
This works fine on Windows, however under OS X, unzipping the file and trying to run it causes the following error:

If anyone can explain the issue, I’d appreciate the insight. However it turns out we can just run Hudson as-is out of the zip file:

Ok, so what’s happened? Hudson is now running as a Java application in the terminal. As well as running the build, it also provides a web interface for us to work with. Open a browser and point it at http://localhost:8080/ and you should see something like:

Before we set up our first job, we should grab a couple of handy plugins first. Click on the Manage Hudson link on the left, then Manage Plugins and finally the Available tab. You should see a long, slightly exciting (or intimidating, depending on your outlook on life) list of plugins. Have a look through the list – there’s lots here to play with – but for now select the Twitter and Mercurial plugins (assuming I’ve convinced you to try Mercurial), and click on the Install button.
You should see the plugins being downloaded and installed, along with a message to restart Hudson. When Hudson is running, there’s a Prepare for Shutdown option on the Manage Hudson page. For now though, it’s enough to go to the Terminal window you’re running Hudson in and kill it with Ctrl+C (I’m a bit old fashioned that way).
Run Hudson again from the terminal window, and we’re ready to set up our first automated build. For a start, let’s create a build that monitors our source control repository and kicks off a build when it sees any changes.
On the main Hudson dashboard, click New Job. Give the job a name, choose the “free-style software project” option and click OK.
On the resulting page you can configure a bunch of options. Feel free to go nuts here. Each option has a ‘?’ icon that provides useful help. Here’s the settings I used:
Under Source Code Management, I chose Mercurial and pointed it at my Fogbugz Repository. The Fogbugz repository requires the user to be authenticated, so we do this by including the user name and password in the URL in the form:
https://USER_NAME:PASSWORD@PATH_TO_REPOSITORY
Note that, if your user name has a ‘@’ symbol in it, replace the ‘@’ with ‘%40′ to avoid the URL being incorrectly parsed by Hudson or Fogbugz (see the screen shot below).
Hudson also supports many other types of source control, pick the one that you use. Another small note here – when setting up an automated build for the first time, it’s a good idea to use a small test project first, to allow faster testing of your set up. My actual production code can take many minutes to build (not my fault! OpenFeint is slow to build), so instead, for this article, I’ve created AwesomeGame from one of the standard XCode templates. Once I have a running build system, I’ll then go back and add in my production code.

Next up, we want to check if we need to trigger a build by polling SCM for changes. We schedule Hudson to check SCM every minute using CRON-like syntax :

Then, we add the actual build step, executing a shell command to run XCode from the command line using xcodebuild. Have a look at the xcodebuild man page for all the various options. For now, we want to build our AwesomeGame target in both Debug and Release modes. I’ve done this below using two build steps:

Finally, let’s tell Hudson how to notify us when the build is done. I selected email and Twitter notifications. If you’re on a team, notice the option to notify the individual who committed the changes that broke the build – without having to notify the entire team. As well as the person responsible for the break it’s good practice to have a nominated ‘build monkey’ whose job it is to check all builds – so make sure they’re getting all the build results as well. A quick note on Twitter here – don’t use your own Twitter account unless you want to spam all your followers! Instead, create a bogus build account for Hudson to use, and follow it from your main account.
Assuming we’re all happy with the settings (we can always come back and tweak them), click Save.
Hudson now takes us to the page for our project. On the left is a Build Now option – let’s try it out… After a few seconds, you should see a progress bar in the bottom left, telling you that Hudson is building your project. If nothing happens, check the top right of the page for an Enable auto-refresh option.
Once finished, we’ll see a blue ball that indicates a successful build (your code in source control does build, right?). If instead you see a red icon, then the build has broken, and we need to fix something. Either way, click on the most recent build link to see details of the build:

On this page, we can see the status of this particular build (remember blue ball means success), the changes in source control from the last build (none in this case, as we manually triggered the build) and the console output, where we can see the details of the code being checked out from source control and built using XCode. If your build has failed, this is a good place to look for the problem.
Phew! The system works! Checking Twitter, sure enough there’s a success message there:

But hang on, where’s my email? The problem here is that we need to configure Hudson with an smtp server so that it can deliver mail to us. Go back to the Manage Hudson page, and click on Configure System. Near the bottom you can configure the global settings for email and Twitter. If you’re unsure what smtp server to use, check the settings for your email program – you’re looking for the name of your outgoing smtp server.
So enter in your smtp details, and the system admin email address (that’s you). Click on the Test button and make sure that you get the test email message.

Going back to the main Hudson page, you should notice that our project is listed, and on the right hand side is a Build Now icon (so you don’t have to go into the project to kick off a build). Click it to start another build, and then click on your project to follow the build’s progress… Still no email. Bugger. Going to the project’s Configure screen, I look up the help for email, which sheds some light on the issue:

This is sensible – no point in spamming out emails when builds are all going well.
So by now we know that we can check out our code and build it automatically. But where is the build? Hudson creates a working folder in your root directory. Have a look in ~/.hudson, and you’ll see all of Hudson’s internals. In particular, the folder ~/.hudson/jobs/Awesome Game contains all of our build history and a workspace folder in which the code is checked out and built. So if I want to get the built app, I can grab it from:
~/.hudson/jobs/Amazing%20Game/workspace/build/Release-iphoneos/
Later we’ll look at packaging up the build and putting it somewhere handy, but for now, let’s make sure that it’ll pick up on changes in source control. Check out a working copy (if you don’t have one) of your project and put in a small change that will cause the build to break. This ought to do it:

Commit the change (or commit and push if you’re using a remote Mercurial server like I am) and wait for a minute. You may notice a message mentioning a ‘quiet period’ before the build kicks off properly. This quiet period is Hudson waiting after it detects a change in source control to make sure all changes have been committed – this is particularly useful with CVS, where every file is committed separately.
Ah, BOOM! Our build has failed nicely. And I got an email this time, which is nice
A broken build is something that shouldn’t be left broken, so let’s fix it and check the build comes back happily. Fix the code, push, commit, wait… success! Twitter and email confirm everything’s OK.
We’ve covered quite a bit so far so it’s probably a good time to take a break and see what we’ve achieved, and how that matches our goals from last week.
What works?
- Monitor source control (Mercurial and Subversion in my case), kicking off a build whenever changes are checked in.
- We’ll be able to manually kick off a build as needed.
- The build will grab all our source code from source control and build it in all relevant configurations – debug, release, simulator, device and so on.
- When the build is finished, it’ll notify people of the success / failure.
- There’ll be a handy location (web page most likely) where we can monitor / control the whole thing.
What do we still need to do?
- We’ll schedule a nightly build as well, just in case anything outside of source control has changed. This is fairly simple – an exercise for the reader!
- Copy a successfully built app to somewhere useful, preferably packaging it up with a provisioning profile in a zip archive, ready for emailing.
- Automatically update version numbers on our ‘stable’ build with each build.
- Bundle up the resulting builds with a provisioning profile and copy them to a shared folder.
- Start up automatically under when your build machine is booted.
- Paint a unicorn.
OK, plenty to work on, I’ll be back next week with some more detail, or if you’re keen have a crack yourself and let me know how you get on!
Setting up an Automated Build in an iOS environment
by George on Aug.13, 2010, under Coding, Project Management
What? Why?

An automated build is a system that can build your software from source to finished product without human intervention. At it’s simplest, this can be an XCode project or a makefile – after all, you don’t compile each file and link them together by hand, do you? The key idea is that we can remove human error from the process, making it more efficient. The ideal is to have a system whereby you can build all versions of your software with a single click (and also score a couple of points on the Joel test).
Consider the following situation. You want a fresh build of the code to show off to your boss, “Reckless” Jim, to keep him off your back. When you wake up, you grab your iPhone 4 (lucky bastard), open Safari and click a link on a web page before you get in the shower (remember to put the iPhone down first). While you’re halfway through your hot water supply (and the Sound of Music soundtrack), the following is happening:
- Your ‘build’ machine HAL schedules an automated build.
- It grabs the latest code tagged as ‘stable’ from source control.
- The code is then built in all configurations (debug/release, simulator/iPhone/iPad).
- Unit and functional tests are run on the resulting apps to ensure that nothing is broken.
- The built apps are bundled up with a provisioning file, ready for installation on any of your test devices.
- The resulting bundles are copied to a shared folder for you to download while scoffing down your Fruit Loops.
- An email is sent out to the team notifying them of a successful build, along with details of tests run, how long it took to build and who has committed the most lines of code in the last week.
- You grab Reckless as he comes in the door (he’s always late) and put a running build in his hand.
Cool, huh?
Or how about this:
- Your team mate “Lazy” Jason checks in a new feature, and heads out (it’s 2pm) so he can go surfing for the day.
- Your build system Grumpy detects the change in source control and begins a build.
- By now Jason is half way out the door, but he’s paused to (try to) chat up Christine, the new graphic designer who started yesterday.
- Meanwhile, Grumpy is building the source code from the development branch in source control.
- Uh oh! The build is broken – Jason forgot to check-in AwesomeFeature.mm.
- Grumpy send a text alert to you (as build monkey) as well as to Jason who was the person who caused the build to break.
- Jason is beginning to have a bad day. Not only has Christine turned down his advances in an unequivocal (and slightly cruel) way, but you catch him before he gets out the door.
- Disheartened, Jason heads to his desk to fix the build. Fortunately the solution is fairly obvious and he checkins in a fix within a couple of minutes.
- Good news – the new build is fine. The team is notified of a clean build and Jason can leave for the beach knowing the team doesn’t hate him, but that he is now the nominated build monkey until some one else breaks the build.
Neat, eh?
This second example is what’s known as continuous integration – every time you check in new code to source control, the whole build is exercised to make sure nothing’s broken. Why? Often a broken build is a simple 30 second fix at the time, but 2 weeks later it might require hours of sorting through commit logs to see where the problem is.
The solution

So, what does it take to set up a system like this? Not as much as you might think. There are some neat tools out there to get you up and running fairly quickly. The problem is that I didn’t have time to try out both of the likely candidates for this week’s deadline. I’ve used CruiseControl before, and Hudson looks promising.
So here’s the goal for next week. I’ll show you how to set up a system that will:
- Monitor source control (Mercurial and Subversion in my case), kicking off a build whenever changes are checked in.
- We’ll schedule a nightly build as well, just in case anything outside of source control has changed.
- We’ll be able to manually kick off a build as needed.
- The build will grab all our source code from source control and build it in all relevant configurations – debug, release, simulator, device and so on.
- When the build is finished, it’ll notify people of the success / failure.
- There’ll be a handy location (web page most likely) where we can monitor / control the whole thing.
- Automatically update version numbers on our ‘stable’ build with each build.
- Bundle up the resulting builds with a provisioning profile and copy them to a shared folder.
- Start up automatically under when your build machine is booted.
- Paint a unicorn.
In the mean time here’s a couple of sample chapters from Pragmatic Project Automation: How to Build, Deploy, and Monitor Java Applications that covers the basics of setting up CruiseControl.
So, now to decide between Hudson and CruiseControl. If you have any thoughts on either of these systems (or another I haven’t heard of), please let me know in the comments below…
Fluffy Buns – a handy tool for developing better games
by George on Aug.06, 2010, under Game Design, Reviews
Got skillz?
Any good software developer is always on the look out for new techniques or tools. But when was the last time you actively cultivated your social skills?
Does this sound unecessary? We’re coders after all, dealing with syntax and pixels, right? Well consider this. Our games are nothing until we’ve put them into the hands of our players. It’s a social contract we have with the players to offer them a fun and engaging experience. And most importantly, if they don’t like it, you’re up the proverbial creek without a paddle.
If we’re going to make our game great, we need to see it’s effect on potential players. For the best results, we need to do it early and often to avoid wasting time on ideas and implementations that just aren’t good.
So, assuming you’re buying into this argument so far, the next step is to get some feedback from players. Giving and receiving feedback is very difficult to do well, and it’s a skill that continually needs to be trained and refined, alongside your other mad skillz.
Giving feedback
Giving feedback can be difficult – you need to let the game developer know what doesn’t work, but without leaving them whimpering in a corner when you’re done. The trick here is to think of a hamburger’s fluffy buns. The idea is that you wrap the “meat” of your concerns in between a nice couple of “fluffy” buns to soften the blow.
Example:
“Your game crashes all the time and is unplayable.”
Example:
” I like what you’ve done with the art style, and I can see a lot of promise in your game Mega Zombie Ninja Defense HD. However, I’m having trouble with the game quitting unexpectedly on me. It happens fairly regularly at the start of each level and is making it difficult to get into the game. I’m keen to get further into the game, please let me know if I can help in tracking down the problem.”
So, both of these comments say basically the same thing right? But which would you rather receive from a beta-tester? Here’s a few key points:
- The first example comes across as a personal attack on the developer, mainly through the use of the word “Your”. It’s the written equivalent of stabbing your finger at someone to make a point. The recipient of this comment immediately becomes defensive and unwilling to take on board your comments.
- Also in the first example, the phrases “all the time” and “is unplayable” are absolute (rather than subjective) statements about the game that may not be true. “Crashes all the time for me“ may be true, but can you really speak for all the other testers playing the game?
- In the second example, the initial compliment puts the developer in a receptive frame of mind, ready to listen to your concerns – establishing a dialogue. Talking about “the” game rather than “your” game makes for an objective discussion, rather than an emotional one.
- Expressing the problem in terms of “my experience” means you’re open to the possibility that it’s not the developer’s fault – perhaps you’ve updated to a new OS reveision that they haven’t had a chance to test yet, or perhaps you’re jailbroken phone running a Linux kernel may have something to do with the issues you’re having.
- You’ve knocked the guy down and given him a kick in the guts, telling him his code crashes (even if it’s true, it’s not nice to hear), so wrap up by saying something nice to pick him up off the ground again feeling positive about what needs to be done.
There’s more at stake here than just being all new age and caring. It’s about being able to get to the heart of a problem and fixing it. The fact that it can help build a stronger relationship with someone is just a nice side effect.
It is better to give than to receive
OK, so let’s say your the king of fluffy bins, and people love you as a beta tester because you give honest, helpful feedback. Now it’s your turn to send a build out to a handful of testers. It’s hard. You’re feeling a bit nervous – hoping they love the game, terrified that they won’t. And then you get this:
“Man this sucks, couldn’t you do any better?”
Ouch. What can you do? First off, try not to take it personally. You asked for peoples opinions, you have to be prepared to take the good with the bad. If people only offer praise, you’re game will suffer for it. Just watch American Idol some time if you don’t believe me. All those poor people who can’t sing to save themselves. I can just imagine their well meaning family telling them “You’re fantastic, you can do anything you want to do”.
OK, so we’ve gotten over the initial shock of the feedback. Now it’s time to ask yourselves “Why did this person have such a bad experience?” There’s obviously a problem here, and you need to develop the skill to find out what’s going on. This is where the “Five Whys” technique comes into play. Let’s imagine how the conversation could go:
“Man this sucks, couldn’t you do any better?”
“Wow, I’m sorry it didn’t go so well for you, can you give me an idea of what went wrong?”
“I just couldn’t get into it.”
“Why was that, was it too hard? Did the controls make sense?”
“It was OK until I reached the first platform, I just couldn’t get up onto it.”
“Why was that, were you double jumping?”
“Double jumping? You can do that?”
“Yeah, just triple tap the player again after he’s jumped. Did you read the instructions at the beginning of the game?”
“Oh those, I kinda skipped through the last seven pages.”
“Fair enough, maybe I should look at shortening them down a bit. Triple tap may be a bit tricky too, I guess I could look at using a tap and hold or something. That shouldn’t take too long to fix. If I sent you a new build, would you give it another go?”
“Sure, sounds good”
Wonderful, a happy ending. With a little effort on our part, we’ve turned a flippant, unhelpful response into some valuable information:
- If a player can’t master double jumping, the game is unplayable. Is it really that important a skill for our game?
- Triple tapping is a pain.
- Our “how to play” instructions are too long.
- Maybe we should put the first time the player is required to double jump further into the first level?
- Perhaps we can shorten the instructions and break them up into smaller chunks, delivered as needed rather than all at once?
All that from “Man this sucks, couldn’t you do any better?” . The idea of “five whys” is to strip away the superfluous and get at the heart of a problem.
Wrapping up
A bullet list to wrap up:
- Avoid being personal (using “you”), unless you’re talking about yourself (“I think”).
- Think of it as a puzzle to solve objectively. The answer is there, you just need to develop the techniques to find it.
- “Never attribute to malice that which is adequately explained by stupidity.” A person who’s gone to the effort of offering criticism may have a valid problem they don’t know how to communicate.
- Your harshest criticism is also you’re greatest opportunity for improvement.
- Be wary of feedback from friends and family – avoid asking what they think – rather ask them for ways to help you improve and fix the game.
So, maybe there is something to being nice after all. Mastering the art of giving and receiving feedback may seem unimportant at first, but it’s one of the most valueable tools you have.
What do you think?
The Game Developer’s Bookshelf
by George on Jul.23, 2010, under Coding, Reviews
Obtaining a Fix
Some Great Books
The Art of Game Design : A Book of Lenses
by Jesse SchellBeginning iPhone 3 Development: Exploring the iPhone SDK
by Dave Mark and Jeff LaMarcheUser Interface Design for Programmers
by Joel SpolskyGame Engine Architecture
by Jason GregoryThe Pragmatic Programmer: From Journeyman to Master
by Andrew HuntMy Name is George
Distributed Version Control – Getting Started
by George on Jul.16, 2010, under Uncategorized
It’s not just for academic hippies
There have been a lot of people talking up Distributed Version Control Systems (DVCS). Until recently, I’d assumed that it was the same people who have been talking up Linux for the last 15+ years. Don’t get me started on them. It seemed the principal argument used by many people was ‘everyone has their own repository’. To me, that sounded like a recipe for disaster – I’m far happier with the concept of a central, authoritative repository.
So I was surprised when Joel Spolsky came out in favour of Mercurial (or Hg), a DVCS. Joel’s a fairly level headed, mainstream kind of person – what was he doing fraternizing with the Linux-loving hippies and beatniks? After reading his Hg introduction, I realized I was in danger of becoming a convert too. When you’re done here, you may want to go over to hginit.com – you won’t find a better introduction to Hg or distributed version control in general.
What’s so good about it?
So, it turns out that DVCS is a viable alternative to regular, vanilla flavored version control. And by that I mean Subversion or CVS, the systems I’m most familiar with. There’s a few main points that convinced me to give Hg a try:
- It’s not too dissimilar to ‘normal’ source control, meaning it’s fairly simple to make the transition (add files, update, commit, revert etc work basically the same way)
- Rather than worrying about ‘everyone’ having a repository, the key thing is that you have your own local repository that’s just for you. So you get the safety net of frequent check-ins without having to worry about ‘breaking the build’.
- Branching is something a lot of people strenuously avoid with Subversion, because the tools just aren’t set up to handle it easily. Because of the way Hg tracks changes, merging branches is a simpler and more reliable process.
- Mercurial still supports the idea of a central repository, and in fact handles multiple staging servers (development, stable, release etc) fairly well.
I’ve been using Hg on a couple of projects for a while now, and I like it. The big wins for me are how simple it is to set up a new repository and how convenient it is to have a local repository for frequent check-ins.
Getting started
So what’s needed to get started? Well the good news is that all the tools you need are freely available and well made. First off, you really should read Joel’s introduction. After that, the command line tools are available from here. Using the command line is a great way to learn a version control system and really understand what’s going on – and it’s surprisingly simple.
Sooner or later though, you’ll want to look at some sort of GUI though to speed the process up. @bunnyhero put me onto MacHg which I’ve been using for a week or so now it’s been excellent. There’s a good screencast that covers the basic features of MacHg and will get you up and running straight away.
You may think that not having your version control inside XCode is a pain, but in fact I think it’s a huge bonus to separate IDE and version control. I’ve never seen source control handled properly inside an IDE (I’m thinking Visual Studio, Eclipse and XCode here). Version control is about files and folders, and I don’t want the IDE thinking it know better than me how to apply version control to a project by making ‘assumptions’ to try and streamline the process.
And finally, one of the strengths of version control is that it forces you to maintain backups of your code base. And the best backup is an off site one. Setting this up is a pain, right? Actually no, as once again Joel comes to the party and makes this easy. His company Fogcreek offer remotely hosted project management, bug tracking and version control tools, including support for Hg (they call their Hg toolset Kiln).
Obviously this is service you pay for, right? Yes. Unless you are a student or small company (or in fact anyone who doesn’t need more than two active users), in which case it’s FREE. Setup is trivial, and before you know it you can have a professional grade offsite Hg server of your very own.
While you’re at it, you also get their Fogbugz tools as well, so simple bug tracking, scheduling, wiki, code review and customer support all come as part of the free package. Nice. I should point out I get nothing for recommending Fogcreek, I’m just a bit of a fanboy.
Give it a go
So there you are, if you’re looking for an easy way to get into source control, or you’re sick of merging branches in Subversion, you might give Hg a go. All the tools you need are freely available for a small scale team and the learning curve is not that steep.
One last detail – I did have a little trouble getting MacHg to talk to Kiln . The problem is that MacHg needs the URL to include your username and the repository URL, and separates them with an ‘@’ symbol. Kiln’s user names are typically your email address , so MacHg get’s a little confused when it sees something like:
https://george.sealy@gmail.com@acornheroes.kilnhg.com/Repo/Repositories/Group/FaerieDev
Fortunately, the solution is fairly straight forward, you can ‘escape’ the ‘@’ symbol in your user name like so:
https://george.sealy%40gmail.com@acornheroes.kilnhg.com/Repo/Repositories/Group/FaerieDev




