400種類のアプリを毎日ビルドする自動化の技術 1. ビルド・申請作業とは 2. 既存のワークフローと関係者 3. 課題の整理 4. 自動化の目的とゴール 5. 自動化の内容と技術的な手法 6. 効果的に自動化を進めるためのベストプラクティス
w/ Presenter Note https://www.icloud.com/keynote/0xAxiOjmcpRfjqSdlwcJSrspg#iOSDC_2020_-_Yappli
Kishikawa Katsumi400छྨͷΞϓϦΛຖϏϧυ͢ΔࣗಈԽͷٕज़
View Slide
࣍1. Ϗϧυɾਃ࡞ۀͱ2. طଘͷϫʔΫϑϩʔͱؔऀ3. ՝ͷཧ4. ࣗಈԽͷతͱΰʔϧ5. ࣗಈԽͷ༰ͱٕज़తͳख๏6. ޮՌతʹࣗಈԽΛਐΊΔͨΊͷϕετϓϥΫςΟε
Ϗϧυɾਃ࡞ۀͱ
Ϗϧυɾਃ࡞ۀͱ1. YappliͷCMSʹొ͞ΕͨใΛऔಘ2. ΞϓϦ͝ͱʹXcodeϓϩδΣΫτΛੜ3. ύοέʔδΛϏϧυ4. App Store ConnectʹΞοϓϩʔυ5. ৹ࠪఏग़6. Push௨ͷূ໌ॻͷ࡞ɾஔ
طଘͷϫʔΫϑϩʔͱؔऀ
طଘͷϫʔΫϑϩʔͱؔऀCMSཧπʔϧApp Store ConnectCircle CIJIRAAWS S3Developer PortalϏϧυϚγϯGoogle Sheets͓٬͞· ୲ऀΤϯδχΞ
طଘͷϫʔΫϑϩʔʢʴखॱʣͱؔऀCMSཧπʔϧApp Store ConnectCircle CIJIRAϏϧυϚγϯGoogle SheetsAWS S3͓٬͞· ୲ऀΤϯδχΞDeveloper Portal
طଘͷϫʔΫϑϩʔʢʴखॱʣͱؔऀCMSཧπʔϧApp Store ConnectCircle CIJIRADeveloper PortalϏϧυϚγϯGoogle SheetsAWS S3͓٬͞· ୲ऀΤϯδχΞ
՝ͷཧ• ֤खॱͦͦࣗ͜͜ಈԽ͞Ε͍ͯΔͷͷ ؒͷख࡞ۀ͕ଟ͍
՝ͷཧ• ֤खॱͦͦࣗ͜͜ಈԽ͞Ε͍ͯΔͷͷ ؒͷख࡞ۀ͕ଟ͍• YappliଆͰิ͕ඞཁͳใΛख࡞ۀͰೖྗ͍ͯ͠Δ
CMSʢʹཧը໘ʣʹొ͞Ε͍ͯΔใΞϓϦ໊ΞΠίϯΞϓϦͷઆ໌ɾΩʔϫʔυͳͲεΫϦʔϯγϣοτURLεΩʔϜ༗ޮͳػೳɾSDKόϯυϧIDձ໊ࣾʢνʔϜ໊ʣόʔδϣϯϏϧυ൪߸λάʢϒϥϯνʣ͓٬͞·୲ऀΤϯδχΞ
՝ͷཧ• ֤खॱͦͦࣗ͜͜ಈԽ͞Ε͍ͯΔͷͷ ؒͷख࡞ۀ͕ଟ͍• YappliଆͰิ͕ඞཁͳใΛख࡞ۀͰೖྗ͍ͯ͠Δ• ؒҧ͍͕ى͜Γ͍͢• ֬ೝɾగਖ਼ɾϦτϥΠͷखؒ
՝ͷཧ• ख࡞ۀ͕ଟ͍• ಉ͡ใΛෳͷਓ͕ؒมߋ͢ΔաఔͰޡΓ͕ࠞೖ͢Δ• ॲཧͷهɾมߋཤྺ͕ͳ͍ͷͰؒҧ͍ʹؾͮ͘͜ͱ͕ΕΔ• ࣦഊɾमਖ਼ͷαΠΫϧ͕͍• ಛఆͷϚγϯʹϩάΠϯ͢Δඞཁ͕͋Δ
ࣗಈԽͷతɾΰʔϧ• ख࡞ۀ͕ଟ͍• ಉ͡ใΛෳͷਓ͕ؒมߋ͢Δ• ॲཧͷهɾมߋཤྺ͕ͳ͍• ಛఆͷϚγϯʹϩάΠϯ͢Δඞཁ͕͋Δ
ࣗಈԽͷతɾΰʔϧ• ख࡞ۀΛͳ͘͢• ใͷมߋखॱΛཧ͢Δ• ॲཧͷهɾมߋཤྺΛੵ͢Δ• ͯ͢ͷॲཧΛCIαʔϏε্Ͱ࣮ߦ͢Δ
͞ΒͳΔཧͷϫʔΫϑϩʔ• ͯ͢ͷॲཧ͕ίʔυͰهड़• ్தܦաͷอଘ• ૣࣦ͘ഊ͢Δ• ͍ͭͰϦτϥΠՄೳ• มߋཤྺͷੵ• ਓؒͷΞΫγϣϯ͚ͩͰͳ͘ ͞·͟·ͳॲཧͱ࿈ܞ࣮ͯ͠ߦ• ୭Ͱɺ͍ͭͰɺ Ͳ͔͜ΒͰ࣮ߦͰ͖Δ
ࣗಈԽͷ༰ͱٕज़తͳख๏
Ϗϧυ࡞ۀ• ରͷΞϓϦέʔγϣϯΛ֬ೝ͢Δ• ཧը໘ʹొ͞ΕͨใΛ֬ೝ͢Δ ※࣮ࡍ͍͍ͪͪ֬ೝ͠ͳ͍͕ɺؒҧ͍ͬͯΔͱϏϧυྃޙɺΞοϓϩʔυͷࡍʹࣦഊ͢Δ• ཧը໘ͰରͷΞϓϦέʔγϣϯΛࢦఆ͢Δ• ཧը໘ͰόʔδϣϯͱϏϧυ൪߸Λೖྗ͢Δ• ཧը໘ͰϏϧυରͷλάʢϒϥϯνʣΛࢦఆ͢Δ• ཧը໘͔ΒϏϧυΛ࣮ߦ͢Δ• ϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δ• ϦϦʔεϊʔτεΫϦʔϯγϣοτͳͲਃσʔλΛΞοϓϩʔυ͢Δ
Prototyping
1st Prototype
Slack Bolt• SlackΞϓϦΛ࡞͢ΔJavaScriptϑϨʔϜϫʔΫ• Block KitͰ࡞ͬͨJSONΛͦͷ··ը໘දࣔʹ͑ΔͷͰUI͕؆୯ʹ࡞ΕΔ• Slack Botͱͯ͠࡞͓ͬͯ͘ͱɺޙ͔ΒผͷϫʔΫϑϩʔͱ࿈ܞ͍͢͠
Slack BoltϝϯγϣϯʹԠͯ͠ ೖྗϝχϡʔΛදࣔ͢ΔྫUIBlock Kitʹ༻ҙ͞Ε͍ͯΔͷΛΈ߹ΘͤΔ͚ͩBlock Kit BuilderͰ؆୯ʹσβΠϯͰ͖Δ
2ndPrototype
ԿΛ͍ͯ͠Δ͔1. SKUʢΞϓϦΛҰҙʹࣝผ͢ΔIDʣΛೖྗ2. Fastlane SpaceshipΛͬͯόϯυϧIDձ໊ࣾͷਖ਼֬ͳใΛऔಘ3. GitHubϦϙδτϦ͔Β࠷৽ͷϦϦʔεͷλάΛऔಘ4. όʔδϣϯɺϏϧυ൪߸ɺϏϧυରͷλάʢϒϥϯνʣͱͯ͠ઃఆ5. ཧը໘ͷσʔλΛߋ৽6. ूΊͨใΛࢦఆͯ͠CIΛτϦΨʔ͢Δ
Ϗϧυ࡞ۀ• ରͷΞϓϦέʔγϣϯΛ֬ೝ͢Δ• ཧը໘ʹొ͞ΕͨใΛ֬ೝ͢Δ ※࣮ࡍ͍͍ͪͪ֬ೝ͠ͳ͍͕ɺؒҧ͍ͬͯΔͱϏϧυྃޙɺΞοϓϩʔυͷࡍʹࣦഊ͢Δ• ཧը໘ͰରͷΞϓϦέʔγϣϯΛࢦఆ͢Δ ➡ Slack Botͷը໘Ͱࢦఆ• ཧը໘ͰόʔδϣϯͱϏϧυ൪߸Λೖྗ͢Δ• ཧը໘ͰϏϧυରͷλάʢϒϥϯνʣΛࢦఆ͢Δ• ཧը໘͔ΒϏϧυΛ࣮ߦ͢Δ ➡ Slack Botͷ֬ೝը໘ͷϘλϯΛԡ͢• ϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δ• ϦϦʔεϊʔτεΫϦʔϯγϣοτͳͲਃσʔλΛΞοϓϩʔυ͢Δ
طଘͷϫʔΫϑϩʔʢʴखॱʣͱؔऀCMSཧπʔϧApp Store ConnectBitriseJIRADeveloper PortalϏϧυϚγϯGoogle SheetsAWS S3͓٬͞· ୲ऀΤϯδχΞ
εϚʔτϑΥϯ͔Β࣮ߦͰ͖Δ• ͍ͭͰɺͲ͔͜ΒͰ؆୯ʹ• ࣦഊͯ͠ϦτϥΠ͢Δ͚ͩ
ʢύοέʔδͷΞοϓϩʔυ͕ޭͨ͠Βʣϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δ
ϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δखॱ• VPNʹଓ͢Δ• ϏϧυϚγϯʹϦϞʔτϩάΠϯ͢Δ• Push௨ͷূ໌ॻΛߋ৽͢ΔεΫϦϓτΛ࣮ߦ͢Δ $ sh pem.sh 26FF4BEC
ূ໌ॻΛߋ৽͢ΔεΫϦϓτʢpem.shʣͷ༰• ҾͷSKU͔ΒόϯυϧIDTeam IDΛऔಘ͢Δ ※ࢀরઌख࡞ۀͰϝϯςφϯε͞Ε͍ͯΔεϓϨουγʔτʢ͔ΒExport͞ΕͨϑΝΠϧʣ• fastlane pemΛ࣮ߦͯ͠ূ໌ॻΛ࡞·ͨߋ৽• ৽͍͠ূ໌ॻΛS3ʹΞοϓϩʔυ• ϏϧυϚγϯ͔ΒͷΈΞΫηεͰ͖Δαʔόʹূ໌ॻΛஔ
• VPNʹଓ͢Δ• ϏϧυϚγϯʹϦϞʔτϩάΠϯ͢Δ• Push௨ͷূ໌ॻΛߋ৽͢ΔεΫϦϓτΛ࣮ߦ͢Δ sh pem.sh 26FF4BECख࡞ۀϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δखॱख࡞ۀ·͕͍ͪ͑͢ख࡞ۀ
ূ໌ॻΛߋ৽͢ΔεΫϦϓτͷ༰• ҾͷSKU͔ΒόϯυϧIDTeam IDΛऔಘ͢Δ ※ࢀরઌख࡞ۀͰϝϯςφϯε͞Ε͍ͯΔεϓϨουγʔτʢ͔ΒExport͞ΕͨϑΝΠϧʣ• fastlane pemΛ࣮ߦͯ͠ূ໌ॻΛ࡞·ͨߋ৽• ৽͍͠ূ໌ॻΛS3ʹΞοϓϩʔυ• ϏϧυϚγϯ͔ΒͷΈΞΫηεͰ͖Δαʔόʹূ໌ॻΛஔͦͦ͜͜ͷසͰ·͕͍ͪͬͯΔมߋཤྺ͕Βͳ͍
Ϗϧυ࣌ʹূ໌ॻΛߋ৽͢Δ
Ϗϧυ࣌ʹূ໌ॻΛߋ৽͢Δ• ূ໌ॻͷ࡞ɾߋ৽ʹඞཁͳใʹύοέʔδͷΞοϓϩʔυʹඞཁͳใ ʢApple IDɺόϯυϧIDɺTeam IDɺetc.ʣ Ϗϧυ࣌ʹͯ͢ἧ͍ͬͯΔ• ύοέʔδͷΞοϓϩʔυ͕ޭ͍ͯ͠ΕͦͷΞϓϦͷূ໌ॻΛؒҧ͍ͳ͘ߋ৽Ͱ͖Δ
ূ໌ॻΛߋ৽͢ΔखॱΛ ϏϧυεΫϦϓτʹΈࠐΉ
• VPNʹଓ͢Δ• ϏϧυϚγϯʹϦϞʔτϩάΠϯ͢Δ• Push௨ͷূ໌ॻΛߋ৽͢ΔεΫϦϓτΛ࣮ߦ͢Δ sh pem.sh 26FF4BECϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δखॱ
• ҾͷSKU͔ΒόϯυϧIDTeam IDΛऔಘ͢Δ ※ࢀরઌख࡞ۀͰϝϯςφϯε͞Ε͍ͯΔεϓϨουγʔτʢ͔ΒExport͞ΕͨϑΝΠϧʣ• fastlane pemΛ࣮ߦͯ͠ূ໌ॻΛ࡞·ͨߋ৽• ৽͍͠ূ໌ॻΛS3ʹΞοϓϩʔυ• ϏϧυϚγϯ͔ΒͷΈΞΫηεͰ͖Δαʔόʹূ໌ॻΛஔϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δखॱ
TipsS3ͷΞοϓϩʔυكʹࣦഊ͢Δূ໌ॻͷߋ৽ʹޭ͢Δͱظݶ͕ۙͮ͘·Ͱߋ৽͞Εͳ͍ʢߋ৽͢Δʹڧ੍తʹ༗ޮͳূ໌ॻΛແޮԽ͢Δʣͭ·Γߋ৽ޙS3ͷΞοϓϩʔυʹࣦഊ͢Δͱূ໌ॻΛखʹೖΕΒΕͳ͍CIͷΞʔςΟϑΝΫτͱ͓ͯͯ͘͠͠
CIͷΞʔςΟϑΝΫτͱͯ͠ՌΛ͢
ϏϧυϚγϯͷഇࢭ
ϏϧυϚγϯͷഇࢭʹϑΝΠϧΛࣗಈతʹಉظ͢Δ
ैདྷͷखॱ172.16.xxx.xxx1.ϏϧυϚγϯʹϩάΠϯ2.ূ໌ॻΛ࡞ɾߋ৽3.S3͓ΑͼαʔόʹΞοϓϩʔυ
৽͍͠खॱ172.16.xxx.xxx1.CIͰূ໌ॻΛ࡞ɾߋ৽2.CI͔ΒS3ʹΞοϓϩʔυ
ϏϧυϚγϯʹϑΝΠϧΛࣗಈతʹಉظ͢Δ172.16.xxx.xxx
ϏϧυϚγϯʹϑΝΠϧΛࣗಈతʹಉظ͢Δ
ϏϧυϚγϯͷഇࢭ• σʔλͷࢀরݩΛਖ਼͘͢͠Δ S3ʢಈ͍͍ͯΔڥʹਖ਼͍͠ڥʣ͔ΒGitHubʹσʔλΛϛϥʔϦϯά• ϏϧυϚγϯͰఆظతʹGitϦϙδτϦΛߋ৽ʢPullͷΈʣ͠ɺ ࣾαʔόʹϑΝΠϧΛஔ• ϏϧυϚγϯཧతʹ͍ͬͯΔ͕ਓ͕ؒଓ͢Δ͜ͱͳ͍ ≒ഇࢭ
• ࠷ॳղܾࠔͩͬͨ͜ͱɺࣗಈԽͷൣғΛ૿͍ͯ͘͠͏ͪʹ ผͷղ๏͕ద༻Ͱ͖ͨΓ͢Δ• ࣗಈԽΛద༻͍ͯ͘͠ࡍʹ·ͣݱࡏͷঢ়ଶΛͳΜͰGitʹίϛοτ͓ͯ͘͠ͱྑ͍ɻ มߋཤྺ͕͑Δ͜ͱͱGitHubͳΒCIͱͷ࿈ܞ͕Γ͍͢ɻTips
Ϗϧυ࡞ۀ• ରͷΞϓϦέʔγϣϯΛ֬ೝ͢Δ• ཧը໘ʹొ͞ΕͨใΛ֬ೝ͢Δ ※࣮ࡍ͍͍ͪͪ֬ೝ͠ͳ͍͕ɺؒҧ͍ͬͯΔͱϏϧυྃޙɺΞοϓϩʔυͷࡍʹࣦഊ͢Δ• ཧը໘ͰରͷΞϓϦέʔγϣϯΛࢦఆ͢Δ ➡ Slack Botͷը໘Ͱࢦఆ• ཧը໘ͰόʔδϣϯͱϏϧυ൪߸Λೖྗ͢Δ• ཧը໘ͰϏϧυରͷλάʢϒϥϯνʣΛࢦఆ͢Δ• ཧը໘͔ΒϏϧυΛ࣮ߦ͢Δ ➡ Slack Botͷ֬ೝը໘ͷϘλϯΛԡ͢• ϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δ ʴϏϧυϚγϯͷഇࢭ• ϦϦʔεϊʔτεΫϦʔϯγϣοτͳͲਃσʔλΛΞοϓϩʔυ͢Δ
طଘͷϫʔΫϑϩʔʢʴखॱʣͱؔऀCMSཧπʔϧApp Store ConnectBitriseJIRADeveloper PortalϏϧυϚγϯAWS S3͓٬͞· ୲ऀΤϯδχΞ
ϦϦʔεϊʔτεΫϦʔϯγϣοτͳͲਃσʔλΛΞοϓϩʔυ͢Δ
ʴ̍
ॲཧ͕ྃͨ͠ΒJIRAͷνέοτʹίϝϯτ͢Δ
Ϗϧυ࡞ۀ• ରͷΞϓϦέʔγϣϯΛ֬ೝ͢Δ• ཧը໘ʹొ͞ΕͨใΛ֬ೝ͢Δ• ରͷΞϓϦέʔγϣϯΛࢦఆ͢Δ• ཧը໘ͰόʔδϣϯͱϏϧυ൪߸Λೖྗ͢Δ• ཧը໘ͰϏϧυରͷλάʢϒϥϯνʣΛࢦఆ͢Δ• ϏϧυΛ࣮ߦ͢Δ• ϓογϡ௨ͷূ໌ॻΛ࡞·ͨߋ৽͢Δ• ϦϦʔεϊʔτεΫϦʔϯγϣοτͳͲਃσʔλΛΞοϓϩʔυ͢Δ• ྃͨ͠ΒJIRAͷνέοτʹίϝϯτ͢Δ
ཧͷϫʔΫϑϩʔʹ͚ͯ
ཧͷϫʔΫϑϩʔʹ͚ͯ• طଘͷPush௨ͷূ໌ॻΛCIͰຖࣗಈߋ৽ ➡ ࣮ߦ݁Ռ͔ΒσϕϩούʔنʹະಉҙͷΞΧϯτΛݕग़Ͱ͖Δ• ผͷγεςϜʹΑΔূ໌ॻͷظݶΕ௨ʹࣗಈͰཧ༝Λίϝϯτ͢Δ
ཧͷϫʔΫϑϩʔʹ͚ͯ• ผͷγεςϜ͔Β௨͞ΕΔJIRAͷνέοτ͔Βਃ͕ඞཁͳΞϓϦΛ ࣗಈతʹݕग़• Bot͕Ϗϧυը໘ΛεϨουʹฦ৴͢ΔܗͰදࣔ
ཧͷϫʔΫϑϩʔʹ͚ͯ• ผͷγεςϜ͔Β௨͞ΕΔJIRAͷνέοτ͔Βਃ͕ඞཁͳΞϓϦΛ ࣗಈతʹݕग़• Bot͕Ϗϧυը໘ΛεϨουʹฦ৴͢ΔܗͰදࣔ• نಉҙ͕ඞཁͳΞϓϦέʔγϣϯϏϧυલʹ௨
ཧͷϫʔΫϑϩʔʹ͚ͯ• ผͷγεςϜ͔Β௨͞ΕΔJIRAͷνέοτ͔Βਃ͕ඞཁͳΞϓϦΛ ࣗಈతʹݕग़• Bot͕Ϗϧυը໘ΛεϨουʹฦ৴͢ΔܗͰදࣔ• ʢ༧ఆʣͦͦࣗಈͰϏϧυͯ͠͠·͓͏• ʢ༧ఆʣJIRAͷνέοτΛ࡞ͨ͠ΒϏϧυΛ։࢝ɺͱ͢ΕΤϯδχΞҎ֎ͷਓ͕͍͍͢ͷͰʁ
ʢิʣπʔϧͷΞοϓσʔτΛࣗಈԽ• DependabotͰNPMͱBundlerͷߋ৽ΛࣗಈతʹPR͢Δ docs.github.com/en/github/administering-a-repository/keeping-your-dependencies-updated-automatically• Dependabot Auto MergeͷGitHub ActionΛઃఆͯ͠PRΛࣗಈతʹϚʔδ͢Δ github.com/marketplace/actions/dependabot-auto-merge
ʢิʣπʔϧͷΞοϓσʔτΛࣗಈԽ
࣮ݱͰ͖ͨ͜ͱɾ͜Ε͔Β• ͯ͢ͷ࡞ۀΛίʔυԽ• ख࡞ۀΛʢ΄΅ʣͳͨ͘͠• ॲཧͷهΛ͢• มߋཤྺΛੵ͢Δ• ૣࣦ͘ഊ͢Δ• ϦτϥΠՄೳ• ਓؒͷΞΫγϣϯ͚ͩͰͳ͘͞·͟·ͳॲཧͱ࿈ܞ࣮ͯ͠ߦ• ͍ͭͰɺͲ͔͜ΒͰ࣮ߦͰ͖Δ
࣮ݱͰ͖ͨ͜ͱɾ͜Ε͔Β
͜Ε͔Β• ΑΓపఈతʹख࡞ۀΛͳ͘͢• ͬͱଟ͘ͷγεςϜɺ௨ͱ࿈ܞ͢Δ• ͓٬͞·͕ࣗࣗͰϏϧυɾਃͰ͖ΔΑ͏ʹ͢Δ
ޮՌతʹࣗಈԽΛਐΊΔͨΊͷྑ͍ϓϥΫςΟε• ࣦഊ͠ͳ͍Α͏ʹ͢Δ • ϧʔϧΛ؆୯ʹ͢Δ• ػցͷ߹ʹ߹ΘͤΔ• ϦΧόϦʔॲཧΛࣗಈԽ͢Δ• ؒҧ͍͕ىͬͯͤ͜ΔΑ͏ʹ• ̍ͭͷ͜ͱ͚ͩΛ͏·͘Δ• ΤϥʔॲཧΛ͕ΜΒͳ͍- ૣΊʹࣦഊ͢Δ- ਖ਼ৗܥҎ֎ʹ͖ͨΒ୯७ʹऴྃ͢Δ- 80-90%͘Β͍ಈ͍͍ͯΕΑ͍ ͦΕΛ95-100%ʹ͢Δʹലେͳίετ͕͔͔Δ
·ͱΊ• ख࡞ۀʹΑΔଛࣦײΑΓ͔ͳΓଟ͍• ࣗಈԽϨόϨοδ͕ޮ͖ɺ͔ͭෳརޮՌΛੜΉ• ࣗಈԽͨ͠γεςϜಉ࢜૬ޓ࿈ܞͰ͖Δ• ػցͰͰ͖Δ͜ͱΛػցʹͤΔ͜ͱͰɺΑΓߴҐͷղܾʹઐ೦Ͱ͖Δ