Mercari Engineering Blog

We're the software engineers behind Mercari. Check out our blog to see the tech that powers our marketplace.

AndroidのCI時間を10分短縮し、開発を爆速にするためのKarakuriを作った話

f:id:tadashi-nemoto0713:20180629154905p:plain

こんにちは、メルカリの自動化&品質保証グループ(Automation & QA Group:通称AQA)で、自動化をぶりぶりしている tadashi0713 です。

私は普段、テスト自動化・CI(継続的インテグレーション) / CD(継続的デリバリー)改善・その他社内の生産性を上げるための自動化を行っています。

今回は、最近行なっている Android CIの高速化・改善 についてご紹介したいと思います。

◆ これまでのAndroid CI / CD

去年、私はJP版メルカリAndroidのCI / CDサービスをCircleCI1.0からBitriseに移行しました。

Bitrise - Mobile Continuous Integration and Delivery

Android Test Night #1 というイベントでもLTをしましたので、そちらのスライドも参考にしていただければと思います。


当時、リリース版のビルドとGoogle Play Storeへのアップロードは、エンジニアが手元で手動で行なっていたため、ヒューマンエラー・コストが発生しやすい状況でした。

そのため、Bitriseに移行した上で上記の作業を自動化しました。

BitriseはZapierのようにGUIで簡単にWorkflowを作成することができ、当時初めて触った自分でも簡単に作成することができました。

また、Workflow内で使うことができるIntegrationも充実しており、Google Play Storeへのアップロードも、Integrationの項目を入力するだけで簡単に設定することができます。

f:id:tadashi-nemoto0713:20180626185341p:plain


また、当時はCircleCI1.0からBitriseに移行しただけで、幾分かビルド時間を短縮することができました。

◆ CircleCI2.0に段階的に移行

現在メルカリのエンジニアは増え続け、AndroidエンジニアだけでもBitriseに移行した当時より2倍以上に増えました。

エンジニアが増えると必然的にBitrise上でのビルド回数は増えます。

その結果、ビルド時間自体や、同時実行数などの制限により、エンジニアが待たないといけない状況が多くなりました。

それはとても勿体無いと思い、CircleCI2.0を使うことによって解決できないかと考えました。

メルカリではAPI・iOS・Android・Frontendなど、様々なレポジトリでCircleCI2.0を利用しています。

継続的インテグレーション・継続的デリバリー - CircleCI

また、Androidに関しては、CircleCIが公開しているDocker Imageを利用することができます。

defaults: &defaults
  working_directory: ~/code
  docker:
    - image: circleci/android:api-27-alpha
  resource_class: xlarge

そこでまずは、一番実行される「Pull Request毎に走らせるWorkflow」を改善し、そこから段階的にCircleCI2.0に移行しようと試みました。

◆ Pull Requestで機械が素早くフィードバックする

まず、Pull Request毎に走らせるWorkflowを作りました。

ここでは主に、ユニットテスト・スタイルチェック・静的解析を行っています。

Bitriseと同じWorkflowをCircleCI2.0(resource classはxlarge)で直列実行したところ、5~6分の短縮 に成功しました。

またCircleCI2.0のWorkflowでは、Jobを並列実行をさせることもできます。

Using Workflows to Schedule Jobs - CircleCI

f:id:tadashi-nemoto0713:20180628121935p:plain

これによって、合計で 約10分の時間短縮 に成功しました。


加えて、下記2点の改善をしました。

◇ コードレビュー自動化

コードレビュー自動化ツールとして、Dangerを利用しています。

GitHub - danger/danger: 🚫 Stop saying "you forgot to …" in code review

現時点では特別複雑なルールは決めていませんが、下記2つのDangerのプラグインを活用しています。

GitHub - noboru-i/danger-checkstyle_format: Danger plugin for checkstyle formatted xml file.

GitHub - loadsmart/danger-android_lint: A Danger plugin for Android Lint

これによって、スタイルチェックや静的解析で出た指摘結果を、コメントしてもらうことができます。

f:id:tadashi-nemoto0713:20180628122009p:plain

◇ ユニットテスト可視化

ユニットテストのカバレッジはCodecovを使って可視化させるようにしました。

Codecov

導入に関しては下記の記事を参考にさせていただきました。

developers.yenom.tech

