As you may have already read, we recently completed some work with LateRooms.com to design and build a refreshed and refined version of their current iOS and Android applications. Philip nicely went into some details around the process behind getting the design from a rough sketch, to a fully functioning polished MVP from the design side of things.
This post will take a look at the process and tools behind the development side of the coin, and how the development team worked to reach the app stores on time and on point.
Project setup was a very important factor from day one for us, due to the size of team and cross platform nature of the project. A modular approach to this using git submodules was the logical choice. This allowed us to work between teams with as little friction and repetition as possible.
The project consists of a few major functional chunks, each representing a git repository:
- iOS codebaseThis contained the Objective-C powering the iOS application as well as the calabash-ios Ruby BDD step implementation files.
- Android codebaseContaining the Java powering the Android application as well as BDD written in our Android developers Java BDD framework.
- BDD feature filesThe cucumber BDD feature files which define the expected behavior of both the Android and iOS applications.
- iOS assetsThe assets displayed in the iOS application, having this in a submodule allows the designers to push and manage changes without affecting the main code base.
- Android assetsSimilar to the iOS assets but for the Android application.
- Design specificationsContaining exported images of complete screens to use as a reference while developing features. As well as specifications such as font sizes, measurements and copy.
Using this approach offered us a number of advantages, including giving the designers the ability to easily update assets within the application by pushing changes to the relevant git assets repo. Another was the ability to make use of GitHub pull requests & issues in the relevant repositories avoiding clutter on the main codebase repositories.
GitHub provides us with some really nice tools to help us work better as a team and stay on top of our bugs. It sits very much at the core of our workflow and we use it heavily everyday. We use it for a number of things:
- IssuesGitHub is our main issue tracker, using GitHub instead of an external issue tracker gives us the ability to do some nice tricks. We can close issues with commit messages, easily create links from pull requests to issues for reference, and assign our issues to milestones that represent our sprint to track progress.
- Code reviewThe most useful feature provided by GitHub is the pull request. We use pull requests as a protective barrier between us and our mainline branch. When a developer completes a feature with passing unit & BDD tests they will open a pull request. This allows any available developer on the team to take a look at the changes and suggest any improvements to ensure everything that goes into develop is of the highest quality, nobody is perfect and can have a bad day. Integration with Jenkins also allows us to easily see if a build is failing or passing.
- BuildsWhen someone pushes up to remote we use webhooks to trigger a build inside Jenkins, this let's us know ASAP when something has gone bad so that we can fix it and keep the codebase as healthy as possible. We also use the GitHub pull request builder jenkins plugin to build pull requests. This integrates GitHub and Jenkins nicely together letting us easily see if a pull request is successfully building or failing before we merge it into the mainline.
- ReleasesA while back I added some functionality to my build tools gem yolo to integrate releases with GitHub. This allows us to host each release created manually or via our automated build tools within GitHub. Each release will contain release notes, the ipa file as well as the dSYM folder and be associated to a commit. Having an easy to access and search backup of each release along with its dSYM comes in very handy.
Automating all the things
Automation is very important to us here at ustwo, if you have to do something manually more than once then you should be automating it. We've tried to automate as much of our development process as possible using a combination of Hubot, Jenkins & some Xcode build tools magic using Ruby.
- JenkinsJenkins sits at the center of our build tools toolchain, which hasn't been any easy ride for the iOS team. The iOS tool chain is notoriously bad in a continuous integration environment, unstable sums it up best. As mentioned earlier we utilize GitHub service hooks to build each push & pull request. For iOS the build itself is configured using a Makefile which runs a few tasks such as cleaning up before building, building using xctool and then cleaning up some more. Jenkins and iOS has been a less than perfect combination, so this is a pain point we're working hard on improving.
- HubotWe use Campfire as our main communication channel, which luckily for us Hubot is compatible with. Using a Hubot script it's possible to release builds via Jenkins and yolo with a simple command in any of our Campfire chat rooms. Hubot also provides us with lots of fun in terms of cat pictures, sounds and memes when we need a time out. Tying up nicely with Jenkins, Hubot also reports to us when the build status changes and on which branch the status changed which is useful if the build is accidentally broken.
Putting it all together
These tools and processes have helped us to deliver a product we are proud of on a tight deadline, utilizing existing services, our own custom tools as well as development practices such as TDD & BDD we are able to function as a well oiled cross platform, multi discipline, multi location team. We're always looking to improve our tools so let us know if you know of anything we're missing out on that helps your team work better and more effectively.