LoginSignup
5
5

More than 3 years have passed since last update.

AndroidアプリでCIツール-Jenkins/CircleCI編

Posted at

CIツール第2弾です。
CIってなにとか、第1弾のGithub Actions編は、こちらをご覧下さい。
Kotlin, LiveData, coroutine なんかを使って初めてのAndroidアプリを作る(10)

今回の目標

JenkinsとCircleCIについて、簡単に動かしてみます。
今回は、リリースビルドについては割愛します。
debugビルドとテストまでとします。

※署名はやろうとすると結構大変みたいで:sweat_smile:
JenkinsはAndroid Signingというプラグインがあるのですが、AndroidStudioで作ったjksファイルはPKCS12じゃないため、今回は使えません。
試してみたい方は、keytoolで作り直してやってみると良いかと思います。

Jenkins

昔なじみのクCIツールです。クラウド型ではありません。
自分で用意した環境で動かす必要があります。でも導入はそんなに難しくないので、やってみましょう。
個人プロジェクトなら、余ってるPCなんかをJenkinsマシンにしちゃうのでもいいかも知れません。お金かからないですからね。ただ、古いPCにすると、スペックが足りなくて、ビルドやテストに時間がかかってしまうかも知れませんが。

今回は、ローカルで動かすJenkinsです。
サーバーを立ててやる方は、まずそちらを用意して環境を作って下さい。

(1) Jenkinsインストール

インストールと言っても難しいことはありません。

1. 自分でインストール

公式サイトからwarをダウンロードして好きな場所に置いておくパターンです。
これのメリットは、よく分からない設定が後に残らず試せることですね。
サーバーを立ててJenkinsマシンとして常に稼働させたいような場合には、2の手順をやりましょう。

ダウンロードページで、一番下の方にある、Generic Java package (.war)と書いてあるところをクリックします。

最新版か、LTS(Long-term Support)のどちらにするかはご自由にどうぞ。私はLTS版を落としました。

ファイルがダウンロードできたら、好きな場所にjenkins.warを移動します。
ターミナルなどでそのフォルダに移動し、次のコマンドで起動します。

$ java -jar jenkins.war

起動ログが流れて、こんな表示が出ると思います。

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

【パスワード文字列】

This may also be found at: /Users/<ユーザー名>/.jenkins/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************

あとでこのパスワードを使うので、コピーしておきます。
起動したターミナルを閉じてしまうとJenkinsも落ちるので、気をつけましょう。

しばらく待つと、ログが止まるので、そうしたらブラウザでhttp://localhost:8080にアクセスします。

以下のようなページが表示されるので、先ほどコピーしたパスワード文字列を貼り付け、[Continue]をクリックします。

qiita10_90.png

次のページでは、[Install suggested plugins]を選びましょう。Androidのビルドに欠かせないGradleやGitのプラグインなんかはこれでインストールされます。

qiita10_91.png

Adminユーザーを任意の情報で作ります。
パスワード忘れるとややこしいので、これだけは忘れないようにしましょう。

qiita10_92.png

次のページでは、Jenkins URLを設定しますが、今はローカルで動かすだけなのでそのままにしておきます。
パブリックドメインを持っていてサーバーを立てる人は、ここにそれを入れるのかな?(やってみたことない)

qiita10_93.png

[Save and Finish]をクリックし、次のページで、[Start using Jenkins]をクリックすると、下のような感じで起動するはずです。

qiita10_94.png

Jenkinsおじさんこんにちは!

2. インストーラーからインストール

公式サイトのダウンロードページで、自分のOSに合ったファイルをダウンロードしてクリックして、あとはインストーラーに任せることも出来ます。
マシンが起動すると自動的に起動してくれる設定をしてくれるので、常時稼働させたいような場合にはこちらが便利です。

ただ、どのユーザー権限で動いているかが分かりづらく、ジョブによってはそのために動かなかったりすることがあります。

