Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

GitHub Actions で構築する Android アプリの CI/CD

Hiroyuki Kusu
September 03, 2021

GitHub Actions で構築する Android アプリの CI/CD

CI/CD Conference 2021 ( https://event.cloudnativedays.jp/cicd2021 ) の資料

Hiroyuki Kusu

September 03, 2021
Tweet

More Decks by Hiroyuki Kusu

Other Decks in Technology

Transcript

  1.  ձ໊ࣾ גࣜձࣾΏΊΈ ઃཱ೔ 2000೥1݄27೔ ैۀһ਺ 244໊ʢ2021೥5݄࣌఺ɺਖ਼ࣾһͷΈ׵ࢉʣ ࣄۀ಺༰ ΠϯλʔωοταʔϏεͷاը/։ൃ/੍࡞/ӡ༻ࢧԉ ॴࡏ஍

    ౦ژΦϑΟε ˟154-0024 ౦ژ౎ੈా୩۠ࡾݢ஡԰2-11-23 αϯλϫʔζB౩7֊ʢ༣ศ෺ड෇8֊ʣ ژ౎ΦϑΟε ˟600-8411 ژ౎෎ژ౎ࢢԼژ۠ӊؙ௨࢛৚Լϧਫۜ԰ொ620൪஍ COCONӊؙ 4֊ ח૔ΦϑΟε ˟248-0014 ਆಸ઒ݝח૔ࢢ༝ൺϲ඿2-9-62 FORUM 302
  2. ໨࣍  • GitHub Actions ʹ͍ͭͯ • Android ͷ CI/CD

    • ϓϧϦΫΤετͷνΣοΫ • masterϒϥϯνͷड͚ೖΕνΣοΫ • ΞϓϦͷࣾ಺഑෍ • ͦͷ΄͔؀ڥͷ੔උ
  3. GitHub Actions ʹ͍ͭͯ  • GitHub ۘ੡ͷιϑτ΢ΣΞϫʔΫϑϩʔ࣮ߦ؀ڥ • ઐ༻αʔόΛࣗલͰ༻ҙ͢Δඞཁ͕ͳ͍ʢ༻ҙ͢Δ͜ͱ΋Ͱ͖Δʣ •

    ϫʔΫϑϩʔ͸ YAML ϑΝΠϧ΁ఆٛͯ͠ϦϙδτϦʹ֨ೲ • 1ϦϙδτϦ͋ͨΓಉ࣌ʹ 20 ฒྻ·ͰϫʔΫϑϩʔΛ࣮ߦՄೳ • ࣮ߦ؀ڥͷ OS ͱͯ͠ Ubuntu LinuxɺmacOSɺWindows ͕ར༻Ͱ͖Δ • υΩϡϝϯτ͸ॆ࣮͍ͯ͠Δ • https://docs.github.com/ja/actions
  4.  GitHub Actions ʹ͍ͭͯ • ݱ࣌఺Ͱ 10,000 ۙ͘ͷΞΫγϣϯ͕ެ ։͞Ε͍ͯΔ •

    ॴఆͷํ๏ͰϦϙδτϦΛ༻ҙ͢Δ͚ͩ ͳͷͰࣗ࡞΋؆୯ • ඞͣ͠΋ Marketplace ʹެ։͢Δඞ ཁ͸ͳ͍ GitHub Marketplace
  5. jobs : build : name: Buil d runs-on: ubuntu-20.0 4

    steps : - name: Check ou t uses: actions/checkout@v 2 - name: Set up JD K uses: actions/setup-java@v 1 with : java-version: 1 1 - name: Bundle with Gradl e run: ./gradlew assembleDebug  GitHub Actions ʹ͍ͭͯ Android ͷϏϧυ؀ڥ͕ඪ४Ͱ੔උ͞Ε͍ͯ ΔͷͰɺͦͷ··ϏϧυͰ͖Δ Android ΞϓϦͷϏϧυ
  6. run: | curl -X POST \ -H "Content-Type: application/json" \

    -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -d "{ \"body\": \"hoge\" }" \ https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments  GitHub Actions ʹ͍ͭͯ • GitHub ্ͷେ֓ͷΠϕϯτΛτϦΨʔʹϫʔΫϑϩʔΛىಈͰ͖Δ • https://docs.github.com/ja/actions/reference/events-that-trigger-work fl ows • GitHub API ༻ͷτʔΫϯ͕ඪ४Ͱར༻Ͱ͖Δ 㱺 CI/CD ͚ͩͰͳ͘։ൃϑϩʔʹؔ͢ΔࣗಈԽͰ΋ Github Actions Λར༻Ͱ͖Δ ྫ: ࣗಈͰϥϕϧΛ෇༩͢ΔɺIssue Λ࡞੒͢Δɺetc.. ϓϧϦΫΤετʹίϝϯτ͢Δྫɿ τʔΫϯ
  7.  • ϩʔΧϧͰϫʔΫϑϩʔͷಈ࡞ݕূ͕Ͱ͖ͳ͍ • ϒϥϯν͕ෳ਺͋Δ৔߹ɺϫʔΫϑϩʔͷमਖ਼ͷ൓ө͕೉͍͜͠ͱ͕͋Δ • ϞόΠϧΞϓϦ։ൃʹಛԽ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍ • Bitrise ͳͲϞόΠϧઐ༻ͷ

    CI αʔϏεʹൺ΂Δͱ଍Γͳ͍͜ͱ΋ • ࣮ߦ؀ڥͱͯ͠ macOS Λબ୒͢Δͱ Linux ͷ10ഒͷίετ • ͱ͸͍͑ Android ΞϓϦ։ൃͰ͸ͦΕ΄Ͳར༻͠ͳ͍ GitHub Actions ʹ͍ͭͯ มߋ఺
  8. Android ͷ CI/CD ϓϧϦΫΤετͷ νΣοΫ NBTUFSϒϥϯνͷ ड͚ೖΕνΣοΫ ΞϓϦͷࣾ಺഑෍ ˍ࣮ػ֬ೝ Google

    Play ΁ͷϦϦʔε ςετͷ௕͞  ※ ʮmasterʯϒϥϯνͷՕॴ͸ӡ༻ϑϩʔʹΑΔͱࢥ͏ͷͰಡΈସ͍͑ͯͩ͘͞
  9.  • GitHub Actions ͷඪ४ͷ࣮ߦ؀ڥͰɺAndroid ͕໰୊ͳ͘ϏϧυͰ͖ɺ଎౓తʹ΋໰୊ͳ͠ • ΞϓϦ͕૿͑ͯ͘ΔͱɺBitrise Ͱͷ GUI

    ϕʔεͷ؅ཧ͕൥ࡶʹࢥ͑ͨ • ϫʔΫϑϩʔࣗମʢYAMLϑΝΠϧʣΛόʔδϣϯ؅ཧ͠ɺϓϧϦΫΤετͰͷϨϏϡʔͷର৅ʹ • ΋ͱ΋ͱ GitHub Λશ໘ར༻͍ͯͨ͠ͷͰɺCI/CD ΋ GitHub Ͱ׬͍݁ͨ͠ • ϦϙδτϦຖʹ20ͷ࣮ߦ؀ڥׂ͕Γ౰ͯΒΕΔͷͰɺଞͷΞϓϦͷར༻ঢ়گʹґଘ͢Δ͜ͱ͕ͳ͍ • Bitrise ΋ܖ໿ϓϥϯ࣍ୈʁ • ίετ͕͍҆ • $0.008/෼ʢLinux ͷ৔߹ʣɺ50,000 ෼/݄ ͷແྉ࿮ʢGitHub Enterprise Cloud ͷ৔߹ʣ • Bitrise ͸ϫʔΫϑϩʔ಺ͷෳ਺ͷδϣϒΛฒྻͰ࣮ߦͰ͖ͣɺ଎౓͕ग़ͳ͍ ΏΊΈͰ͸ 20ʙ30 ͷ Android ϓϩδΣΫτΛ GitHub Ͱ։ൃɾ؅ཧ͠ɺCI/CD ͸ Bitrise Λར༻͍ͯͨ͠ 㱺 GitHub Actions ΁Ҡߦʢதʣ Android ͷ CI/CD
  10. ϓϧϦΫΤετͷνΣοΫ • ੩తղੳ • Android Lintʢඪ४ͷݕࠪπʔϧʹΑΔݕࠪʣ • ktlintʢKotlinίʔυͷϑΥʔϚοτͷݕࠪʣ • Ϣχοτςετ

    • ϓϧϦΫΤετͷମࡋʢ։ൃνʔϜͰͷϧʔϧʹଇ͍ͬͯΔ͔ʣ ϓϧϦΫΤετͷ࡞੒ɾߋ৽ΛܖػʹίʔυΛνΣοΫ ࣮ߦ࣌ؒΛ୹ͯ݁͘͠ՌΛ͢͹΍͘։ൃऀ΁ϑΟʔυόοΫ  ※ ࣮ߦ͕͔͔࣌ؒΔͷͰϏϧυͰ͖Δ͔ͷνΣοΫ͸ݱঢ়͍ͯ͠ͳ͍
  11. • ϓϧϦΫΤετΛνΣοΫ͢ΔεΫϦϓτΛ Ruby Ͱ ॻ͚Δ 㱺 ϓϧϦΫΤετͷମࡋ౳ΛػցతʹνΣοΫ • νΣοΫ݁Ռ͸ϓϧϦΫΤετ΁ίϝϯτ͞ΕΔ •

    ϓϥάΠϯʹΑΔ֦ு͕Մೳ(ࣗ࡞΋Մ) • ੩తղੳ΍ςετͷ݁ՌΛѻ͏ϓϥάΠϯ͋Γ  ϓϧϦΫΤετͷνΣοΫ https://danger.systems/ruby/ ※ Ruby Ҏ֎ͷ Danger ΋͋Δ͕ϓϥάΠϯ͕๛෋Ͱ͸ͳ͍
  12. masterϒϥϯνͷड͚ೖΕνΣοΫ • ੩తղੳ • Android LintʢՄೳͳΒϏϧυόϦΞϯτຖʣ • ϢχοτςετʢՄೳͳΒϏϧυόϦΞϯτຖʣ& ॏ͍ͨϢχοτςετʢ͋Ε͹ʣ •

    ϏϧυͰ͖Δ͔ͷνΣοΫ • UI ςετ ϓϧϦΫΤετͷϚʔδΛܖػʹ master ϒϥϯν΁౷߹͞ΕͨίʔυΛνΣοΫ 㱺 master ͷίʔυ͕ϦϦʔεՄೳͳ඼࣭Ͱ͋Δ͜ͱΛ୲อ͢Δ ͋Δఔ౓͕͔͔࣌ؒͬͯ΋Α͍ͷͰ໢ཏతʹ 
  13. jobs : android-lint : # .. . android-test : name:

    Android tes t runs-on: macos-10.1 5 strategy : matrix : api-level: [23, 26, 29, 30] fail-fast: fals e timeout-minutes: 30 # ෆ҆ఆͳͷͰλΠϜΞ΢τΛઃఆ steps : - name: Check ou t uses: actions/checkout@v 2 - name: Set up JD K uses: actions/setup-java@v 1 with : java-version: 1 1 - name: Run android tes t uses: reactivecircus/android-emulator-runner@v 2 with : api-level: ${{ matrix.api-level } } target: google_api s arch: x8 6 profile: pixe l disable-animations: tru e script: ./gradlew connectedDebugAndroidTest  masterϒϥϯνͷड͚ೖΕνΣοΫ macOS͕ඞཁ ϚτϦΫεͰฒྻ࣮ߦ ΤϛϡϨʔλ্Ͱ UI ςετΛ࣮ߦ UI ςετͷྫ GitHub ͷը໘
  14.  jobs : android-lint : # .. . notify-failed :

    name: Notify faile d needs: [android-lint, unit-test, android-test, build ] if: failure( ) runs-on: ubuntu-20.0 4 steps : - name: Notif y uses: hkusu/slack-post-action@v 1 env : SLACK_APP_TOKEN: ${{ secrets.ANDROID_CI_SLACK_TOKEN } } with : channel: ‘your_slack_channel ’ message: '*Acceptance Check failed.* ' color: 'danger ' report-sha: ${{ github.sha } } log-button: 'View log’ masterϒϥϯνͷड͚ೖΕνΣοΫ fail ࣌ͷ Slack ௨஌ʢϓϧϦΫΤετͱҧͬͯίϝϯτ൓ө͢Δը໘͕ແ͍ͷͰʣ
  15.  masterϒϥϯνͷड͚ೖΕνΣοΫ ݱࡏͷUIςετʹ͍ͭͯ͸࣮ߦ଎౓͕஗͘ɺςετ݁Ռ΋෼͔ΓͮΒ ͍ͷͰվળͷ༨஍͋Γ.. • Google ͕ఏڙ͢Δ Android Emulator Container

    Λར༻͢Δʁ • https://medium.com/androiddevelopers/continuous-testing-with-android-emulator-containers-95d89a3ea270 • Firebase Test Lab Λ࢖͏ʁ • ฐࣾͰ Firebase ͷΞΧ΢ϯτΛ؅ཧ͍ͯ͠ͳ͍έʔε͕͋Δ.. • Bitrise ͷ Device testing for Android εςοϓΛ࢖͏ʁ • ཪͰ Firebase Test Lab Λར༻͍ͯ͠Δ໛༷͕ͩɺࣗલͰ Firebase ͷΞΧ΢ϯτΛ༻ҙ͢Δ ඞཁ͸ͳͦ͞͏ • AWS Device Farm Λ࢖͏ʁ
  16.  ΞϓϦͷࣾ಺഑෍ • Firebase App Distribution Λ࢖͏ʁ • ฐࣾͰ Firebase

    ͷΞΧ΢ϯτΛ؅ཧ͍ͯ͠ͳ͍έʔε͕͋Δ.. • DeployGate Λ࢖͏ʁ • ฐࣾͷن໛(ΞϓϦ਺ɾਓ਺)Ͱར༻͢Δͱྉۚతͳ΋ͷ͕৺഑.. • ഑෍͚ͩ Bitrise Λ࢖͍ଓ͚Δʁ ࣮ݱʹ͋ͨͬͯݕ౼ͨ͠ιϦϡʔγϣϯ ΍Γ͍ͨ͜ͱ͸ओʹ Android ͷ୯ҰϑΝΠϧʢapkϑΝΠϧʣͷ഑෍ͷΈͳͷ ͰɺAmazon S3 ͱ Slack Λར༻ͨ͠࢓૊ΈΛࣗ࡞͢Δ͜ͱʹͨ͠ ※ ͜ͷ࢓૊Έ͸਺ϓϩδΣΫτͰςετӡ༻ͷஈ֊ͳͷͰɺݱঢ়͸·ͩ Bitrise Λ࢖ͬͯ഑෍͍ͯ͠ΔϓϩδΣΫτͷํ͕ଟ͍Ͱ͢ɻ
  17. ΞϓϦͷࣾ಺഑෍ Amazon API Gateway AWS Lambda  :.- "DUJPOT ᶃ

    masterϒϥϯνͷड͚ೖΕνΣοΫ׬ྃ work fl ow_run Πϕϯτ ᶄ ఆظ࣮ߦʢྫ: ςετظؒ͸ຖே8:00ʹ഑෍ʣschedule Πϕϯτ ᶅ λάͷϓογϡʢྫ: ϦϦʔελάʣpush Πϕϯτ εϥογϡίϚϯυ Amazon S3 • ΞϓϦͷϏϧυ • S3 ΁Ξοϓϩʔυ • Slack ΁௨஌ ᶆ ೚ҙͷόʔδϣϯͷΞϓϦͷ഑෍ ʢλά or ϒϥϯν or ίϛοτSHAΛࢦఆʣ ᶃʙᶆͷ4௨ΓͰϏϧυͷϫʔΫϑϩʔΛىಈ repository_dispatch Πϕϯτ ϏϧυͷϫʔΫϑϩʔ ௨஌ ※ ਪଌ͞Εͳ͍μ΢ϯϩʔυURL + ظݶ෇͖
  18.  jobs : build : name: Buil d runs-on: ubuntu-20.0

    4 steps : - name: Check ou t uses: actions/checkout@v 2 with : ref: ‘your_sha ' - name: Set up JD K uses: actions/setup-java@v 1 with : java-version: 1 1 - name: Build with Gradl e run: ./gradlew assembleDebu g - name: Get apk pat h id: apk-pat h run: echo "::set-output name=path::$(find **/build/outputs/apk -name '*.apk' -type f | head -1) " - name: Upload apk file to S 3 id: uploa d uses: hkusu/s3-upload-action@v 2 with : aws-access-key-id: ${{ secrets.ANDROID_CI_AWS_ACCESS_KEY_ID } } aws-secret-access-key: ${{ secrets.ANDROID_CI_AWS_SECRET_ACCESS_KEY } } aws-region: 'ap-northeast-1 ' aws-bucket: ${{ secrets.ANDROID_CI_AWS_BUCKET } } file-path: ${{ steps.apk-path.outputs.path } } output-file-url: 'true ' content-type: 'application/vnd.android.package-archive ' output-qr-url: 'true ' - name: Get apk inf o id: apk-inf o uses: hkusu/apk-info-action@v 1 with : apk-path: ${{ steps.apk-path.outputs.path } } - name: Notif y uses: hkusu/slack-post-action@v 1 env : SLACK_APP_TOKEN: ${{ secrets.ANDROID_CI_SLACK_TOKEN } } with : channel: ‘your_slack_channel ’ message: '*Build Succeeded!* ' color: 'good ' report-sha: ‘your_sha ' log-button: 'View log’ fields: | [ { "title": "app name" , "value": "${{ steps.apk-info.outputs.application-name }}" , "short": tru e } , { "title": "application ID" , "value": "${{ steps.apk-info.outputs.application-id }}" , "short": tru e } , { "title": "build variant" , "value": "Debug" , "short": tru e } , { "title": "version name (version code)" , "value": "${{ steps.apk-info.outputs.version-name }} (${{ steps.apk- info.outputs.version-code }})" , "short": tru e } , { "title": "min SDK version" , "value": "${{ steps.apk-info.outputs.min-sdk-version }}" , "short": tru e } , { "title": "target SDK version (compile SDK version)" , "value": "${{ steps.apk-info.outputs.target-sdk-version }} ($ {{ steps.apk-info.outputs.compile-sdk-version }})" , "short": tru e } , { "title": "apk file size" , "value": "${{ steps.apk-info.outputs.readable-file-size }}" , "short": tru e } ] image: ${{ steps.upload.outputs.qr-url } } actions: | [ { "type": "button" , "text": "Download apk" , "url": "${{ steps.upload.outputs.file-url }} " } ] ϏϧυͷϫʔΫϑϩʔͷྫ
  19.  ΞϓϦͷࣾ಺഑෍ Slack ͔ΒΞϓϦΛ഑෍͢Δྫ • Android ୺຤ͰΞϓϦΛμ΢ϯϩʔυͰ͖ ΔΑ͏ʹ QR ίʔυΛ༻ҙ

    • ഑෍͞ΕͨΞϓϦΛ • ϓϩδΣΫτؔ܎ऀͰνΣοΫ • QA νʔϜͰςετ • Slack ͔ΒϏϧυ͢Δ͜ͱͷར఺ • ୭͕ԿΛ͔͕ͨؔ͠܎ऀؒͰ෼͔Δ • ։ൃऀͰͳͯ͘΋ϏϧυͰ͖Δ
  20. τʔΫϯͷ؅ཧ  • Ϙοτ༻ʹ࡞ͬͨ GitHub ΞΧ΢ϯτͷ Personal Access Token •

    GitHub Actions ͷϫʔΫϑϩʔதͰඪ४Ͱར༻Ͱ͖Δ GitHub ϢʔβͷτʔΫϯͰ ͸ผͷϫʔΫϑϩʔΛىಈͰ͖ͳ͍ͷͰɺͦͷΑ͏ͳέʔεͰར༻ • GitHub App Λ࡞੒ͯͦ͠ͷτʔΫϯΛར༻ͨ͠ํ͕Α͍͔΋͠Εͳ͍ • GitHub App ͷτʔΫϯΛར༻͢Δҝͷ Actions ΋ز͔ͭެ։͞Ε͍ͯΔ • Cybozu ͞Μ࡞੒ͷ Action • https://github.com/cybozu/octoken-action
  21. name: Format with ktlin t on : workflow_dispatch : schedule

    : - cron: '0 3 * * 3' # ຖिਫ༵೔ͷਖ਼ޕ env : TARGET_BRANCH: 'master ' jobs : format : name: Format with ktlin t runs-on: ubuntu-20.0 4 steps : - name: Check ou t uses: actions/checkout@v 2 with : ref: ${{ env.TARGET_BRANCH } } - name: Set up JD K uses: actions/setup-java@v 1 with : java-version: 1 1 - name: Format with ktlin t run: ./gradlew ktlintForma t - name: Create pull reques t uses: peter-evans/create-pull-request@v 3 with : token: ${{ secrets.ANDROID_CI_GITHUB_TOKEN }} # ϓϧϦΫνΣο ΫͷϫʔΫϑϩʔΛಈ͔͍ͨ͠ͷͰ GITHUB_TOKEN Ҏ֎Λࢦఆ commit-message: Format with ktlin t title: Format with ktlint (auto generated ) body: This PR was automatically generated by the [$ {{ github.workflow }}](https://github.com/${{ github.repository }}/ actions/runs/${{ github.run_id }}) . branch: feature/format_with_ktlin t branch-suffix: short-commit-hash # ಉ͡ϓϧϦΫ͸࡞Βͳ͍  • Gradle λεΫͷ࣮ߦ͔ΒͷϓϧϦΫΤετࣗ ಈ࡞੒͸Α͘࢖͏ • ࠨ͸ࣗಈϑΥʔϚοτमਖ਼ͷྫ • ΄͔ʹ͸ Swagger ϑΝΠϧͷߋ৽Λܖػ ʹ Gradle λεΫΛ࣮ߦ͠ API ΫϥΠΞϯ τͷίʔυΛੜ੒ͨ͠Γ౳