Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Continuous Integration Friday, March 8, 13

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

“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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Maintain a single repository Friday, March 8, 13

Slide 12

Slide 12 text

Automate the build Friday, March 8, 13

Slide 13

Slide 13 text

Build passes or fails Friday, March 8, 13

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Build runs on every commit Friday, March 8, 13

Slide 16

Slide 16 text

Easy to retrieve latest build Friday, March 8, 13

Slide 17

Slide 17 text

Automate Deployment Friday, March 8, 13

Slide 18

Slide 18 text

...more! Friday, March 8, 13

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Friday, March 8, 13

Slide 23

Slide 23 text

Friday, March 8, 13

Slide 24

Slide 24 text

Friday, March 8, 13

Slide 25

Slide 25 text

Friday, March 8, 13

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

⌘B Friday, March 8, 13

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

1command Friday, March 8, 13

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Building the Xcode Project xcodebuild -workspace Foo.xcworkspace \ -scheme Foo \ -sdk iphonesimulator \ -configuration Debug \ ONLY_ACTIVE_ARCH=NO clean build Friday, March 8, 13

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Progress formatter Friday, March 8, 13

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

What about Code Signing? Friday, March 8, 13

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

doc Friday, March 8, 13

Slide 54

Slide 54 text

$ brew install appledoc Friday, March 8, 13

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Friday, March 8, 13

Slide 57

Slide 57 text

Friday, March 8, 13

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

Friday, March 8, 13

Slide 60

Slide 60 text

ocunit2junit.rb Friday, March 8, 13

Slide 61

Slide 61 text

Plug it into Jenkins! Friday, March 8, 13

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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