Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deploy to Testflight using Travis-CI
language: objective-c
before_script:
- chmod +x scripts/travis/add-key.sh
- chmod +x scripts/travis/remove-key.sh
- chmod +x scripts/travis/testflight.sh
- ./scripts/travis/add-key.sh
script: xctool -workspace [Workspace name].xcworkspace -scheme '[Scheme to use]' -configuration [Build configuration name] -sdk iphoneos7.1 CONFIGURATION_BUILD_DIR='~/build/' build
after_success:
- ./scripts/travis/testflight.sh
after_script:
- ./scripts/travis/remove-key.sh
env:
global:
- DISTRIBUTION_LISTS="[Comma separated Testflight distributions lists]"
- APPNAME="[Name of .app file]"
- 'DEVELOPER_NAME="iPhone Distribution: [Organization name] ([User ID])"'
- PROFILE_NAME=[Name of provisioning file]

How to automagically deploy to Testflight using Travis-CI

  1. Copy the .travis.yml into your repo and edit it
    1. Replace [Workspace name] with your workspace name. If you don't have a .workspace file and wish to use your .xcodeproj file replace the -workspace flag with a -project flag followed by your project name.
    2. Replace [Scheme to use] with the Scheme you wish to use.
    3. Replace [Build configuration name] with the build configuration you want to use.
    4. Replace [Comma separated Testflight distributions lists] with the Testflight distributions lists.
    5. Replace [Name of .app file] with the name of your App. In most cases it's same name as your project name.
    6. Replace [Organization name] with the name of the organization defined in the certificate you will use to sign this App. You'll find this in your keychain. If the certificate has ([User ID]) at the end, don't forget to update [User ID]. If not, delete ([User ID]) and the brackets surrounding it.
    7. Replace [Name of provisioning file] with the file name of your provisioning file name without the extension.
  2. Create the folders "scripts/travis/profile"
  3. Export the following things from the Keychain app
    1. "Apple Worldwide Developer Relations Certification Authority" to scripts/travis/apple.cer
    2. Your iPhone Distribution certificate to scripts/travis/dist.cer
    3. Your iPhone Distribution private key to scripts/travis/dist.p12 (Important to choose a proper password)
  4. Execute travis encrypt "KEY_PASSWORD=[Your .p12 password]" --add
  5. Execute travis encrypt "TEAM_TOKEN=[Testflight team token]" --add
    1. You'll find your Team token here
  6. Execute travis encrypt "API_TOKEN=[Testflight API token]" --add
    1. You'll find your API token here
  7. Copy add-key.sh, remove-key.sh and testflight.sh to scripts/travis
  8. Copy your mobile provisioning profile to scripts/travis/profile/
  9. Stage all the new files, it should be:
    • .travis.yml
    • apple.cer
    • dist.cer
    • dist.p12
    • [Name of provisioning file].mobileprovision
    • add-key.sh
    • remove-key.sh
    • testflight.sh
  10. Commit and push!
  11. That's a Wrapp! ;)

Only sending to Testflight if branch is "build_testflight"

In testflight.sh on row 6 we check which branch is being built. At the moment it will only send it to Testflight if the current branch is named "build_testflight". Feel free to remove this if it doesn't suit your needs :)

