How we integrate & deploy Mobile Apps with Travis CI part 2

Preview:

Citation preview

How we integrate & deploy Mobile Apps with Travis CIMarcio Klepacz, iOS Engineering @ GetYourGuide

Mobile Warsaw, Poland 2015

Overview

Who we are

Problem

Requirements

Solution

Result

Improving

Marcio Klepacz, GetYourGuide

Who we are

GetYourGuide Offers the Largest Travel

Activities Inventory Worldwide

Marcio Klepacz, GetYourGuide

800+

10,600+5,300+

800+

4,000+

2,000+

Marcio Klepacz, GetYourGuide

The Problem

Repetitive

Manual

We want to automate that

Fit our workflow

Developer Happiness

Marcio Klepacz, GetYourGuide

😄Develop

😊

Run

Tests

😐Configure

😒

Build

😠

Write

release

notes

😤

Upload,

notify

users,

etc.

The Requirements

Requirements

Marcio Klepacz, GetYourGuide

Automatically build and test on push

Fit into gitflow workflow (feature, develop and

release) branch

Produce binaries that can be tested (downloaded)

Requirements / Gitflow

Marcio Klepacz, GetYourGuide

Requirements / Gitflow

Marcio Klepacz, GetYourGuide

Requirements / Gitflow

Marcio Klepacz, GetYourGuide

Requirements / Summary

Marcio Klepacz, GetYourGuide

Build an Alpha App with Test Environment

Able to book with dummy credit card

Build a Beta App with the Live Environment

Real content

Build and test on every push

Distribute app to testers from release and develop branches

Relieve developers from repetitive manual tasks

Marcio Klepacz, GetYourGuide

XcodeServer

Jenkins Ship.io Travis CI Circle CI

iOS and Android

✘ ✔︎ ✔︎ ✔︎ ✔︎

Actionsspecific to branches

✔︎ ✔︎ ✔︎ ✔︎

✔︎

Build on push

✔︎ ✔︎ ✔︎ ✔︎ ✔︎

Big community

✔︎ ✔︎ ✘ ✔︎ ✘

Hosted ✘ ✘ ✔︎ ✔︎ ✔︎

The Solution

Travis

Marcio Klepacz, GetYourGuide

Hosted Continuous Integration service

Configuration file in your project (.travis.yml)

Define SDK, build env and output

custom scripts

Connected to Github

Triggers in every push and pull request

Available for many platforms

Travis Setup (.travis.yml)

Marcio Klepacz, GetYourGuide

It’s not using the iPhone SDK

code signing is needed

Doesn’t differentiate between branches

Doesn’t archive

Doesn’t distribute

language: objective-c

xcode_project: MyNewProject.xcodeproj

xcode_scheme: MyNewProjectSharedScheme

iPhone SDK

custom build per branch

generate .ipa

distribute

Import keys (import-keys.sh)

# 1. Create keychain

security create-keychain -p travis ios-build.keychain

# 2. Make as default

security default-keychain -s ios-build.keychain

# 3. Unlock keychain

security unlock-keychain -p travis ios-build.keychain

# 4. Add certificates to keychain

security import ./ios-travis-ci/certificates/dist.cer -k ios-build.keychain -T /usr/bin/codesign

security import ./ios-travis-ci/certificates/dist.p12 -k ios-build.keychain -P $KEY_DIST_PASSWORD -T /usr/bin/codesign

# 5. Copying provisioning profile to Travis

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles

cp ./ios-travis-ci/profiles/*.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

Marcio Klepacz, GetYourGuide

iPhone SDK

custom build per branch

generate .ipa

distribute

Import keys (import-keys.sh)

# 1. Create keychain

security create-keychain -p travis ios-build.keychain

# 2. Make as default

security default-keychain -s ios-build.keychain

# 3. Unlock keychain

security unlock-keychain -p travis ios-build.keychain

# 4. Add certificates to keychain

security import ./ios-travis-ci/certificates/dist.cer -k ios-build.keychain -T /usr/bin/codesign

security import ./ios-travis-ci/certificates/dist.p12 -k ios-build.keychain -P $KEY_DIST_PASSWORD -T /usr/bin/codesign

# 5. Copying provisioning profile to Travis

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles

cp ./ios-travis-ci/profiles/*.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

⛔️️

Marcio Klepacz, GetYourGuide

iPhone SDK

custom build per branch

generate .ipa

distribute

Security

Marcio Klepacz, GetYourGuide

You can encrypt environment variables using

Travis command line tool on your terminal:

~ $ travis encrypt ‘KEY_DIST_PASSWORD=abc123’ –add

Passing the option “--add” will automatically add the secure

key to your .travis.yml

env:

global:

- secure: Pz3cxDffsdafasf34324fdsf232fdsfdsf3fdsf

iPhone SDK

custom build per branch

generate .ipa

distribute

Travis Setup (.travis.yml)

Marcio Klepacz, GetYourGuide

Use iPhone SDK ✅

Doesn’t differentiate between branches

Doesn’t archive

Doesn’t distribute

language: objective-c

env:

global:

- secure: Pz3cxDffsdafasf34324fdsf232fdsfdsf3fdsf

before_script:

- ./scripts/import-key.sh

script:

- xctool -workspace MyNewProject.xcworkspace -scheme MySharedScheme -sdk iphoneos -configuration Beta

iPhone SDK

custom build per branch

generate .ipa

distribute

Building (build_app.sh)

# 1.

xctool -workspace ${APP_NAME}.xcworkspace \

-scheme ${APP_NAME} \

-sdk iphonesimulator test

# 2.

export RELEASE_SUFFIX=".release”

# Bundle Identifier:

#

com.getyourguide.mobile.$(PRODUCT_NAME:rfc1034identifier)${BUNDLE_ID_SUFFIX}${RELEASE_

SUFFIX}

# 3

xctool -workspace ${APP_NAME}.xcworkspace -scheme ${APP_NAME} \

-sdk iphoneos \

-configuration ${APP_BUILD_CONFIG} \

OBJROOT=$PWD/build \

SYMROOT=$PWD/build

Marcio Klepacz, GetYourGuide

iPhone SDK

custom build per branch

generate .ipa

distribute

Travis Setup (.travis.yml)

Marcio Klepacz, GetYourGuide

Use iPhone SDK ✅

Differentiate between branches ✅

Doesn’t archive

Doesn’t distribute

global:

- secure: Pz3cxDffsdafasf34324fdsf232fdsfdsf3fdsf

matrix:

- APP_BUILD_CONFIG=Debug

- APP_BUILD_CONFIG=Beta

before_script:

- ./scripts/import-key.sh

script:

- ./scripts/build-app.sh

iPhone SDK

custom build per branch

generate .ipa

distribute

# 1.

xcrun -sdk iphoneos PackageApplication \

-v ”$BUILD_DIR/$APP_NAME.app" \

-o ”$BUILD_DIR/$APP_NAME.ipa" \

--sign "$DEVELOPER_NAME" \

--embed ”$PROVISIONING_PROFILE"

# 2.

release_notes=`git log --since=1.week --pretty=format:"%an - %s"`

curl \

-F status="2" \

-F notify="0" \

-F release_type="2" \

-F notes="$release_notes" \

-F notes_type="0" \

-F "ipa=@$outputdir/$APP_NAME.ipa" \

-F "mobileprovision=@$provisioning_profile" \

-H "X-HockeyAppToken: ${HOCKEY_APP_TOKEN}" \

https://rink.hockeyapp.net/api/2/apps/upload # Uploading to HockeyApp

Archiving and uploading

(archive_and_upload.sh)

Marcio Klepacz, GetYourGuide

iPhone SDK

custom build per branch

generate .ipa

distribute

Travis Setup (.travis.yml)

Marcio Klepacz, GetYourGuide

Use iPhone SDK ✅

Differentiate between branches ✅

Archive ✅

Distribute ✅

language: objective-c

env:

global:

- secure: Pz3cxDffsdafasf34324fdsf232fdsfdsf3fdsf

before_script:

- ./scripts/import-key.sh

script:

- ./scripts/build-app.sh

after_success:

- ./scripts/archive_and_upload.sh

iPhone SDK

custom build per branch

generate .ipa

distribute

Move the scripts away from the app

repository (Optional)

Marcio Klepacz, GetYourGuide

Maintenance 👍

Reusable 👍

Slower builds 👎

git:

submodules: false

before_install:

- git submodule init ios-travis-ci

- git submodule update --remote --merge ios-travis-ci

Result

Marcio Klepacz, GetYourGuide

Automate tasks

App is distributed

No manual configuration

Different actions between branches

5 different apps to test concurrently

(@banaslee’s phone)

Improving

Some pain left

Marcio Klepacz, GetYourGuide

Provisioning profile included on project 👎

Very long shell script files 👎

Can’t scale 👎

Very Travis dependent👎

Fastlane by @KrauseFx

Marcio Klepacz, GetYourGuide

Lets you define and run your deployment

pipelines for different environments.

Ruby gem

Powerful toolchain

Automates certificates and

prov.profile installs

Flexible

Open source

Fastlane / Example

Marcio Klepacz, GetYourGuide

# ../fastlane/Fastfile

#...

lane :deploy do

# Installing certificates

cert( development: true, username: "cibot@getyourguide.com")

# Fetching and installing proviosning profiles

sigh( adhoc: true, force: true, filename: "myFile.mobileprovision")

# Build project

gym( scheme: "MyApp", workspace: "MyApp.xcworkspace", configuration: ENV["APP_BUILD_CONFIG"])

# Shipping

hockey( api_token: '...', ipa: './app.ipa', notes: "Changelog")

end

#...

Fastlane / Example .travis.yml

Marcio Klepacz, GetYourGuide

language: objective-c

env:

global:

- secure: Pz3cxDffsdafasf34324fdsf232fdsfdsf3fdsf

script:

- bundle exec fastlane deploy

Scalable 👍

Faster 👍

Focused on Apple environment 👎

Thanks for your time@marciok and marcio@getyourguide.com

References

Marcio Klepacz, GetYourGuide

Travis CI for iOS - Mattes Groeger

johanneswuerbach / .travis.yml - Johannes Würbach

The OS X Build Environment - Travis CI

Fastlane - Felix Krause

Recommended