なので私は、自分で.warを好きな場所に置いた上で、launchctlの登録も自分でやるのが好きです。あるいは 登録しないで必要なときだけ起動コマンド叩いています。

(2) プラグインのインストール

Androidをビルド、テストできるようにプラグインをインストールする必要があります。

  • ダッシュボード((起動時に表示されている画面)で、[Jenknsの管理]をクリック
qiita10_101.png
  • [プラグインの管理]をクリック
qiita10_102.png
  • [利用可能]タブをクリック
qiita10_103.png
  • フィルターに[Android]と入力し、表示された中から、以下の2つをチェック
    • Android Emulator
    • Android Lint
qiita10_105.png
  • ページ下部にある[ダウンロードして再起動後にインストール]をクリック
qiita10_106.png
  • ダウンロードが始まったら、[インストール完了後、ジョブがなければJenkinsを再起動する ]をクリック
qiita10_107.png
  • 再起動するのを待つ
    • もし長時間待っても変わらないようならブラウザを再読込してみて下さい。

これで準備が出来ました。

なお、AndroidSDKやJDK、Gitなどもインストールしてパスを通しておくことが必要です。
それらについては、個別に調べて下さい。

※インストールしたプラグインは、削除出来ません。

(3) ジョブを作成する

さっそくジョブを作っていきましょう。

1. ジョブを作成

  • ダッシュボードで、[新規ジョブ作成]をクリック
qiita10_110.png
  • 任意の名称を入力する(必須)
  • [フリースタイル・プロジェクトのビルド]を選ぶ
  • [OK]をクリック

qiita10_111.png

2. [General]タブの設定

  • 説明欄に任意の説明を記入
  • [Github project]にチェック
    • [Project url]には、GithubプロジェクトのルートページのUrlを貼り付ける

qiita10_112.png

3. [ソースコード管理]タブの設定

  • [Git]をチェック
    • チェックアウトしてビルドしたいリポジトリのUrlを貼り付ける
    • 認証情報を追加する
    • [追加]をクリック(a)
    • [Jenkins]を選択
    • 必要な設定を入力する
      • Domain: グローバルドメイン
      • 種類: ユーザー名とパスワード
        SSHでアクセスしたい方はSSHを選んで下さい。その場合、Githubへの登録も必要です
      • 選んだ種類に必要な情報を入力する(ユーザー名とパスワードなら、Githubのユーザー名とパスワード)
      • IDと説明は任意
    • [追加]をクリック
      qiita10_114.png
    • [認証情報]のドロップダウンリストから今作成したものを選択
    • [ビルドするブランチ]に任意のブランチを指定
      • ワイルドカードや正規表現を使えます
      • ブランチは複数指定が出来ます
        qiita10_113.png

4. [ビルド・トリガ]タブの設定

  • [SCMをポーリング]をチェック(※任意)
    ※ サーバーを立てている場合は、[Github hook trigger for GITScm polling]が使えます
    • [スケジュール]には、クーロン風の時間指定を記入
    • 例) 15分おきにチェック H/15 * * * *

qiita10_115.png

5. [ビルド環境]タブ

  • [ビルド開始前にワークスペースを削除する]にチェック
  • [Run an Android emulator during build]にチェックを入れる

    • [Run existing emulator]を選択
    • [AVD name]に、作成済みのエミュレーターの名前を入力

      • エミュレーターの名前は、ターミナルなどで以下のように打つと確認できます。
        console $ android list avd

      ※作成済みのエミュレーターを使った方が安定します

    • [Reset emulator state at start-up]にチェック(テスト中にクラッシュしたときなど、次の実行が不安定になるので入れておいた方が良い感覚です)

    • [Show emulator window]をチェック
      ※チェックしないとテストが不安定です

qiita10_116.png
qiita10_117.png

6. [ビルド]タブの設定

  • [ビルド手順の追加]をクリック
  • [シェルの実行]をクリック
  • [シェルスクリプト]に、以下の内容を記入
