こんにちは、Androidエンジニアの堀江(@Horie1024)です。VASILY DEVELOPERS BLOGは新年2回目の更新になります。ちなみに去年の更新回数は53回だったようです。
また、Androidチームのトピックスとしては、先日ベストイノベーティブアプリ大賞を受賞した際にいただいたトロフィーがオフィスに届きました。今年も賞をいただけるようVASILY全員で頑張ります。
はじめに
Android版iQONのリリースは約1~2週間に1回行っており、リリース前には社内QAを実施しています。QAを実施するために必要な作業は定型な作業ですが、手動で行うと思いの外時間が掛かりますし、作業の抜け漏れが起きる事もあります。
そこで、タイトルにもあるようにQAの実施に必要な作業を自動化しました。一度自動化してしまえば作業に抜け漏れがなくなり、自分たちの時間も節約できます。
今回は具体的にどのように自動化したのかご紹介しようと思います。
自動化の方法
VASILYでは、以前からHeroku上にホストしたHubotをSlackと連携させ利用しています。したがって、今回もSlackとHubotを使い自動化を行っていきます。Slackから特定の文字列を入力するとHubotが反応し、QA実施に必要な作業を自動的に実行するようにします。
この記事ではHerokuやHubotの設定は紹介しませんが、Web上に良い記事が多くありますので参考にしてみてください。
QA終了までの流れの整理
まず、今までのQA開始からQA終了までの流れを整理し書き出しました。QAは毎回以下のような流れで開始され終了します。
- QAの開始・終了日時をSlackで全員に通知
- GoogleスプレッドシートでQAシートを作成
- Qiitaチームにリリースノートを作成
- APKを作成しBetaで社内に配布
- SlackでQA依頼
- QA終了日時を過ぎたらSlackにQA終了報告とお礼を投稿
次にこれらをどこまで自動化するのかを考えます。
自動化する範囲
どこまで自動化するかを考え易くするために先程整理したQAの流れをQA予告、QA準備、QA開始、QA終了の4つのフェーズに分類してみました。
分類する中で気づいたのは、QA準備以外のフェーズは全てSlackへの投稿という点です。これらのQA実施に関する連絡は、柔軟に対応できるようにした方が使い勝手が良さそうに思えます。
例えば、QAをお願いする時に一言添えたいかもしれませんし、QAの終了日時が伸びるかもしれません。また、QAでたくさんのフィードバックをもらえてお礼の文言を変えたい場合もあるかもしれません。
したがって、QA準備フェーズの自動化にフォーカスします。
コマンドの設計
SlackからHubotを使い自動化するには、Hubotに反応させるコマンドを決める必要があります。シンプルにandroid qa
としてみました。
Slackでandroid qa
と入力するとHubotが反応し以下の作業を実行するようにします。
- GoogleスプレッドシートでQAシートを作成
- Qiitaチームにリリースノートを作成
- APKを作成しBetaで社内に配布
どう自動化するか?
QAシート、リリースノートの作成、APK配布を自動化するにはどうすれば良いでしょうか。各作業について考えていきます。
1. GoogleスプレッドシートでQAシートを作成
QAシートは以下のフォーマットを利用しています。
Sheets APIを使うことでフォーマット通りのスプレッドシートを作れますが、コードが複雑になるため予め用意したスプレッドシートをマスターにし、それをDrive APIでコピーしてQAシートを作ります。
追記
マスタースプレッドシートの共有にサービスアカウントを追加する必要があります。
2. Qiitaチームにリリースノートを作成
Qiitaチームへのリリースノートの作成にはQiita API v2を使用し、POST /api/v2/itemsを使うことで投稿することができます。リリースノートのフォーマットは以下の通りで、記事のタイトルには「Android バージョン番号 リリースノート」、タグには「リリースノート」、「Android」を付けます。
# リリース日 # QA * 期限 * QAシート # 更新内容
タイトルのバージョン番号やリリース日、QAの期限はSlackを通じて対話的に入力できるようにします。また、更新内容にはGitHub APIのRepository/Releasesを使用し、GitHubのリリース機能で記載した内容を取得するようにします。そして、QAシートの項目には、作成したQAシートのURLを記載します。
3. APKを作成しBetaで社内に配布
AndroidチームではCIにWerckerを使用しています。以下のQiitaの記事にまとめていますが、Wercker APIでビルドを実行しAPKの作成とBetaでの配布を行います。
記事内でも紹介していますが、Wercker APIをHubotから使用するためのAPI ClientをOSSとして公開しています。
以下のように簡単にWercker APIを使用することが可能です。
const Wercker = require('wercker-client').default; const wercker = new Wercker({ token: 'your_token' }); wercker.Runs .getAllRuns({applicationId: "your_application_id"}) .then((res) => { console.log(res); }).catch((err) => { console.log(err); });
全体の流れ
Slackにandroid qa
と入力してからの処理の流れを図にすると以下のようになります。
① Slackにandroid qa
と入力
② Hubotが反応
③ Drive APIを使いQAシートを作成
④ Qiitaチームにリリースノートを投稿
⑤ Wercker APIを使いビルドを開始
⑥ WerckerがGitHubからアプリのコードを取得しAPKを作成
⑦ BetaでAPKを配布
⑧ 配布の完了をSlackに通知
実装
上記の流れを実装したサンプルコードです。
サンプルコードでは以下の流れで処理を行っています。
- Google APIクライントの初期化
android qa
コマンドを定義- リリースするVersion Nameを入力
- マスターとなるシートをコピーしてQAシートを作成
- QAシートのタイトルをVersion Nameを含めたタイトルに更新
- QAシートのアクセス権限を特定のdomainに属するアカウントのみ編集できるよう変更
- GitHubのrepositoryからリリースノートを取得
- リリース日を入力
- QA期間を入力
- リリースノートをQiitaに投稿
- Wercker APIを使いビルドを開始
ローカルで実行
実行中の様子はこのようになります。
リリースノートもテンプレート通りに投稿されています。
実装する上で困った点
Google APIクライントの初期化
HubotからDrive APIを操作するにはgoogle/google-api-nodejs-clientを使うのですが、認証・認可についての情報が少なく困りました。
手順としては、最初にAPIマネージャーからGoogle Drive APIを有効にします。
https://console.cloud.google.com/apis/api/drive/overview
次にコンソールにアクセスし、サービスアカウント名とサービスアカウントIDを入力してサービスアカウント新規作成します。役割には、スプレッドシートの編集を行う必要があるため編集者を指定します。役割の詳細はこちらから確認できます。
キーのタイプにJSONを選択し、作成をクリックするとJSONファイルがダウンロードされます。
ダウンロードしたJSONを使用し認証・認可を行います。こちらを参考に、以下のようにgoogleapisモジュールのJWT(JSON Web Token)メソッドを使いクライアントを作成します。
JSONファイル中にclient_email
とprivate_key
というフィールドがあるので、それを以下のSERVICE_ACCOUNT_EMAIL
、SERVICE_ACCOUNT_KEY
に当てはめます。
const jwtClient = new google.auth.JWT( SERVICE_ACCOUNT_EMAIL, null, SERVICE_ACCOUNT_KEY, ['https://www.googleapis.com/auth/drive'], null);
これでDrive APIを使用できるようになります。
SERVICE_ACCOUNT_KEY
をHerokuの環境変数から読み込むとクライアントの初期化に失敗する場合があるので、以下の記事にまとめています。
Hubotとの対話的な入力
リリースするVersion Name、リリース日、QA期間はHubotと対話的に入力するようにしています。今回は、hubot-conversationモジュールを使用しました。
VersionNameを入力させるには以下のようなコードになります。
// Slackに通知 msg.reply("リリースするVersion Nameを入力してください。"); // Version Nameの入力を待機 var dialog = conversation.startDialog(msg); dialog.addChoice(/([0-9]*\.[0-9]*\.[0-9]*)/, (conversationMsg) => { // 入力された文字の取得 console.log(conversationMsg.match[1]); });
Drive APIでのファイルのパーミッション変更方法
ファイルのパーミッションを変更するには、Permissionsのcreateメソッドを使用します。
パーミッションはrole
とtype
の組み合わせで指定します。例えば、編集権限をvasilyドメインのユーザーに付与するなら以下のように指定します。
{ role: "writer", type: "domain", domain: "vasily" }
google/google-api-nodejs-clientでは、Request Bodyをresourceパラメータで指定するのでファイルのアクセス権限を変更するコードは以下のようになります。
drive.permissions.create({auth: jwtClient, fileId: sheetsId, resource: { role: "writer", type: "domain", domain: "vasily" }}, (err, res) => {});
まとめ
自動化した結果、QAの準備が自動的に完了するようになりとても楽になりました。また、作業の抜け漏れも無くなりスムーズにQAを行うことができています。GitHubのリリース機能でリリース内容を書くのを忘れる事があるのが課題です。
VASILYでは一緒にサービスを開発してくれるエンジニアを募集しています。今後はiQON以外の新規サービスの開発も行う予定ですので、少しでもご興味のある方のご応募をお待ちしています。