Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOS Build Automation with Jenkins

iOS Build Automation with Jenkins

Presented at CocoaConf Chicago 2013.

Ben Scheirman

March 08, 2013
Tweet

More Decks by Ben Scheirman

Other Decks in Programming

Transcript

  1. Jenkins
    Your personal butler for
    continuous integration and
    build automation in iOS
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  3. I work for
    Houston, TX
    iOS, Android, Rails,
    Coffee, Beer
    I’m hiring!
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  5. Continuous Integration
    Friday, March 8, 13

    View full-size slide

  6. Integration Problems
    • Machine-specific configuration
    • Merge conflicts
    • Contention on core files (project.pbxproj)
    • Bad changes committed
    • Updating certificates / profiles
    Friday, March 8, 13

    View full-size slide

  7. Actions, Pain, &
    Frequency
    Pain
    Time between actions
    http://martinfowler.com/bliki/FrequencyReducesDifficulty.html
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  10. Fowler’s Tenets of CI
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  12. Automate the build
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  17. Automate Deployment
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. Friday, March 8, 13

    View full-size slide

  23. Friday, March 8, 13

    View full-size slide

  24. Friday, March 8, 13

    View full-size slide

  25. Friday, March 8, 13

    View full-size slide

  26. CI Servers
    • Jenkins
    • Travis
    • TeamCity
    • CruiseControl (.NET)
    • CI Joe
    Friday, March 8, 13

    View full-size slide

  27. Installing Jenkins
    $ brew install jenkins
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  29. More useful plugins
    Github Plugin
    IM Notifier
    Status Monitor
    Hipchat Notifier (or Campfire)
    100’s of others
    Friday, March 8, 13

    View full-size slide

  30. So we have a CI Server,
    now what?
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. ⌘B
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  36. 1command
    Friday, March 8, 13

    View full-size slide

  37. Set up your CI Machine
    just like your Dev
    Machines
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  42. Red / Green Test Output
    https://gist.github.com/subdigital/3931414 * Works best with Kiwi
    Friday, March 8, 13

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  45. Why Xcodebuild-rb?
    • Integration with Rake
    • Easily find BUILT_PRODUCTS_DIR
    • Progress Formatter!
    Friday, March 8, 13

    View full-size slide

  46. Progress formatter
    Friday, March 8, 13

    View full-size slide

  47. Building an IPA
    /usr/bin/xcrun -sdk iphoneos \
    PackageApplication \
    -v \
    "build/Foo.app"
    -o "build/Foo.ipa"
    Friday, March 8, 13

    View full-size slide

  48. What about Code
    Signing?
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  50. Installing certificates
    security unlock -p jenkins jenkins
    security import provisioning/ios_distribution.p12 \
    -k ~/Library/Keychains/jenkins \
    -P jenkins
    Friday, March 8, 13

    View full-size slide

  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

    View full-size slide

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

    View full-size slide

  53. doc
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  56. Friday, March 8, 13

    View full-size slide

  57. Friday, March 8, 13

    View full-size slide

  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

    View full-size slide

  59. Friday, March 8, 13

    View full-size slide

  60. ocunit2junit.rb
    Friday, March 8, 13

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  63. Thanks!
    @subdigital
    @nsscreencast
    @bens (adn)
    http://github.com/subdigital/cocoa-conf-jenkins
    http://speakerdeck.com/u/subdigital/jenkins
    Friday, March 8, 13

    View full-size slide