./gradlew assemble

./gradlew lint testDebugUnitTest

./gradlew connectedCheck

qiita10_118.png

7. [ビルド後の処理]タブの設定

  • [ビルド後の処理を追加]をクリック
  • [Publish Android Lint results]を選択

    • 設定は特に不要
  • [ビルド後の処理を追加]をクリック

  • [JUnitテスト結果の集計]を選択

    • [テスト結果XML]に以下を入力
      • **/test-results/testDebugUnitTest/*.xml
      • **/androidTest-results/connected/*.xml
  • [ビルド後の処理を追加]をクリック

  • [成果物の保存]をクリック

    • [保存するファイル]に以下の内容を入力
      • **/*.apk

qiita10_119.png

以上で設定は終わりです。
実行してみましょう。

ビルド実行をクリックすると、ビルドが手動で起こせます。

qiita10_120.png

ビルド結果ページです。

qiita10_121.png

何度かビルドした後のダッシュボードの表示サンプルです。

qiita10_122.png

Github Actionsと違い、テスト結果はページ上で見られます。

なお、エミュレーターは、作成済みのものを指定した方が良いと書きましたが、更に、閉じるときに確認ダイアログが表示されたままになり、エミュレーターが終了しないままになってしまうので、以下の設定もしておいた方が良いです。

  • エミュレーターの設定ボタンを押す

qiita10_126.png

  • Snapshopの[Settings]タブを選ぶ
  • Save quick-boot state on exit for AVD:XXXXXの項目を、Noにする qiita10_127.png

クイックブートしなくなりますが、テストの時は初期状態の方が都合が良いので、常にOS再起動からやってもらいます。

(4) Slack通知

プラグインでは上手くいかなかったので(いろいろ仕様が変わったため情報が古い)、Curlコマンドでやります(汗)

1. Incoming Webhookの作成

まずは前回と同じ方法で、Incoming Webhookを作成します。

Webhook URLを秘密テキストとして使うため、コピーしておいて下さい。

2. 秘密テキストの作成

ダッシュボードから、

[認証情報]-[System]-[グローバルドメイン]

とメニューを進み、左側のメニューに表示される[認証情報の追加]から、先ほどコピーした文字列を登録します。

qiita10_123.png

3. 秘密テキストのバインド

  • ジョブの設定画面で、[ビルド環境]タブを表示
  • [秘密テキストや秘密ファイルを使用する]にチェックを入れる
    • [追加]をクリック
    • 先ほど作成した秘密テキストを選ぶ
    • 変数名は任意ですがビルドのシェルスクリプトで使う際に間違えないように

qiita10_130.png

4. curl実行

[ビルド]のシェルスクリプトに直接Curlコマンドを書いていきます。

基本的には以下のような形式でCurlコマンドを実行すればOKです。

POST_DATA=`cat << EOF
    payload={
    "text": "I am a test message",
    "attachments": [
        {
            "text": "And here’s an attachment!"
        }
    ]
}
EOF`
curl --data-urlencode "${POST_DATA}" ${WEBHOOK_URL}

メッセージ文の設定は、https://api.slack.com/docs/messages/builder などで適宜カスタマイズして下さい。

以上で設定は終わりです。
保存をクリックして、ジョブを実行してみて下さい。

完了したら、通知が来ます。

qiita10_128.png

qiita10_129.png

私にはこれが精一杯のデザイン(苦笑)
出来れば、branch名とかコミットメッセージとか拾いたいですね。
それらは、[ビルドから利用可能な環境変数の一覧]というリンクから探して使えます。

CircleCI

GithubActionsと同様のSaas型で、日本語サポートもあるらしいCircleCIも試してみました。Githubに特化したCIツールのようですね。
でも、Github特化なら、Github Actionsが出来たし、今から使うメリットは・・・なんだろう?(笑)
あ、テスト結果がブラウザから見られる、かなあ。でも失敗したメソッドを見つけるのが大変だったので、どっちもどっちかなあ・・・