security create-keychain -p travis ios-build.keychain
security default-keychain -s ios-build.keychain
security unlock-keychain -p travis ios-build.keychain
security -v set-keychain-settings -lut 86400 ios-build.keychain
security import ./scripts/travis/apple.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASSWORD -T /usr/bin/codesign
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp ./scripts/travis/profile/* ~/Library/MobileDevice/Provisioning\ Profiles/
security delete-keychain ios-build.keychain
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/*
#!/bin/sh
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then
echo "This is a pull request. No deployment will be done."
exit 0
fi
if [[ "$TRAVIS_BRANCH" != "build_testflight" ]]; then
echo "Testing on a branch other than build_testflight. No deployment will be done."
exit 0
fi
# Thanks @djacobs https://gist.github.com/djacobs/2411095
PROVISIONING_PROFILE="$HOME/Library/MobileDevice/Provisioning Profiles/$PROFILE_NAME.mobileprovision"
RELEASE_DATE=`date '+%Y-%m-%d %H:%M:%S'`
OUTPUTDIR="/Users/travis/build"
echo "********************"
echo "* Signing *"
echo "********************"
xcrun -log -sdk iphoneos PackageApplication "$OUTPUTDIR/$APPNAME.app" -o "$OUTPUTDIR/$APPNAME.ipa" -sign "$DEVELOPER_NAME" -embed "$PROVISIONING_PROFILE"
RELEASE_NOTES="This version was uploaded automagically by Travis\nTravis Build number: $TRAVIS_BUILD_NUMBER\nUploaded: $RELEASE_DATE"
zip -r -9 "$OUTPUTDIR/$APPNAME.app.dSYM.zip" "$OUTPUTDIR/$APPNAME.app.dSYM"
echo "********************"
echo "* Uploading *"
echo "********************"
curl http://testflightapp.com/api/builds.json \
-F file="@$OUTPUTDIR/$APPNAME.ipa" \
-F dsym="@$OUTPUTDIR/$APPNAME.app.dSYM.zip" \
-F api_token="$API_TOKEN" \
-F team_token="$TEAM_TOKEN" \
-F distribution_lists=$DISTRIBUTION_LISTS \
-F notes="$RELEASE_NOTES" -v \
-F notify="FALSE"
@boekkooi

This comment has been minimized.

Copy link

commented May 13, 2014

When you unlock the keychain it maybe locked later on due to a timeout.
You can prevent this by adding security -v set-keychain-settings -lut 86400 ios-build.keychain in add-key.sh.
This will set the keychain timeout to 24 hours and that should be enough to build your app.

Special Thanks to Jay Zeschin (http://modeset.com/what-we-know/2013/03/11/jenkins_keychain_timeouts)

@JagCesar

This comment has been minimized.

Copy link
Owner Author

commented May 15, 2014

Thanks @boekkooi, added it :)

@Legoless

This comment has been minimized.

Copy link

commented May 26, 2014

Awesome work. I do have one question. The build fails, if I use default parameters that Travis CI uses:

xcode_workspace: [App name].xcworkspace
xcode_scheme: [Scheme]
xcode_sdk: iphonesimulator7.1

It says that [App name].app does not exist. Any ideas maybe?

@JagCesar

This comment has been minimized.

Copy link
Owner Author

commented Jun 2, 2014

Legoless, have you defined this in your .travis.yml?

env:

  • APPNAME="[Name of .app file]"

PS. Sorry for the late answer, I don't get any notifications when someone posts here :( .DS

@JagCesar

This comment has been minimized.

Copy link
Owner Author

commented Jun 2, 2014

Legoless, now I know why it doesn't work for you. On the following row:

script: xctool -workspace [Workspace name].xcworkspace -scheme '[Scheme to use]' -configuration [Build configuration name] -sdk iphoneos7.1 CONFIGURATION_BUILD_DIR='~/build/' build

I tell the compiler to place the .app file in ~/build. When you are using the default params the compiled .app-file won't be placed there, and thereby not found by the script.

@Legoless

This comment has been minimized.

Copy link

commented Jun 4, 2014

You are correct. Is there any particular reason you are placing the build in home directory?

@JagCesar

This comment has been minimized.

Copy link
Owner Author

commented Jun 12, 2014

Legoless, nope. :)

@cerupcat

This comment has been minimized.

Copy link

commented Sep 19, 2014

Great scripts! Is it possible to add the commit message to the release notes for testflight? I'm just wondering how to get the release notes a little more detailed in terms of what was in this build.

@chrismeyersfsu

This comment has been minimized.

Copy link

commented Oct 1, 2014

Should a corresponding file exist for the -configuration and -scheme directives? Maybe generated by xcode?

More simply, I don't know what to set -configuration and -schema to.

@chrismeyersfsu

This comment has been minimized.

Copy link

commented Oct 17, 2014

Ok, got further in the process. -configuration 'Debug' and -scheme SRDispatcher were required. Now I am having the following error.

+xcrun -log -sdk iphoneos PackageApplication /Users/travis/build/SRDispatcher.app -o /Users/travis/build/SRDispatcher.ipa -sign 'iPhone Distribution: Stadium Runner, LLC (F283G2H72J)' -embed '/Users/travis/Library/MobileDevice/Provisioning Profiles/XC_Ad_Hoc_comstadiumrunnerdispatcher.mobileprovision'
env SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication /Users/travis/build/SRDispatcher.app -o /Users/travis/build/SRDispatcher.ipa -sign iPhone\ Distribution\:\ Stadium\ Runner,\ LLC\ \(F283G2H72J\) -embed /Users/travis/Library/MobileDevice/Provisioning\ Profiles/XC_Ad_Hoc_comstadiumrunnerdispatcher.mobileprovision
error: Failed to read entitlements from '/var/folders/gw/_2jq29095y7b__wtby9dg_5h0000gn/T/It0cBrRabD/Payload/SRDispatcher.app'

Any clue what Failed to read entitlements is all about?

@alexcorre

This comment has been minimized.

Copy link

commented Mar 27, 2015

seeing the same entitlements errors as @chrismeyersfsu. any ideas?

@mhkt

This comment has been minimized.

Copy link

commented Apr 19, 2015

For anyone struggling with the entitlements error @chrismeyersfsu ran into, this change to the code signing build settings fixed it for me:
http://stackoverflow.com/questions/26497863/xcode-6-1-error-while-building-ipa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.