Continuous Integration and Continuous Delivery are not new ideas. But they do bear repeating, especially in the context of mobile software development.
My (hopefully skewed) impression is that a lot of mobile software developers tend to avoid these kinds of practices either out of ignorance or just perceived lack of value due to having smaller teams and applications. Far too often I’ve seen developers put builds together on their local dev machines to then send out to testers or to go to the app store. What I intend to do here is speak to mobile software developers — Android in particular — and make the case for why you should adopt a Continuous Delivery lifestyle and how you can achieve this in the Android ecosystem.
Creating, maintaining and evolving software is one of the more complex activities we humans engage in. And the software we build has an ever increasing level of complexity and importance to the world as a whole. Given that it’s getting both more complex and more important, we as an industry need to do a better job ensuring quality and timely delivery to our users. One way to work toward that goal is to do what we developers do best and make computers and software automate all of the tedious and error-prone activities that come along with software development.
Obviously, we can’t automate away the actual writing of the code. Programming involves talking to people, figuring out what their problems are and coming up with creative ways to solve them with code. That’s that part we all love and it’s something that must be performed by people.
So what kinds of things can we automate? Almost everything else, actually. Compiling the code, testing that the code works as expected, packaging the application, updating our project management tools and team members with progress updates, delivering the application to testers, reporting issues to the team, etc. Ideally, once we’ve written the code to add new features to the application, it would kick off a pipeline of automated processes that ensure the app is of a high quality and is delivered as close to the end users as possible. In practice, this probably won’t be auto-delivered to your entire live user base, but it should at least go straight to your testers and/or product owners who need to sign off that the app is working as expected.
So I’ve said you should get into this type of flow, but I’m sure some of you are asking why? What’s the big deal? I’ve been doing builds locally on my machine for years and it’s worked well enough. Well, let’s discuss some of the benefits.
How much time do you spend on the tasks I mentioned above? Even if it’s a small amount of time each day, these are tasks that you do repeatedly, throughout the life of a project and your career. Between building, testing, packaging, deploying and updating tools, you or your team members could easily spend an hour or more per day on these repetitive activities. (Especially performing manual regression testing.) Imagine if that time was applied to more productive things, every day, across your entire organization. If you saved one-half hour per day per team member across a team of 4 developers, that would equate to about 12 man-weeks by the end of the year.
Not only is it a time sink, but it’s not very fun doing repetitive things. Even if you don’t end up saving a dramatic amount of time by developing the automation process, you’ll probably be happier spending that time on the more thought-provoking work of making software do your tasks for you.
I mentioned above how complex software is and it continues to get even more so. How could you possibly have any confidence that the state of your software is anything but broken unless you have a repeatable process set up that proves otherwise? Anything less is basically a shot in the dark that assumes no human error happened to occur in the manual process of testing and deployment — this time. Next time, mistakes go back to being a likely occurrence. Is that how you want to live your professional life? Or would you rather act like a professional and guarantee the quality of your work?
You’ll also achieve higher confidence when one build process produces all of your build variants. Whether it’s packaging a white-labeled app with different branding, pointing to different web service environments, having debug info enabled/disabled, etc. That way if your testing team signs off on a particular build, you don’t have to turn around and do more builds to deploy it under different scenarios and risk introducing unintentional changes.
No more “works for me”
When you have a single build server that starts from a clean state and executes automated tests, you will no longer have the “works on my machine” syndrome. A good example of this is a recent project that we inherited. We received the source from the previous developer, but about 20% of the image assets were missing and we couldn’t build the project. Turns out, those images were pointing to somewhere on that developer’s local machine instead of from the project folder that was under source control. This is the kind of thing that just won’t happen when you automate your builds on a build server. It makes sure that everything that is needed for your project is in source control and can be built from a clean state. Everytime. And you never run into a situation where you can’t build the app because Jimmy is on vacation and he has the ______ that’s needed.
The best time to fix a problem or make tweaks based on feedback is when that knowledge is fresh in your head. If a test starts to fail the moment your changes are integrated into the rest of your team’s changes, you can quickly fix it before the bug gets more costly to fix. And if the new feature gets automatically and immediately delivered to the product owners, you will get faster feedback as to whether it’s adding the intended value. Otherwise, with a non-automated process, it could be days or even weeks before your team runs a full regression test, finds and fixes a problem and eventually gets it out to the product owners.
Empowering product owners
When product owners have the continuous ability to pull a fresh, stable, shippable build, they can be more flexible in the decisions that they make. They can start doing things like demo the latest and greatest version to earn new business, ship a feature earlier than planned to get it into customers’ hands, ship more often because they don’t have to wait on lengthy manual testing cycles to complete, etc. All of this can happen independently of the development team even knowing or caring because, to the developers, they are continuously delivering a shippable product, automatically, all the time.
When everything is done manually and on an ad hoc basis, it’s possible (probable?) that every time a new build is created, at least one or more things will be done slightly differently. Even if that something is just the format of the release notes that get generated to communicate what’s changed. On the other hand, when you have an automated process, you have explicitly codified your team’s process and created a standard for which all builds will be performed. Not that you can’t change those standards, but when they are changed, they are changed explicitly and will remain until they are explicitly changed again.
And so much more…
There are many more benefits of adopting The Continuous Delivery Lifestyle™. Like being easier to transition team members on/off the team, having the ability to more quickly react to problems in production, better involvement of your designers in the QA process, etc. But, I don’t want to continue to drone on. It’s time to get to the good stuff…
Ok, so you’re convinced you say? But how do you get started? If this type of thing is completely new to you, it may be overwhelming given the vast amount of choices out there for performing automation tasks. In my next post, I’ll walk you through setting up a basic Android example using Gradle, Travis CI, GitHub, Pivotal Tracker and Google Play.