とりあえず、見ていきましょう。

(1) 登録

  • トップページで、[無料でビルドを開始する]をクリック

qiita10_202.png

  • GithubかBitbucketのアカウントでログインをクリック

qiita10_203.png

  • 認証を許可する

qiita10_204.png

(2) プロジェクトの設定

  • Select an organizationが表示されたら、任意の組織を選んでクリック

qiita10_205.png

  • リポジトリを選択

qiita10_206.png

  • [Hello World]の部分をクリックして、Androidを選択
qiita10_207.png
  • [Start Building]をクリック
qiita10_209.png
  • [Add Manualy]をクリック
qiita10_210.png
  • [Download config.yml]をクリック
qiita10_212.png
  • [Start Building]をクリック

qiita10_213.png

これで、いったんプロジェクトが保存されます。

(3) config.ymlを編集する

  • プロジェクトルートに.circleciというフォルダを作成する
  • ダウンロードしたconfig.ymlをそこに置いて開く
  • ビルドステップを記述する

ビルドステップには、デバッグビルドとUnitTestのみにしました。デバッグapkと、テスト結果をArtifactにアップします。
全部でこうなりました。

config.yml
version: 2.1

orbs:
 android: circleci/android@0.2.0

jobs:
  build:
    executor: android/android

    steps:
      - checkout
      - run:
          command: ./gradlew assembleDebug
      - run:
          command: ./gradlew testDebugUnitTest
      - store_artifacts:
          path: app/build/reports
          destination: reports
      - store_test_results:
          path: app/build/test-results
      - store_artifacts:
          path: app/build/outputs/apk/debug/app-debug.apk
          destination: app-debug.apk

とりあえず、GithubActionsと同様、masterブランチに、ブランチ設定をした設定ファイルがないと意図取りに動かないため、masterブランチに上げてしまいます。
今回は、特定のブランチのみに絞って行いたいので、このような設定になります。

config.yml
workflows:
  version: 2
  build-deploy:
    jobs:
      - build:
          filters:
            branches:
              only: feature/qiita_10_sub/circleci

上記の設定を、config.yml一番下に追加して下さい。

  • masterブランチにコミット、push
  • 対象ブランチにマージしてpush

これで対象ブランチでワークフローが走るはずです。

(4)パイプライン実行

動き始めた時のPiplineページの表示。

qiita10_211.png

完了時の表示。

qiita10_214.png

Jobsをクリック。

STEPSタブ

qiita10_215.png

TESTSタブ

qiita10_217.png

ARTIFACTSタブ

qiita10_216.png

ええっ
アーカイブはしてくれないの??

でも一応、index.htmlをクリックすればテスト結果が見られるので、ダウンロードする手間が不要な分、マシですかね。

失敗したときのTESTSタブ

qiita10_219.png

たくさんエラーがあるとちょっと見づらそうですが、Artifactから確認するしか無いですね。

(5) エミュレーターテストについて

CircleCIでは、エミュレーターでのテストが出来ないため、Firebase TestLab等と連携させないとダメみたいです。
なのでここではやりません。興味ある方はこちらなどを参考に実行してみて下さい。

CircleCI 2.0 での Android エミュレーターのテスト

https://support.circleci.com/hc/ja/articles/360000028928-CircleCI-2-0-%E3%81%A7%E3%81%AE-Android-%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88

Test Labについては、いずれ触れてみるつもりです。

(6)その他の設定

1. スキップコメント

[ci skip]でコミットメッセージを始めると、そのコミットのみを含むpushは、パイプラインが実行されません。

qiita10_218.png

2. Slack通知

やっぱりやりたいですよね、Slack通知。
Incoming WebhookでURLを発行するのは同じです。

  • Piplinesのトップページで、[Project Settings]をクリック
