Since switching over to Apple’s TestFlight, we’ve been pretty pleased. The clear versioning of applications, easy internal and external test distribution, and having App Store distribution hooked into the same system is actually really great. Other improvements to the rest of the process for code signing and distribution system have been welcome as well – I rarely have to go into the developer portal and manually enter things these days.
I’m assuming that we’ll see more and more functionality rolled into TestFlight. This has been my experience with Apple as a developer over the last decade: Apple waits until things are well-polished and tested prior to release. (In general, at least; everyone is allowed to make mistakes.) For example, it was only a few years ago when a private API that Apple used in one of their applications was a cause for protest. The argument was often that Apple was being anti-competitive and screwing the little man, pre-emptive Sherlocking, if you will.
Of course, many of us knew then what most folks know now: private APIs are often the beta version of what will become a public API. Most code improves over time. Our first shots at solving new problems are often ugly. As we become more comfortable with the problem and its solution, we can craft a more appropriate API for that solution. This applies to SDK developers even moreso: an early, ugly API decision can cause problems for years for many, many developers.
So, it stands to reason that Apple is already working on improvements and additions to this process of deploying to internal and external testers, and to the App Store. Hopefully, many of those improvements will address different types of companies and different workflows. As has happened in the past, there have been times our workflow has fit directly into Apple’s vision, there has been times where a little more work was required, and there have been times where we have been forced to change our workflow. That’s just the nature of things. In this particular case, we’re doing a bit more work to deploy to testers than we had done before Apple took over TestFlight.
Related: Piloting Life in the Fastlane
Prior to Apple acquiring TestFlight, we had a pretty solid automated process for building and deploying to testers. We do our work on branches off of our main development branch (which for us, is just master). When work is finished, we create a pull request for the working branch. Someone else must review the work before accepting the request, and acceptance will merge the branch into master. Changes to master would automatically trigger our Travis CI build server to grab the source, build it, verify the build and upload it to TestFlight. When it was important to send out a build to testers or non-developers, we just clicked the button in TestFlight to make the most recent build available.
This automated process was very useful, especially for provisioning. If something changed about the provisioning profile, one developer could make the change, give the information to the build server, and no one else would know, care or be interrupted from their work.
Xcode bots seek to solve at least part of this problem – and may eventually solve the entire problem. I recently installed Xcode Server and set up a CI bot within Xcode. The unfortunate part was that I never got fully finished because there is apparently a bug in Xcode Server that doesn’t appropriately download provisioning information, so the automated builds couldn’t be code-signed. There was a workaround, but even still, without the ability to upload those to builds to the new TestFlight portal, it wasn’t all that useful to have build archives hosted on the machine running Xcode Server (which was in this case just my normal laptop).
Xcode bots do allow post-hooks, which means that if the API to upload to iTunes Connect was publicly available, we’d be able to push those builds directly to iTunes Connect. I would imagine that as Apple improves this process, this would just be a checkbox instead of a custom post-hook script. I hope that solution has some finer-grained control over which commits and which branches trigger this.
So for now, we’re just kicking builds up to iTunes Connect manually via Xcode. That process is actually pretty seamless, all things considered, but an automated approach would be the next obvious step. Currently, the iTunes Connect portal is good enough that it doesn’t require a developer to really manage – this is great – but the bridge between getting builds from developers to the portal where non-developers can manage them is going to be key.
But there is still another struggle here, and I think has been a struggle for awhile, especially for consulting companies like ours: developer portal and iTunes Connect roles and users.
Since the builds to Apple’s TestFlight must be signed by a distribution certificate, and now we’re submitting and signing from a developer’s machine, any developer that can submit builds (which we’d like that to be all developers upon successful code merge) must have access to the distribution certificate. Additionally, a developer is often part of multiple teams (for example, I have 7 different teams to pick from when I log in to my account).
This is where things get a little blurry. First, only the team agent can create App Store certificates for corporate accounts – unless I’m missing something, and I’ll be honest, I very well might be. (For enterprise accounts, the contents of the team agent’s developer portal are entirely distinct from an admin/member portal. I’m not sure why this is the case.) The problem here is that the typical team agent for a company, in my experience, is probably someone in procurement or marketing, or at a level within the software wing of the company that is in a more hands-off position. In other words, the email, “Hey, can you create a distribution certificate …” is usually followed up with “Huh?” about a week later.
In every occurrence of this, the solution was that the enterprise company gave us the credentials to their team agent account. That isn’t particularly a secure approach, but it is the most efficient one. It becomes more interesting with iTunes Connect because an email address can only be a member of one iTunes Connect portal – so even though iTunes Connect allows administrator level accounts the access they need to work, our emails are already tied to our company’s account or some other company’s account. Again, the credentials to the iTunes Connect owner account has been the solution for this as well.
I’m not sure what the solution is here. One part of me wants a process more like Google Play Store, where builds are automatically uploaded through CI tools into an Alpha channel and can be promoted through Beta into distribution. The issue here – which is somewhat of an issue even with the Play Store’s process – is that the builds we’re distributing to testers often have a different environment (i.e., pointing to a development server) than the one we’re distributing to the world. Since only one build per version is really ‘active’ – a multi-build system for different environments of the same application doesn’t really work.
Again, I have no idea what the solution is to this – perhaps being able to modify keys in the Info.plist and re-signing an existing build within the portal would work, but that still doesn’t guarantee anything and it would require another review pass.
If I think about what an ideal solution would be, I boil it down to two distinct workflows: getting builds into a distribution portal and distributing those builds to the right audience.
Getting builds into the distribution portal should be available to all developers on the team (where those developers may not be employed by the owner of the product), should ensure that the appropriate branch and scheme is built and should ideally be automated. I’d also like to be able to support multiple environments.
For distribution, what I’ve really seen is that there are five different audiences: developers on the project, people close to the project but in a more product or management oriented role, people responsible for QA, ‘higher ups’ that have a stake in the project but are not close to development and the deployment audience.
Developers on the project can deploy to their own device via Xcode whenever they want. Product/management teams on the project typically need frequent updates, but aren’t going to deploy via Xcode (these are what I think of as ‘internal testers’). QA folks get less frequent builds than the first two groups, and also require an easier solution than building via Xcode and likely should not have access to anything but build products (these folks toe the line between internal and external testers). The higher ups get builds infrequently and won’t be bothered with a solution other than ‘I click this button on my email and I get the app.’; collecting UDIDs is out of the question. And of course, the final audience gets the least frequent updates.
What would also be great is if the time spent reviewing the builds that go through some of these earlier audiences could either minimize or eliminate review time to deploy to the world.
If I’m missing something that accomplishes tasks like these, I’d definitely like to hear it.