Continuous integration
for
iOS projects
Aleksandra Gavrilovska
Netcetera
355
AGENDA

>  iOS App Distribution Process
>  Practices of Continuous Integration
>  Jenkins
   –  How to configure slave
   –  How to configure job
>  Build system at Netcetera
   –  Overview of rake tasks
   –  Benefits
   –  Improvements




                                         2
iOS App Distribution Process




                               3
Practices of Continuous Integration


>    Maintain a code repository
>    Automate the build
>    Make the build self-testing
>    Everyone commits to the baseline every day
>    Every commit (to baseline) should be built
>    Keep the build fast
>    Test in a clone of the production environment
>    Make it easy to get the latest deliverables
>    Everyone can see the results of the latest build
>    Automate deployment


                                                        4
overview

>    Open source continuous integration service provider
>    Runs in servlet container such as Apache Tomcat
>    iOS Projects MUST be build on Mac
>    Jenkins instances as slaves




                                                           5
Configuring Jenkins Mac Slave




                                6
Create New Job

>  Properties that must be set




                                 7
Custom build system


>  Implemented in Ruby
>  Rake wrapper around xcodebuild
   –  Rakefile
   –  Several Ruby scripts
   –  Included in our xCode project templates




                                                8
Rakefile

xcode_project :"___PROJECTNAME___" do!
  # The artifact_id is a alias for the main Xcode target!
  artifact_id           "___ARTIFACT_ID___”!
  project_id            "___PROJECT_ID___"!
  group_id              "___GROUP_ID___"!
  svn                   "___SVN___"!
!
  release_destination "http://buildfs.group.nca/dav/projects/___PROJECTNAME___/
release/"!
  snapshot_destination "http://buildfs.group.nca/dav/projects/___PROJECTNAME___/
snapshots/"!
!
  itunes_artwork "src/main/resources/iTunesArtwork”!
!
  adhoc_package "NetceteraAdhoc" do!
     identity "iPhone Distribution: Netcetera AG"!
     # by default the provisioning profile used will be src/packaging/
ADHOC_PACKAGE_NAME.mobileprovision!
     # you can override by using!
     # provisioning_profile "path to provisioning profile"!
  end!
end!

                                                                              9
Rake tasks
agavrilo-2:agavrilo$ rake –tasks!
rake build             # Invokes xcode build to compile the project!
rake ci                 # Invoked by the CI system!
rake clean              #   Cleans the project!
rake package            #   Creates the packages!
rake release            #   Performs a release!
rake release:rollback   #   [TBD]!
rake report             #   Reports to techISR.!
rake symbolicate        #   Symbolicates the crash report provided under the
   REPORT variable.!
rake test               # Invokes The tests!
rake uitest             # Run Cucumber features!
!
!
task "ci"     => "deliver-snapshot”!
task "deliver-snapshot" => "package” !
task "package" => ["appstore-package", "adhoc-packages"]!
!
!                                                                              10
Test execution

>  rake test!
>  GHUnit as testing framework
>  Jenkins can run GHUnit tests
     –    http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_ci.html!
>    UnitTest target should Run Script
>    Tests are executed on Simulator
>    JUnit test result report is created (XML file)
>    Reports to internal reporting tool




                                                                                   11
Packaging


>    rake package!
>    ‘Release’ configuration must exist in project scheme!
>    Creates app store package
>    .dSYM file is stored
>    Creates adhoc packages by resigning the app store packages
     –  Decreases the build time
     –  App store and adhoc application are both identical!




                                                                  12
Deployment


>  rake delivery!
>  Deploys all artifacts to snapshot_destination!
   –  All provisioning profiles
   –  App store build
   –  .dSYM package
   –  *.ipa packages
>  Ready to be fetched for testing or submission in iTunes Connect




                                                                     13
Debugging: Symbolicate crash


 >  rake symbolicate REPORT=path_to_report!
    –  REPORT can be a path to directory
 >  Extract the uuid from the crash report
lines = File.readlines(report).map {|line| line.tr("rn", '')}!
!
line = lines[lines.index("Binary Images:") + 1]!
!
line.match(/armv[67] +<[0-9a-z]+>/)[0].split(' ').map {|entry| entry.tr("<>", '')}!

 >  find the appropriate (matching) build on the DAV server
 "No snapshot can be found that matches uuid: #{uuid}, for
    architecture: #{arch}”!
 >  download it
 >  unpack it
 >  symbolicate it
                                                                              14
Conclusion


>  Benefits
   –  Not dependent on xCode version
   –  Control of the build process
   –  Control of the project state
   –  Applications are always ready to be tested
   –  Debugging
   –  Scalable and configurable build system
       • build of workspace
       • Installation of pods