qiita10_220.png
  • [Environment Variables]の[Add Environment Variable]をクリック
qiita10_223.png
  • 変数名を入力し、 Incoming Webhook Urlを貼る

qiita10_224.png

  • [Add Environment Variable]をクリック

qiita10_225.png

  • config.ymlにorbを追加
config.yml
orbs:
 android: circleci/android@0.2.0
 slack: circleci/slack@3.4.2
  • config.ymlにstepを追加
config.yml
      - store_artifacts:
          path: app/build/outputs/apk/debug/app-debug.apk
          destination: app-debug.apk
      - slack/status:
          success_message: ':circleci-pass: $CIRCLE_BRANCH のビルドが完了しました\n:github_octocat: User:$CIRCLE_USERNAME'
          failure_message: ':circleci-fail: $CIRCLE_BRANCH のビルドが失敗しました\n:github_octocat: User:$CIRCLE_USERNAME'
          webhook: '${SLACK_WEBHOOK}'

こんな表示です。

成功時

qiita_227.png

失敗時

qiita_228.png

:circleci-pass::github_octocat:はSlack側に登録している絵文字です。

3. バッジ

やっぱりやりたいですよね、バッジ表示。
古い情報ばかりでなかなか大変でしたが、結局は公式の英語のページに書いてありました。

# Example for specific branch:
[![CircleCI](https://circleci.com/gh/circleci/circleci-docs/tree/teesloane-patch-5.svg?style=svg)](https://circleci.com/gh/circleci/circleci-docs/tree/teesloane-patch-5)

これをコピーしてくるのが良いかと思います。

ブランチを自分のパスに直します。私だと、こうなります。
style=svgだと分かりづらいのでshieldにしました。

[![CircleCI](https://circleci.com/gh/le-kamba/qiita_pedometer/tree/feature%2Fqiita_10_sub%2Fcircleci.svg?style=shield)](https://circleci.com/gh/le-kamba/qiita_pedometer/tree/feature%2Fqiita_10_sub%2Fcircleci)

これをREADME.mdに貼った結果です。

qiita10_222.png

まとめ

CIツールでAndroidのアプリのビルド、テスト、結果レポートやapkをアーカイブ出来るようになりました。

個人的には、Github Actionsが使いやすかったですね。Jenkinsも、ビルドマシンとして別マシンが用意できる環境なら大変強力です。
自分が業務で使ったことがあるので慣れているだけかも知れませんが、設定もほとんどGUIで出来るのでやりやすいのではと思います。
CircleCIは、先ほども書いたとおり、GithubActionsが登場した以上、ちょっと今から使うメリットがないような気がします。エミュレーターテストも出来ないし。
テスト結果の見やすさなら、Jenkinsなんですが、これも慣れの問題かも知れません。

今回紹介しなかったBitriseがモバイルアプリ開発に特化しているようなので、CDまで含めて考えるなら、試してみてもいいかも知れないとは思っています。

ここまでのソースは以下のブランチにアップしてあります。

https://github.com/le-kamba/qiita_pedometer/tree/feature/qiita_10_sub/circleci

https://github.com/le-kamba/qiita_pedometer/tree/feature/qiita_10_sub/jenkins

また、masterブランチにymlファイルが入っていないと、masterブランチを無視する設定がきかないので、各ymlファイルだけmasterにもアップしたります。

予告

以前予告した、データをサーバーに保存するのをやります。そのためにはユーザーを一意に特定する必要があるので、ログイン機能が必要になってきます。
ということで、以下のFirebaseの機能を入れていきます。

  • 認証(Authentication)
  • Databse(Cloud Firestore)

これで、アプリをアンインストールしたり機種変更したりしても、過去データを戻すことが出来ます。
ただ、これはやり方を間違えると、Firebaseにとんでもなく課金されてしまうので、注意が必要です。

参考ページなど

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5