Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Hiroyuki Kusu Hiroyuki Kusu
September 03, 2021

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

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

Avatar for Hiroyuki Kusu

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 ΫϥΠΞϯ τͷίʔυΛੜ੒ͨ͠Γ౳