>  Improvements
   –  Installation of certificates in keychain
   –  Check for code duplicates
   –  Check style
                                                   15
Questions




            16
Aleksandra Gavrilovska
Netcetera


aleksandra.gavrilovska@netcetera.com

Jazoon12 355 aleksandra_gavrilovska-1

  • 1.
  • 2.
    AGENDA >  iOS AppDistribution Process >  Practices of Continuous Integration >  Jenkins –  How to configure slave –  How to configure job >  Build system at Netcetera –  Overview of rake tasks –  Benefits –  Improvements 2
  • 3.
  • 4.
    Practices of ContinuousIntegration >  Maintain a code repository >  Automate the build >  Make the build self-testing >  Everyone commits to the baseline every day >  Every commit (to baseline) should be built >  Keep the build fast >  Test in a clone of the production environment >  Make it easy to get the latest deliverables >  Everyone can see the results of the latest build >  Automate deployment 4
  • 5.
    overview >  Open source continuous integration service provider >  Runs in servlet container such as Apache Tomcat >  iOS Projects MUST be build on Mac >  Jenkins instances as slaves 5
  • 6.
  • 7.
    Create New Job > Properties that must be set 7
  • 8.
    Custom build system > Implemented in Ruby >  Rake wrapper around xcodebuild –  Rakefile –  Several Ruby scripts –  Included in our xCode project templates 8
  • 9.
    Rakefile xcode_project :"___PROJECTNAME___" do! # The artifact_id is a alias for the main Xcode target! artifact_id "___ARTIFACT_ID___”! project_id "___PROJECT_ID___"! group_id "___GROUP_ID___"! svn "___SVN___"! ! release_destination "http://buildfs.group.nca/dav/projects/___PROJECTNAME___/ release/"! snapshot_destination "http://buildfs.group.nca/dav/projects/___PROJECTNAME___/ snapshots/"! ! itunes_artwork "src/main/resources/iTunesArtwork”! ! adhoc_package "NetceteraAdhoc" do! identity "iPhone Distribution: Netcetera AG"! # by default the provisioning profile used will be src/packaging/ ADHOC_PACKAGE_NAME.mobileprovision! # you can override by using! # provisioning_profile "path to provisioning profile"! end! end! 9
  • 10.
    Rake tasks agavrilo-2:agavrilo$ rake–tasks! rake build # Invokes xcode build to compile the project! rake ci # Invoked by the CI system! rake clean # Cleans the project! rake package # Creates the packages! rake release # Performs a release! rake release:rollback # [TBD]! rake report # Reports to techISR.! rake symbolicate # Symbolicates the crash report provided under the REPORT variable.! rake test # Invokes The tests! rake uitest # Run Cucumber features! ! ! task "ci" => "deliver-snapshot”! task "deliver-snapshot" => "package” ! task "package" => ["appstore-package", "adhoc-packages"]! ! ! 10
  • 11.
    Test execution >  raketest! >  GHUnit as testing framework >  Jenkins can run GHUnit tests –  http://gabriel.github.com/gh-unit/docs/appledoc_include/guide_ci.html! >  UnitTest target should Run Script >  Tests are executed on Simulator >  JUnit test result report is created (XML file) >  Reports to internal reporting tool 11
  • 12.
    Packaging >  rake package! >  ‘Release’ configuration must exist in project scheme! >  Creates app store package >  .dSYM file is stored >  Creates adhoc packages by resigning the app store packages –  Decreases the build time –  App store and adhoc application are both identical! 12
  • 13.
    Deployment >  rake delivery! > Deploys all artifacts to snapshot_destination! –  All provisioning profiles –  App store build –  .dSYM package –  *.ipa packages >  Ready to be fetched for testing or submission in iTunes Connect 13
  • 14.
    Debugging: Symbolicate crash >  rake symbolicate REPORT=path_to_report! –  REPORT can be a path to directory >  Extract the uuid from the crash report lines = File.readlines(report).map {|line| line.tr("rn", '')}! ! line = lines[lines.index("Binary Images:") + 1]! ! line.match(/armv[67] +<[0-9a-z]+>/)[0].split(' ').map {|entry| entry.tr("<>", '')}! >  find the appropriate (matching) build on the DAV server "No snapshot can be found that matches uuid: #{uuid}, for architecture: #{arch}”! >  download it >  unpack it >  symbolicate it 14
  • 15.
    Conclusion >  Benefits –  Not dependent on xCode version –  Control of the build process –  Control of the project state –  Applications are always ready to be tested –  Debugging –  Scalable and configurable build system • build of workspace • Installation of pods >  Improvements –  Installation of certificates in keychain –  Check for code duplicates –  Check style 15
  • 16.
  • 17.