iOS Build Automation with Jenkins

iOS Build Automation with Jenkins

Presented at CocoaConf Chicago 2013.

023a6a37e8177cb2f84a236bbce643cf?s=128

Ben Scheirman

March 08, 2013
Tweet

Transcript

  1. Jenkins Your personal butler for continuous integration and build automation

    in iOS Friday, March 8, 13
  2. Hi, I’m Ben @subdigital (Twitter) @bens (adn) benscheirman.com Friday, March

    8, 13
  3. I work for Houston, TX iOS, Android, Rails, Coffee, Beer

    I’m hiring! Friday, March 8, 13
  4. I make screencasts Weekly screencasts on iOS Development $9/month http://nsscreencast.com

    NSScreencast Friday, March 8, 13
  5. Continuous Integration Friday, March 8, 13

  6. Integration Problems • Machine-specific configuration • Merge conflicts • Contention

    on core files (project.pbxproj) • Bad changes committed • Updating certificates / profiles Friday, March 8, 13
  7. Actions, Pain, & Frequency Pain Time between actions http://martinfowler.com/bliki/FrequencyReducesDifficulty.html Friday,

    March 8, 13
  8. When something is painful, do it more often Friday, March

    8, 13
  9. “Many teams find that this approach leads to significantly reduced

    integration problems and allows a team to develop cohesive software more rapidly” - Martin Fowler Friday, March 8, 13
  10. Fowler’s Tenets of CI Friday, March 8, 13

  11. Maintain a single repository Friday, March 8, 13

  12. Automate the build Friday, March 8, 13

  13. Build passes or fails Friday, March 8, 13

  14. Everyone commits to master every day Friday, March 8, 13

  15. Build runs on every commit Friday, March 8, 13

  16. Easy to retrieve latest build Friday, March 8, 13

  17. Automate Deployment Friday, March 8, 13

  18. ...more! Friday, March 8, 13

  19. Ben's Tenet of CI: Friday, March 8, 13

  20. GIVE A CRAP WHEN THE BUILD IS BROKEN Friday, March

    8, 13
  21. Build a culture concerned with quality Friday, March 8, 13

  22. Friday, March 8, 13

  23. Friday, March 8, 13

  24. Friday, March 8, 13

  25. Friday, March 8, 13

  26. CI Servers • Jenkins • Travis • TeamCity • CruiseControl

    (.NET) • CI Joe Friday, March 8, 13
  27. Installing Jenkins $ brew install jenkins Friday, March 8, 13

  28. Useful plugins Git plugin Xcode Testflight Sounds HTML Publisher Friday,

    March 8, 13
  29. More useful plugins Github Plugin IM Notifier Status Monitor Hipchat

    Notifier (or Campfire) 100’s of others Friday, March 8, 13
  30. So we have a CI Server, now what? Friday, March

    8, 13
  31. Have it run the build on every commit Friday, March

    8, 13
  32. What is “the build” ? Friday, March 8, 13

  33. ⌘B Friday, March 8, 13

  34. A Definition of “the Build” Friday, March 8, 13

  35. Compiles Runs Static Analyzer Runs Unit Tests Packages IPAs Generates

    Documentation Archives dSYMs Uploads to Testflight Increments build number Installs the latest distribution certificates & profiles Publishes Code Coverage Reports Inspects for code smells Friday, March 8, 13
  36. 1command Friday, March 8, 13

  37. Set up your CI Machine just like your Dev Machines

    Friday, March 8, 13
  38. Our Mission: Figure out how to do all that.... ON

    THE COMMAND LINE Friday, March 8, 13
  39. Rake Easy Awesome Better than Bash scripting Friday, March 8,

    13
  40. Building the Xcode Project xcodebuild -workspace Foo.xcworkspace \ -scheme Foo

    \ -sdk iphonesimulator \ -configuration Debug \ ONLY_ACTIVE_ARCH=NO clean build Friday, March 8, 13
  41. Running Tests xcodebuild -workspace Foo.xcworkspace \ -scheme Foo \ -sdk

    iphonesimulator \ -configuration Debug \ ONLY_ACTIVE_ARCH=NO TEST_AFTER_BUILD=YES \ clean build Friday, March 8, 13
  42. Red / Green Test Output https://gist.github.com/subdigital/3931414 * Works best with

    Kiwi Friday, March 8, 13
  43. Xcodebuild-rb XcodeBuild::Tasks::BuildTask.new do |t| t.sdk = "iphoneos" t.configuration = "Release"

    t.workspace = workspace t.scheme = scheme t.add_build_setting("ONLY_ACTIVE_ARCH", "NO") t.after_build do |build| derived_dir = build.environment['BUILT_PRODUCTS_DIR'] `rm -rf #{output_dir} && mkdir -p #{output_dir}"` `cp -R #{derived_dir}/* #{output_dir}"` end t.formatter = XcodeBuild::Formatters::ProgressFormatter.new end Friday, March 8, 13
  44. Xcodebuild-rb $ rake -T rake xcode:archive # Creates an archive

    build of the specified target(s). rake xcode:build # Builds the specified target(s). rake xcode:clean # Cleans the build using the same build settings. rake xcode:cleanbuild # Builds the specified target(s) from a clean slate. rake xcode:install # Builds and installs the target rake xcode:settings # Prints the full Xcode build settings Friday, March 8, 13
  45. Why Xcodebuild-rb? • Integration with Rake • Easily find BUILT_PRODUCTS_DIR

    • Progress Formatter! Friday, March 8, 13
  46. Progress formatter Friday, March 8, 13

  47. Building an IPA /usr/bin/xcrun -sdk iphoneos \ PackageApplication \ -v

    \ "build/Foo.app" -o "build/Foo.ipa" Friday, March 8, 13
  48. What about Code Signing? Friday, March 8, 13

  49. Installing certificates TIP: create a keychain for Jenkins Friday, March

    8, 13
  50. Installing certificates security unlock -p jenkins jenkins security import provisioning/ios_distribution.p12

    \ -k ~/Library/Keychains/jenkins \ -P jenkins Friday, March 8, 13
  51. Dir["provisioning/*.mobileprovision"].each do |f| `scripts/install_provisioning_profile.sh #{f}` end Installing Provisioning Profiles https://gist.github.com/subdigital/5049635

    Friday, March 8, 13
  52. BOOM. Renewed Certificate? Updated ad-hoc profile? just drop in provisioning/

    Friday, March 8, 13
  53. doc Friday, March 8, 13

  54. $ brew install appledoc Friday, March 8, 13

  55. Generating Appledoc appledoc \ --project-name Foo \ --project-company "Acme, Inc"

    \ --company-id com.acme \ --output docs \ --create-html \ --no-create-docset \ --ignore Pods \ --keep-intermediate-files . Friday, March 8, 13
  56. Friday, March 8, 13

  57. Friday, March 8, 13

  58. Uploading to Testflight /usr/bin/curl "http://testflightapp.com/api/builds.json" \ -F file=@"build/Foo.ipa" \ -F

    dsym=@"build/Foo.app.dSYM.zip" \ -F api_token="..." \ -F team_token="..." \ -F notes=@"RELEASE_NOTES" Friday, March 8, 13
  59. Friday, March 8, 13

  60. ocunit2junit.rb Friday, March 8, 13

  61. Plug it into Jenkins! Friday, March 8, 13

  62. Links • http://www.martinfowler.com/articles/continuousIntegration.html • http://martinfowler.com/bliki/FrequencyReducesDifficulty.html • http://jenkins-ci.org • https://gist.github.com/subdigital/3931414 (Test

    w/ colored output) • https://gist.github.com/subdigital/5049635 (Install provisioning profiles) Friday, March 8, 13
  63. Thanks! @subdigital @nsscreencast @bens (adn) http://github.com/subdigital/cocoa-conf-jenkins http://speakerdeck.com/u/subdigital/jenkins Friday, March 8,

    13