2014年GooglePlayベストアプリを受賞した弊社のファッションアプリ「iQON」では、リリース作業をCircleCIとDeployGateで自動化しています。今回、どのように自動化したのかを、昨年11月からVASILYで働き始めた堀江(@Horie1024)がご紹介しようと思います。概要iQONの開発フローは、PullRequestベースで行われており、開発が完了したコードをreleaseブランチに随時PullRequestを送りながら開発を進めています。releaseブランチを作成releaseブランチにPullRequest問題が無ければPullRequestをマージ1~3を繰り返すそして、リリース作業は以下のような手順で行っていました。作業手順としては難しくないのですが、頻繁にあるリリースの度に作業が発生するのでとても面倒でした。実現したいこと今回、自動化することで以下の2項目を実現したいと思います。社内への配布の自動化どう実現するかサンプルプロジェクト解説用にサンプルプロジェクトを用意しました。https://github.com/horie1024/CircleCISample全体の流れGitHubへ差分をPushCircleCIがビルドを開始Slackへビルドの成否を通知DeployGateへAPKをアップロード検証端末にDeployGateアプリ経由でAPKを配信APKをインストールAPK作成の自動化コマンドでのAPK作成AndroidStudioでのプロジェクトのビルドiQONの開発には、AndroidStudioを使用しています。AndroidStudioでは、IDEとビルドシステムが疎結合になっているため、コマンドでのビルドが容易に行えます。Pluginを使用してAndroidプロジェクトのビルドを行います。Guideをご覧ください。ビルドスクリプトAndroidStudioでプロジェクトを新規作成すると、以下の2つのbuild.gradleがあります。module内のbuild.gradleにAndroidプロジェクトをビルドするための設定が含まれています。assembleタスク新規作成したAndroidStudioでプロジェクトには、gradlewという実行形式ファイルが含まれており、gradlewを使いGradleのビルドを実行することが推奨されています。gradlewでビルドを実行する場合、Gradleが自動でダウンロードされ、それを使用してビルドが実行されます。詳しい解説はこちらをご覧ください。Gradleによるビルドは、プロジェクト単位で一つ以上のタスクで構成されており、プロジェクトが実行可能なタスクの一覧は、tasksで表示できます。tasksがあり、APKを作成するには、assembleタスクを実行します。APKの2種類の出力を持っていて、assembleタスクを実行すると両方を出力します。出力を分割するには、assembleDebug、assembleReleaseタスクを利用します。今回は、GooglePlayへアップロードできる状態でAPKを作成したいので、assembleReleaseタスクでAPKを作成します。実際にターミナルからassembleReleaseタスクを実行すると、app/build/outputs/apk以下にAPKが出力されるのが確認できます。このassembleReleaseタスクを自動的に実行することで、APKの作成を自動化します。assembleRelease署名の設定サンプルプロジェクトでは、設定していませんが、本来であればassembleReleaseでAPKを作成する場合には署名を付けます。module内のbuild.gradleのコードを以下のようにします。詳細はこちらをご覧ください。リリース作業手順の確認リリース作業の手順を確認し、自動化する箇所を洗い出します。目的はAPK作成の自動化ですので、1~3の手順に注目すると、「PullRequestのマージによってmasterブランチに変更が生じたらAPKを作成する」とまとめられます。これをCircleCIを利用して自動化します。Serviceでは、GitHubとの連携が前提になっているので、GitHubに差分がPushされたのをトリガーに、任意のコマンドを実行するといったタスクを簡単に定義できます。実際にCircleCIにどのような挙動をさせるかの設定は、circle.ymlという設定ファイルに書き、CI対象のリポジトリに設置します。circle.ymlcircle.ymlの構造は6つのセクションに分かれており、上から順に実行されます。これらのセクション全てについて設定を書く必要はありません。各セクションは、bashコマンドのリストを持て、実行したいbashコマンドを指定していきます。コマンドを指定しない場合、CircleCIがリポジトリのコードから推測したコマンドが実行されます。コマンド実行時のオプションとして、以下3種類を選択できます。CircleCIが推測したコマンドより後に実行これら6つのセクションと3種類のオプションを覚えておけば、circle.ymlは問題なく書けると思います。CircleCIをご覧ください。次に、実際にAndroidプロジェクトをビルドするcircle.ymlを書いてみます。applicationsを参考に書いていきます。checkoutセクションとdatabaseセクションについては、必要が無いので設定を書きません。▪︎VMの設定ビルドを実行するには、ANDROID_HOMEの定義が必要になるため、circle.ymlのmachineセクションで定義します。SDKが用意されてるので、そのPathを指定します。Javaのバージョンをopenjdk7に指定します。SDKは初期状態のため、必要に応じてアップデートします。21.1.2をインストールするよう追記します。dependenciesによってビルドが失敗するためです。"android-21,build-tools-21.1.2"サポートライブラリや、GooglePlayServicesライブラリを使用する場合、filterに以下のidを追加します。"extra-google-m2repository,extra-android-m2repository"また、filterに指定できるidは、以下のコマンドで確認できます。--extended▪︎testセクションtestセクションは、必ず実行されてしまうため、overrideでダミーの処理を行うようにします。Pluginを導入している場合、testセクションでテストを実行します。test▪︎APKの作成deploymentセクションでAPKを作成します。deploymentセクションは、複数のサブセクションを持てます。サブセクションは、branchセクションを持ち、差分が生じたブランチが、指定したbranchにマッチした場合に、commandsを実行します。詳しい解説は、こちらを参照してください。assembleRelease▪︎ビルドできるか試すCircleCIで実際にAndroidプロジェクトをビルド出来るか確認します。GitHubのアカウントでログインもしくはサインアップします。Projectsをクリックします。1でアカウントを選択し、2でCIの対象とするプロジェクトを選択します。プロジェクトを選択すると初回のビルドがスタートします。初回ビルドでは、circle.ymlが不正だったためビルドが失敗しました。masterブランチに変更をPushmasterブランチでcircle.ymlを修正し、再度Pushするとビルドがスタートします。circle.ymlが正しく修正されたため、無事ビルドが成功しました。成果物Androidプロジェクトがビルドでき、APKを作成できました。次にAPKをGooglePlayにアップロードできるよう、作成したAPKをダウンロードできるようにします。artifactsとしてビルド毎にダウンロードできます。artifactsとしてダウンロードするには、ビルド成果物を保存する必要があります。成果物を保存するには、generalセクションのartifactsセクションに成果物のパスを指定します。generalセクションは、6つのセクションとは別に、特定のセクションに属さない、ビルド全体に関する設定を書くことができるセクションです。assembleReleasemasterブランチでのみタスクが実行されるようにするここまでで、GitHubでPullRequestをマージもしくは変更をPushすることで、CircleCIのタスクが実行されるようになりました。master以外のブランチへPushした場合でもビルドが実行されてしまいます。そこで、masterブランチへのPushでのみビルドが実行されるようにします。buildを参考に、circle.ymlに設定を追加します。generalセクションにbranchesを追加することで、masterブランチへのPushでのみビルドが実行されるようになります。Slack連携Slackと連携させることで、ビルドの成功・失敗を通知させることができます。URLを入力後、Saveをクリックします。Memoryでビルドが頻繁に失敗するようになりました。ranとして載っています。Androidプロジェクトで発生した場合の対策ですが、プロジェクトによって原因が異なる可能性があるので確実ではありませんが、Gradleのバージョンを2系に上げることで改善できました。社内へのAPKの配布には、DeployGateを利用します。DeployGateは、APKをアップロードすることで、専用アプリを介して開発中のアプリを簡単に配布できるサービスです。DeployGateでのアプリの配布方法DeployGateでのアプリの配布方法は、サインアップ後のチュートリアルがわかりやすく、すぐに理解できました。こちらの資料も参考になりました。APIを利用することで、cURLコマンドで簡単にAPKをアップロードできます。https://deploygate.com/api/users/YOUR_USER_NAME/appsAPIキーの取得APIを利用するには、APIキーが必要になります。APIキーは、DeployGateへ新規登録することで発行されます。新規登録後に、https://deploygate.com/settings#apiKeyにアクセスすることで確認できます。ターミナルでの実行Macのターミナルから実行し、DeployGateにアップロードされることを確認します。DeployGateのダッシュボードにアップロードしたアプリが表示されれば成功です。実際の配布の流れは、以下の通りです。検証端末でDeployGateアプリを起動し、APKをダウンロード・インストールDeployGateからの配信を受けるには、DeployGateアプリをインストールしておく必要があります。CircleCIとの繋ぎこみCircleCIからコマンドを実行し、APKをDeployGateへアップロードします。masterへのPushからAPKがDeployGateへアップロードされるまでの流れは、以下のようになるはずです。masterへ差分をPushCircleCIが検知し、APKを作成DeployGateへのアップロードを実行したがって、circle.ymlを以下のように記述します。https://deploygate.com/api/users/YOUR_USER_NAME/appsdeploymentのcommandsで、APKを作成とAPKのDeployGateへのアップロードを実行しています。ここで、APIキーが直書きになってしまっているので、CircleCIの環境変数に登録し、それを参照するようにします。variablesから設定します。variableをクリックします。するとDEPLOY_GATE_API_KEYとして環境変数が登録されます。登録した環境変数を使用するように書き換えます。https://deploygate.com/api/users/YOUR_USER_NAME/appsこのように、登録した変数は、circle.ymlから参照できます。コマンドの別ファイルへの切り出しcircle.ymlを見やすくするために、コマンドを別ファイルにまとめてしまいます。https://deploygate.com/api/users/YOUR_USER_NAME/appsその結果、最終的なcircle.ymlは、以下のようになります。./deploy.sh動作確認うまくいけば、DeployGateアプリにビルドしたAPKが配信されます。ArtifactsからAPKをダウンロードできます。自動化した結果APKの作成から社内配布まで自動化することができました。PullRequestのマージが行われるとAPKが配布されるようになり、リリース作業がかなり効率化されました。リリース完了まとめCircleCIとDeployGateを利用して、リリース作業を自動化してみました。昨年11月から実際のリリース作業に組み入れ運用していますが、思っていた以上にストレスが減り、快適に開発を行えるようになりました。チームメンバーからの評判も良く、やってみて良かったと思います。改善できる点があり、継続して改善していこうと考えています。現在、GooglePlayへのAPKのアップロード自動化を組み込んだ開発フローおよびリリース作業手順をテスト中です(実験した内容はQiitaに上げました)。今回紹介出来なかった内容もありますので、近日中にご紹介できればと思います。1月28日にSmartNewsさん、Wantedlyさんとベストアプリ勉強会という勉強会を開催します。15:15CircleCIとDeployGateでAndroidアプリのリリース作業を自動化してみた関連記事2019-02-15iOSで構築しているCIのWorkflow紹介こんにちは。iOS担当の荒井です。今回はiOSチームで構築してい...2018-03-13AlexaでAPKを配布するスキルの作り方こんにちは、VASILYで主にAndroid開発を担当している@Horie1024...2017-10-16ビルドバリアントによる複数バージョンのAPKのビルドアプリエンジニアの堀江(@Horie1024)です。Labを使ったAndroidアプリのテストAndroidエンジニアの堀江(@Horie1024)です。Androidアプリのテ...2016-06-15AndroidのCI環境をCircleCIからWerckerに移行しましたこんにちは、エンジニアの堀江(@Horie1024)です。BLOGプロフィール株式会社ZOZOテクノロジーズのテックブログです。