可視化することによって、エンジニアがユニットテストを書くモチベーションはかなり上がりました。

◆ fastlaneを使い、タスクを自動化する

BitriseはIntegrationが充実しているため、とっかかりとしてはとてもよかったのですが、GUIだけで作ろうとすると他のCI / CDサービスへの移行コストが高くなってしまいます。

今回はCircleCI2.0にしましたが、今後より良いCI / CDサービスを求めて、移行する可能性も十分にあります。

そのため、今回は移行と同時に、それらのタスクを fastlane に落とし込みました。

※ Bitriseでもfastlaneは使うことができます。

fastlaneではGoogle Play Storeへのアップロード(supply)以外に下記のような活用をしました。

◇ 社内テスト配布

特定のブランチ(master, epic, release)にコミットされたら、DeployGate・Fabric Betaなどに社内テスト配布するようにします。

これによって、エンジニア以外のプロダクトメンバーでも簡単に実機で確認することができます。

fastlaneには、どちらもActionとして提供されているため、簡単に実装することができます。

# DeployGate
deploygate(
  api_token: ENV['DUMMY_API_TOKEN'],
  user: ENV['DUMMY_USER'],
  apk: apk_path,
  message: message,
  distribution_key: ENV['DUMMY_DISTRIBUTION_KEY']
)
# Fabric Beta
sh("cd .. && touch changelog.txt")
File.write("./changelog.txt", message)
crashlytics(
  api_token: ENV['DUMMY_API_TOKEN'],
  build_secret: ENV['DUMMY_BUILD_SECRET'],
  apk_path: apk_path,
  notes_path: "fastlane/changelog.txt",
  groups: ENV['DUMMY_GROUPS']
)
◇ 自動テストを実行するためのAPKファイルをアップロードする

AQAグループでは現在、Appiumを使ってAndroidの自動テストを実装・実行させています。

詳細に関しましてはこちらの記事をご覧ください。

tech.mercari.com

このテストを実行させるにはAPKファイルが必要となります。

そのため、Workflow内でビルドされたAPKをGoogle Cloud Storageにアップロードさせるようにしています。

fastlaneにはGoogle Cloud Storageにアップロードするためのプラグインがあります。

GitHub - fsaragoca/fastlane-plugin-google_cloud_storage: Download and upload files from Google Cloud Storage

これによって、QAやエンジニアはCircleCIのビルド番号を指定してあげることによって、そのAPKで自動テストを実行させることができるようになっています。

また毎日夜、masterにコミットされた最新のAPKを取得して自動テストを実行しています。

◆ Slack Commandを使って、簡単に社内テスト配布をする

前述したように、特定のブランチにコミットされたら、CircleCI経由で社内テスト配布がされるようになっています。

しかし、それ以外のブランチにおいても、エンジニア以外のメンバーに確認して欲しいなど、社内テスト配信がしたい状況があります。

そのため、Slack Commandを使うことによって、ブランチを指定するだけで簡単に社内テスト配布ができるようにしました。

f:id:tadashi-nemoto0713:20180627114847p:plain

Slack CommandからCircleCIのAPIをCallしてJobをトリガーさせます。

CircleCI API v1.1 Reference - CircleCI

こちらはAWS Lambdaを使い実装しました、詳細についてはこちらの記事をご覧ください。

tech.mercari.com

おわりに

CI / CDの改善は、担当するエンジニアたちの生産性に直結するだけでなく、開発プロセスの改善においてキーとなるものです。

今回は移行がメインになってしまったため、まだ機械にできることはたくさんあります。

引き続きエンジニアやQAなどと協力しながら、妥協することなくAutomation・Karakuri していき、人にしかできないことに集中できる環境にしていきたい思います。

PS・・・テストや自動化の話をカジュアルにできるようにFacebookグループ Agile Testing, Automation and QAの現場 を作ってみました。もしご興味があれば、ぜひ遊びにきてください!

 
Agile Testing, Automation and QAの現場
Facebookグループ · メンバー116人
グループに参加
アジャイルテスティング、自動化、品質保証。そんなキーワードに関心のある方が集まるグループです。アンケートにお答えいただいたからから随時承認中です。ご協力お願いいたします。 日本語をメインで使っていますが、 Some member can communicate with you in English...