詳解Fastfile

011714704c4a925e542d426d4cdaa4e3?s=47 giginet
September 01, 2018

 詳解Fastfile

011714704c4a925e542d426d4cdaa4e3?s=128

giginet

September 01, 2018
Tweet

Transcript

  1. ৄղFastfile iOSDC 2018 @giginet

  2. ୭ • @giginet • Cookpad Inc. ٕज़෦ϞόΠϧج൫άϧʔϓ • Core contributor

    of fastlane
  3. None
  4. ର৅ • ͢ͰʹfastlaneΛಋೖ͍ͯ͠Δਓ • ಋೖํ๏ͳͲʹ͍ͭͯ͸͋·Γ৮Ε·ͤΜ • RubyͰͷ։ൃʹ׳Ε͍ͯͳ͍ਓ

  5. Agenda • fastlane׆༻ࣄྫ঺հ • ࠷ڧͷFastfileͷॻ͖ํ • ໌೔͔Β࢖͑Δศརػೳ • Ξϯνύλʔϯू •

    ޮ཰తσόοάख๏ͷ঺հ
  6. fastlane׆༻ࣄྫू

  7. ίʔυϨϏϡʔ

  8. ϦϦʔεϑϩʔ؅ཧ

  9. αϒϛοτ • CIͰϦϦʔεϏϧυͯ͠AppStore Connectʹαϒ ϛοτ • ΞϓϦ͝ͱʹҟͳͬͨϦϦʔεϑϩʔ • Slack͔ΒλάΛࢦఆͯ͠δϣϒΛىಈ •

    ຖिࣗಈతʹϦϦʔε
  10. None
  11. None
  12. ࣾ಺޲͚Ϗϧυ • masterΛࣗಈͰEnterpriseϥΠηϯεͰϏϧυͯ͠ ഑৴αʔϏεͰࣾ಺഑৴ • ಛఆͷϥϕϧ͕͍ͭͨPR΋ಈ࡞֬ೝ༻ʹ഑৴

  13. ࣾ಺޲͚Ϗϧυ

  14. ࣾ಺޲͚Ϗϧυ

  15. None
  16. એ఻ • ಈ࡞֬ೝͷͨΊͷࣾ಺ΞϓϦ഑৴αʔϏεΛ৽ͨʹ࡞ͬ ͨ࿩

  17. ϝτϦΫεऩू

  18. ͋Γ͕ͪͳ͜ͱ • ͳΜͰ΋Fastfileʹॻ͖͕ͪ • ͳΜͰ΋Ͱ͖ΔͷͰϩδοΫ૿͕͑ͪ • ஌Βͳ͍͏ͪʹյΕ͍ͯΔ • fastlane͓͡͞Μ͕͍Δ

  19. ࠷ߴͷFastfileͷॻ͖ํ

  20. Fastfileͷॻ͖ํʢجຊฤʣ

  21. Fastfile • جຊతʹ͸Ruby • FastlaneͷଞͷΞΫγϣϯ͕؆୯ʹݺ΂Δ • ศརͳಠࣗػೳ͕͍͔ͭ͋͘Δ

  22. private_lane • ಺෦తʹ͔࣮͠ߦͰ͖ͳ͍lane • ڞ௨ॲཧͳͲΛ·ͱΊΔͷʹศར • ΄͔ͷlane͔Βݺ΂Δ

  23. private_lane :build_for_appstore do |params| scheme = params[:scheme] build_ios_app(scheme: scheme) end

    lane :release do build_for_appstore(scheme: 'MyApp') end Ҿ਺ ผͷMBOF͔Βݺ΂Δ
  24. private_lane VS def • private_lane͸಺෦తʹ͸ProcʹͳΔͷͰॻ͖ํ͕ ҟͳΔ • Rubyͷdef͸ؔ਺ΦϒδΣΫτͰ͸ͳ͍

  25. private_lane :build_for_appstore do |params| next unless params[:scheme] build_ios_app end SFUVSOͰ͸ͳ͍

  26. import • ڊେͳFastfileΛ෼ׂͰ͖Δ

  27. # vim: syntax=ruby lane :release do build_for_appstore end import 'ReleaseFastfile'

    fastlane/ReleaseFastfile fastlane/Fastfile
  28. None
  29. GitHubͰͷγϯλοΫεϋΠϥΠτ • Fastfile΍ओཁͳ~file͸ࣗಈతʹRubyͱͯ͠ѻΘΕΔ • ϑΝΠϧ໊Λม͑ͨͱ͖ʹਖ਼ৗʹϋΠϥΠτ͞Εͳ͍໰୊ • ϑΝΠϧͷ1ߦ໨ʹϚδοΫίϝϯτΛهड़͢Δ # vim: syntax=ruby

  30. None
  31. Advanced Feature • ެࣜυΩϡϝϯτͷAdvanced͕ৄ͍͠ • https://docs.fastlane.tools/advanced/

  32. Fastfile • ͳΜͰ΋ॻ͚͕ͪ • = Ruby • ͳΜͰ΋ॻ͖͕ͪ • ʹFastfile͕ͲΜͲΜංେԽ͍ͯ͘͠

  33. ಡΈ΍͍͢Fastfile΁

  34. Q. ࠷ߴͷFastfileͱ͸

  35. A. ແ

  36. ͦ΋ͦ΋FastfileΛॻ͔ͳ͍ • Fastfile͸ίʔυΛॻ͘৔ॴͰ͸ͳ͍ • Fastfile΁ͷهड़ྔΛݮΒ͍ͯ͘͠Ξϓϩʔν

  37. ൿಗ஋΍ઃఆ஋͸؀ڥม਺΁ • fastlaneͷଟ͘ͷύϥϝʔλ͸؀ڥม਺͔Β౉ ͢͜ͱ͕Ͱ͖Δ • ϋʔυίʔυΛ͢ΔΑΓ؀ڥม਺Ͱ஫ೖͨ͠ ํ͕σόοάɺϝϯς͠΍͍͢

  38. slack(message: 'Building...', slack_url: 'https://hooks.slack.com/ services/XXXXXXXX/YYYYYYY/ZZZZZZZ', channel: '#myapp-dev') slack(message: 'Building...') export

    SLACK_URL=https://hooks.slack.com/ services/XXXXXXXX/YYYYYYY/ZZZZZZZ export FL_SLACK_CHANNEL=#myapp-dev
  39. ઃఆͱϩδοΫ͸෼཭͢Δ • ~fileΛར༻͢Δ • Appfile, Gymfile, Scanfile, Matchfile, Deliverfile etc…

    • for_laneͰlane͝ͱͷઃఆ஋΋ར༻Մೳ
  40. lane :buiid_for_appstore do gym(xcodeproj: 'MyApp.xcodeproj', scheme: 'MyApp', configuration: 'Release', export_method:

    'app-store', include_bitcode: true, clean: true) end
  41. scheme 'MyApp' include_bitcode false claen true for_lane :build_for_inhouse do configuration

    'Beta' export_method 'enterprise' end for_lane :build_for_release do configuration 'Release' export_method 'app-store' include_bitcode true end fastlane/Gymfile σϑΥϧτ஋Λઃఆ MBOF͝ͱʹPWFSSJEF
  42. ActionΛ෼཭͢Δ $ bundle exec fastlane new_action

  43. None
  44. module Fastlane module Actions class GetAnswer < Action def self.run(params)

    42 end def self.description "Answer to the Ultimate Question of Life, the Universe, and Everything" end end end end get_answer_action.rb ΞΫγϣϯ࣮ߦ࣌ͷ ॲཧ
  45. actions_path '../actions/' lane :show_answer do UI.message(get_answer) end Fastfile ࠷্෦Ͱϩʔυ͢Δ

  46. Actionͷ෼཭ • ύϥϝʔλͷόϦσʔγϣϯ͕͠΍͍͢(ConfigItem) • ܕνΣοΫɺόϦσʔλɺNullable • ςετ͕ॻ͖΍͍͢(rspec)

  47. $ fastlane generate_certificate \ app_identifiers:com.example.myapp,com.example.mya pp.NotificationService \ type:production ΧϯϚ۠੾Γͷจࣈྻ ಛఆͷจࣈྻ͚ͩड͚෇͚͍ͨ

  48. lane generate_certificate |params| do # Split app_identifier app_identifiers = params[:app_identifiers]

    UI.user_error!("app_identifier must be String") unless app_identifier.is_a?(String) app_identifiers = app_identifiers.split(',') # Validate type type = params[:type] UI.user_error!("Type must be development or production") unless %w(development production).include?(type) # Do something... end ܕνΣοΫ͢Δ TQMJU͢Δ UZQF͕ਖ਼͍͔͠ΈΔ
  49. def self.available_options [ FastlaneCore::ConfigItem.new( key: :type, description: "Certificate type to

    generate. (development or production)", optional: false, verify_block: proc do |value| is_valid = %w(development production).include?(value.downcase) UI.user_error!(“type is invalid") unless is_valid end, type: String), FastlaneCore::ConfigItem.new( ɹɹɹɹkey: :app_identifier, ɹɹɹɹshort_option: "-a", ɹɹɹɹdescription: "The bundle identifier(s) of your app (comma- separated)", ɹɹɹɹis_string: false, ɹɹɹɹtype: Array), ] end ΦʔόʔϥΠυ
  50. def self.available_options [ FastlaneCore::ConfigItem.new( key: :type, description: "Certificate type to

    generate. (development or production)", optional: false, verify_block: proc do |value| is_valid = %w(development production).include?(value.downcase) UI.user_error!(“type is invalid") unless is_valid end, type: String), FastlaneCore::ConfigItem.new( ɹɹɹɹkey: :app_identifiers, ɹɹɹɹshort_option: "-a", ɹɹɹɹdescription: "The bundle identifier(s) of your app (comma- separated)", ɹɹɹɹis_string: false, ɹɹɹɹtype: Array), ] end ΦʔόʔϥΠυ
  51. ίʔυαΠϯ

  52. XcodeͷઃఆΛ׆༻͢Δ • ྫ͑͹഑෍༻ͱࣾ಺Ϗϧυ༻ͳͲͰϏϧυ؀ڥΛෳ਺؅ ཧ͍ͨ͠ #VJME $POpHVSBUJPO %FWFMPQFS 5FBN "QQ*EFOUJpFS $PEF4JHOJOH

    4UZMF %FCVH 0SHBOJ[BUJPO DPNDPPLQBEOFX BQQ "VUPNBUJD 3FMFBTF 0SHBOJ[BUJPO DPNDPPLQBEOFX BQQ .BOVBM #FUB &OUFSQSJTF DPNDPPLQBEOF XBQQJOIPVTF .BOVBM
  53. None
  54. XcodeͷઃఆΛ׆༻͢Δ • FastfileͰApp Identifier΍Code Signing StyleΛॻ͖ ׵͑ • update_app_identifier •

    update_project_team • automatic_code_signing • update_project_provisioning
  55. # Provisioning Profileͷऔಘ match(git_branch: "enterprise", type: 'enterprise', readonly: true, app_identifier:

    'com.cookpad.myapp-beta') provisioning_profile_specifier = ENV["sigh_com.cookpad.myapp-beta_appstore_profile-name"] provisioning_profile_path = ENV["sigh_com.cookpad.myapp- beta_appstore_profile-path"] team_id = ENV["sigh_com.cookpad.myapp-beta_appstore_team- id"] NBUDIͰ1SPWJTJPOJOH1SPpMFΛऔಘ 1SPWJTJPOJOH1SPpMFͷ1BUI΍໊લΛऔಘ
  56. match • Provisioning ProfileΛgitϦϙδτϦͰಉظͰ ͖Δ࢓૊Έ

  57. None
  58. None
  59. # Team IDͷߋ৽ update_project_team( teamid: team_id, ) # Automatic Code

    SigningͷແޮԽ disable_automatic_code_signing( team_id: team_id, profile_name: provisioning_profile_specifier, code_sign_identity: 'iPhone Distribution', targets: %w(MyApp), ) # Provisioning Profileͷઃఆ update_project_provisioning( profile: provisioning_profile_path, target_filter: 'MyApp', )
  60. # App Identifierͷߋ৽ update_app_identifier( app_identifier: 'com.cookpad.myapp-inhouse', ) gym(scheme: 'MyApp-Beta', export_method:

    ‘enterprise')
  61. lane :build_for_inhouse # Provisioning Profileͷऔಘ match(git_branch: "enterprise", type: 'enterprise', readonly:

    true, app_identifier: 'com.cookpad.myapp-beta') provisioning_profile_specifier = ENV["sigh_com.cookpad.myapp-beta_appstore_profile-name"] provisioning_profile_path = ENV["sigh_com.cookpad.myapp-beta_appstore_profile-path"] team_id = ENV["sigh_com.cookpad.myapp-beta_appstore_team-id"] # Team IDͷߋ৽ update_project_team( teamid: team_id, ) # Automatic Code SigningͷແޮԽ disable_automatic_code_signing( team_id: team_id, profile_name: provisioning_profile_specifier, code_sign_identity: 'iPhone Distribution', targets: %w(MyApp), ) # Provisioning Profileͷઃఆ update_project_provisioning( profile: provisioning_profile_path, target_filter: 'MyApp', ) # App Identifierͷߋ৽ update_app_identifier( app_identifier: 'com.cookpad.myapp-beta', ) build_ios_app(scheme: 'MyApp-Beta', export_method: 'enterprise') end
  62. lane :build_for_inhouse # Provisioning Profileͷऔಘ match(git_branch: "enterprise", type: 'enterprise', readonly:

    true, app_identifier: 'com.cookpad.myapp-beta') provisioning_profile_specifier = ENV["sigh_com.cookpad.myapp-beta_appstore_profile-name"] provisioning_profile_path = ENV["sigh_com.cookpad.myapp-beta_appstore_profile-path"] team_id = ENV["sigh_com.cookpad.myapp-beta_appstore_team-id"] # Team IDͷߋ৽ update_project_team( teamid: team_id, ) # Automatic Code SigningͷແޮԽ disable_automatic_code_signing( team_id: team_id, profile_name: provisioning_profile_specifier, code_sign_identity: 'iPhone Distribution', targets: %w(MyApp), ) # Provisioning Profileͷઃఆ update_project_provisioning( profile: provisioning_profile_path, target_filter: 'MyApp', ) # App Identifierͷߋ৽ update_app_identifier( app_identifier: 'com.cookpad.myapp-beta', ) build_ios_app(scheme: 'MyApp-Beta', export_method: 'enterprise') end
  63. XcodeͷઃఆΛ׆༻͢Δ • ίʔυͰϏϧυઃఆΛॻ͖׵͑ͳ͍ • XcodeͷBuild ConfigurationΛ׆༻͢Δ

  64. None
  65. None
  66. #VJME $POpHVSBU JPO %FWFMPQF S5FBN 1SPEVDU #VOEMF *EFOUJpFS $PEF 4JHOJOH

    4UZMF 1SPEVDU #VOEMF *EFOUJUZ 1SPWJTJPOJOH 1SPpMF %FCVH 0SHBOJ[BUJ PO DPNDPPLQBE OFXBQQ "VUPNBUJD J04 %FWFMPQFS "VUPNBUJD 3FMFBTF 0SHBOJ[BUJ PO DPNDPPLQBE OFXBQQ .BOVBM J04 %JTUSJCVUJPO NBUDI "QQ4UPSF DPNDPPLQBE OFXBQQ #FUB &OUFSQSJTF DPNDPPLQBE OFXBQQ JOIPVTF .BOVBM J04 %JTUSJCVJUJPO NBUDI *O)PVTF DPNDPPLQBE OFXBQQCFUB
  67. $PEF4JHO*EFOUJUZ $PEF4JHOJOH4UZMF %FWFMPQFS5FBN 1SPWJTJPOJOH1SPpMF4QFDJpFS

  68. lane :build_for_appstore do # Provisioning Profileͷऔಘ(match) app_identifiers = %w(com.cookpad.myapp com.cookpad.myapp.NotificationService)

    match(type: 'appstore', readonly: true, app_identifier: app_identifiers) # Ϗϧυ gym(scheme: 'MyApp', configuration: 'Release', export_method: 'app-store') end
  69. XcodeͷઃఆΛ׆༻͢Δ • ͜Ε͸͜ΕͰಈ͘ • ͕ɺXcode͕ෆ҆ఆʹͳΓ͕ͪͳͷͰίʔυ αΠϯ͸Կ΍ͬͯ΋ਏ͍

  70. ࠷ߴͷFastfileͷͨΊʹ • ઃఆ஋͸؀ڥม਺Λ࢖͏ • ઃఆͱϩδοΫͷ෼཭ɻ~FileΛ׆༻͢Δ • ڊେͳϩδοΫ͸Actionʹ͢Δ • XcodeͷϏϧυઃఆΛ࢖͏

  71. σόοάख๏

  72. fastlane͋Δ͋Δ • खݩͰͷಈ࡞֬ೝ͕μϧ͍ • ಈ͔ͳͯ͘CIʹpushΛ܁Γฦ͢

  73. σόοάख๏ • جຊతʹRubyͳͷͰσόοΨʔ͕࢖͑Δ • irb, pry, byebug • ൿಗ஋͸؀ڥม਺Λ࢖͏ •

    envchain • ઃఆ஋΋؀ڥม਺Λ࢖͏ • direnv
  74. pry, pry-nav • RubyͷσόοΨ • ϒϨΠΫϙΠϯτΛுͬͯREPL͕ىಈͰ͖Δ • εςοϓ࣮ߦ΋Ͱ͖Δ(pry-byebug) gem 'pry'

    gem 'pry-byebug'
  75. None
  76. # vim: syntax=ruby require_fastlane 'pry' lane :release do |params| binding.pry

    scheme = params[:scheme] build_for_appstore end SFRVJSFͱಉ͡ #SFBLQPJOU
  77. direnv • σόοά༻ʹൿಗ஋Ͱ͸ͳ͍஋͸ϋʔυίʔ υ͢ΔΑΓ؀ڥม਺Ͱ༩͑ͨํ͕ศར • σΟϨΫτϦ಺ͷ؀ڥม਺Λઃఆͯ͘͠ΕΔ ౕ • .envrcΛಡΜͰ͘ΕΔ

  78. export FASTLANE_USER=giginet.net@gmail.com export FL_SLACK_CHANNEL=#ios-dev .envrc

  79. envchain • ΩʔνΣΠϯʹൿಗ஋Λอଘͯ͠؀ڥม਺͔ ΒಡΊΔ΍ͭ • σόοά༻ʹΑ͘࢖͏஋͸ొ࿥͓ͯ͘͠ͱศ ར

  80. envchain

  81. ·ͱΊ • ࠷ߴͷFastfileͷॻ͖ํ͸FastfileΛॻ͔ͳ͍͜ͱ • σʔλ͸ผʹ؅ཧ͢Δ • XcodeͷػೳΛར༻͢Δ • ϓϥάΠϯɺΞΫγϣϯʹͰ͖Δ΋ͷ͸੾Γग़͢ •

    ϩδοΫʹ͸specΛॻ͘
  82. એ఻

  83. એ఻1 • ಈ࡞֬ೝͷͨΊͷࣾ಺ΞϓϦ഑৴αʔϏεΛ৽ͨʹ࡞ͬ ͨ࿩

  84. એ఻2 • ୀ۶ͳ͜ͱ͸App Store Connect APIʹ΍ΒͤΑ͏ • 9/20(Tue) iOSDC Reject

    Conference Day 2
  85. એ఻3 •

  86. ͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