Posts – Page 3

Using Xcode 8’s New Automatic Signing with Jenkins and Fastlane

Please see this update here: Finding Provisioning Profiles by Name Rather than UUID.

With Xcode 8, Apple have provided a new code signing system which aims to make it much easier to deal with code signing on projects. It provides an ‘Automatic’ code signing management. This seems like a great idea and is a much better system than the old ‘fix issues’ button. However it’s automatic nature actually doesn’t work very well on CI build systems such as the one we have using Jenkins and Fastlane.

A great introduction to the new code signing process and where you should start is Samantha Marshall’s excellent blog post on Migrating Code Signing Configurations to Xcode 8 (and also a recap on what Xcode 7 does).

The crux of the issue is that the new automatic signing system attempts to manage the provisioning profiles directly within Xcode itself. Which is a nice idea. But, doesn’t work unless you actually interactively run Xcode. It is useless for when you are running a headless CI system doing automated builds. Not only that, but I have a bit of an aversion to anything too ‘magic’ in automated deployments. Borrowing from the Zen of Python:

“Explicit is better than Implicit.”

I want to pin down my CI system such that when it builds a package I know exactly what it is doing and what provisioning profile it will be using.

What we would like to achieve:

  1. Allow the developers to use automatic provisioning on their local environments so that they can easily sign apps for deployment to their local testing devices
  2. To override anything set above such that we use a specific provisioning profile already set up on the Apple Developer Portal and downloaded using sigh as part of Fastlane. This means we add/remove device UUIDs and entitlements via the Apple Developer Portal.
  3. To allow us to have multiple build types: develop, feature, and release that we use for the different code streams we have during development.

To get this to work we have to do two things:

  1. Explicitly change the ProvisioningStyle to manual in the project.pbxproj file. Whilst ugly, the best way I’ve found to do this is to alter the file itself.

  2. Pass in a .xcconfig file as a parameter to gym in our Fastlane file.

So our logic for this part of the Fastlane file looks like:

      # Set the provisioning style to manual "sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ../#{project}/project.pbxproj"

      if configuration == 'Release' 
            app_identifier: 'com.enquos.totalhealth',
           configuration: configuration,
           xcconfig: 'TotalHealth-release.xcconfig',
      elsif configuration == 'Feature'
            app_identifier: 'com.enquos.totalhealth.feature',
            adhoc: '1',
           configuration: configuration,
           xcconfig: 'TotalHealth-feature.xcconfig',
            app_identifier: 'com.enquos.totalhealth.develop',
            adhoc: '1',
           configuration: configuration,
           xcconfig: 'TotalHealth-develop.xcconfig',

Then in the .xcconfig files we have the settings we need to manually set. E.g. TotalHealth-develop.xcconfig contains:

PROVISIONING_PROFILE_app = f3f8d4cb-a975-4529-8dcd-60e277d92fae
CODE_SIGN_IDENTITY = iPhone Distribution: Legacy Parts Corporation (9Q5433VBYW)

A couple of notes:

  1. The PROVISIONING_PROFILE_SPECIFIER is kept blank. This is because this is only used then doing automatic provisioning
  2. The indirection of PROVISIONING_PROFILE_app and PROVISIONING_PROFILE means that the profile will only be used to sign the app itself and not the pods as they are built.
  3. We set the CODE_SIGN_IDENTITY and CODE_SIGN_IDENTITY to override anything the developers might have set in their local configuration.
  4. We have a separate file for develop, feature and release builds of our app. They have a different provisioning profile UUID specified.

I’d love to have a better way to set the provisioning style to manual if possible. I did try to see if I could override it in the .xcconfig file, but alas it doesn’t seem you can.

Uploading Git Changelog to Fabric Beta for Android Gradle Builds in Jenkins

The git changelog is not exposed as a variable in Jenkins for pipeline builds to use. This is how we got it and send it via Gradle to Fabric Beta when we distribute our automated builds

Global Build Numbers in Jenkins Multibranch Pipeline Builds

We wanted to have build numbers that were unique and incremental across all of our build jobs. Here is how I did it with a small python microservice.

Jenkins 2.0 and Multi-branch pipeline builds for iOS apps with Fastlane

Jenkins 2.0 beta is out and has included a multi-branch pipeline plugin that allows automatic build of feature branches from Github. Here is how I set it up to build feature branch builds of our iOS apps

Getting Proper UTF-8 Output From Fastlane on Jenkins 2.0 Pipeline builds

Jenkins 2.0 pipeline jobs get their locale from the master not slave, so you need to set the local on master to get UTF-8 output working correctly

Safer deleting of a directory

A safer alternative to rm -rf for use in scripts

Jenkins, Github, and IPv6

Github and some other sites don't yet support IPv6. But I want our build servers to be IPv6 only. Here is how I achieved it using OpenBSD's NAT64 and unbound's DNS64 functions

Smart Nation Singapore - Bristol Festival of Ideas - Festival of the Future City

Singapore aims to be the world’s first Smart Nation, with fuller use of technology to live, work and play resulting in improved quality of life for individuals; business opportunities for enterprises; and a government that uses technology to better serve and anticipate citizens’ needs.

NSScotland 2015 Conference

A write up of some of the talks I found interesting at the NSScotland conference in Edinburgh. Dealing with maps; Building a mental health app; Working with distributed teams; and a 30-year old calculator codebase

Force git to use ssh instead of HTTPS

Sometimes you have tools that reference a github url with https and you want them to use ssh instead so your ssh key works