title: How do I deploy automated builds to TestFlight from an Xcode Bot?
body: <p>I spent a good amount of time formatting the mentioned blog with code, screenshots, and etc. that is too much effort to duplicate here on Stack Overflow. That said I figured the community would want some help in this arena (I struggled for a long time figuring it all out), so I posted this question and respective answer. If you still think that the intent of this post is nefarious, please comment as such and I'll delete it!</p>
  
  <p>The question is: how do I configure my fancy new Xcode server with Bots to continuously integrate and send completed builds to my testers via test flight? To me, this seems like the holy grail of CI in the iOS world, so I spent a lot of time to figure it out.</p>
  
  <p>The process involves some manual work that just doesn't seem to get done properly by the XCode server software in Mavericks, at least in the initial release. It took me a lot of time and even some scripting to figure it all out and make it work, and I'm happy to share the results.</p>
  
  <p>For the sake of adding value to this question, I've posted the post-op script that you should run during the Archive process below. The link to my blog below provides step by step details should you need more information.</p>
  
  <pre><code>#!/bin/bash
  #
  # (Above line comes out when placing in Xcode scheme)
  #
  # Valid and working as of 10/29/2013
  # Xcode 5.0.1, XCode Server 
  #
  API_TOKEN="&lt;Your TesFlight API Token&gt;"
  TEAM_TOKEN="&lt;Your TestFlight Team Token&gt;"
  DISTRIBUTION_LISTS="&lt;Comma separated TestFlight Distribution List Names for auto deploy&gt;"
  PROVISIONING_PROFILE="/Library/Server/Xcode/Data/ProvisioningProfiles/&lt;your file name here&gt;.mobileprovision"
  #EXAMPLE:"/Library/Server/Xcode/Data/ProvisioningProfiles/DocLink_InHouse_2013.mobileprovision"
  
  SIGNING_IDENTITY="&lt;your provisioning profile name here&gt;"
  #EXAMPLE:"iPhone Distribution: Unwired Revolution, LLC."
  
  # DO NOT EDIT BELOW HERE!
  ########################################
  DSYM="/tmp/Archive.xcarchive/dSYMs/${PRODUCT_NAME}.app.dSYM"
  
  IPA="/tmp/${PRODUCT_NAME}.ipa"
  
  APP="/tmp/Archive.xcarchive/Products/Applications/${PRODUCT_NAME}.app"
  
  # Clear out any old copies of the Archive
  echo "Removing old Archive files from /tmp...";
  /bin/rm -rf /tmp/Archive.xcarchive*
  
  #Copy over the latest build the bot just created
  echo "Copying latest Archive to /tmp/...";
  LATESTBUILD=$(ls -1rt /Library/Server/Xcode/Data/BotRuns | tail -1)
  /bin/cp -Rp "/Library/Server/Xcode/Data/BotRuns/${LATESTBUILD}/output/Archive.xcarchive" "/tmp/"
  
  echo "Creating .ipa for ${PRODUCT_NAME}"
  /bin/rm "${IPA}"
  /usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "${IPA}" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"
  
  echo "Done with IPA creation."
  
  echo "Zipping .dSYM for ${PRODUCT_NAME}"
  /bin/rm "${DSYM}.zip"
  /usr/bin/zip -r "${DSYM}.zip" "${DSYM}"
  
  echo "Created .dSYM for ${PRODUCT_NAME}"
  
  echo "*** Uploading ${PRODUCT_NAME} to TestFlight ***"
  /usr/bin/curl "http://testflightapp.com/api/builds.json" \
  -F file=@"${IPA}" \
  -F dsym=@"${DSYM}.zip" \
  -F api_token="${API_TOKEN}" \
  -F team_token="${TEAM_TOKEN}" \
  -F distribution_lists="${DISTRIBUTION_LISTS}" \
  -F notes="Build uploaded automatically from Xcode Server Bot."
  
  echo "TestFlight upload finished!"
  </code></pre>
  
  <p>I hope all the time I spent on it will save the community collectively a lot more of theirs!</p>
  
  <p>Here is the link: <a href="http://matt.vlasach.com/xcode-bots-hosted-git-repositories-and-automated-testflight-builds/" rel="noreferrer">http://matt.vlasach.com/xcode-bots-hosted-git-repositories-and-automated-testflight-builds/</a></p>