つばくろぐ @takamii228

知は力なり

Visual Studio App Centerを使って内部向けに継続的にネイティブアプリを配信する(※追記あり)

はじめに

ネイティブアプリの内部テストを円滑にすすめるために、Visual Studio App Centerを使ってアプリを配信する仕組みを触る機会があったので手順をまとめておきます。

Visual Studio App Centerとは

Microsoftが提供しているネイティ・デスクトップアプリ開発向けの開発プラットフォームです。Azure DevOpsとの連携やアプリのデバイス上でのテスト実行、ストア配信などもサポートしており、ビルドやテストの実行に一定時間の無料枠があります。

visualstudio.microsoft.com

今回はビルド済みのAndroidアプリおよびiOSアプリをテスト端末へ配信する手順をまとめます。

1. Visual Studio App Centerの準備をする

アカウントとプロジェクトを作成する

Visual Studio App Centerは以下のID連携を使ってアカウントを作成することができます。

以前はメールアドレスでのアカウント作成もできたようなのですが、今は上記のアカウントからしか利用できないようです。メールアドレスで作成済みのユーザはメールアドレスにてログインできるようです。

今回はGoogleアカウントで作成します。作成するときにOwner Nameを定義することができ、URLに利用されます。

ログインでの認証でIP制限を用いたいケースは、アカウント管理をAzureのIDアカウント管理に任せ、認証画面にFirewallを設定するとよさそうです。

ログインが完了したら、次にアプリのプロジェクトを作成します。

Android用のプロジェクトは右のAdd New appから作成できます。

f:id:takamii228:20200420214929p:plain

今回はBetaとしました。他にも配信中のアプリや内部テストといったラベルがつけられるようです。

iOSも同様に作成します。

f:id:takamii228:20200420215026p:plain

これで前準備は完了です。アカウントのOwner Name、プロジェクトIDをあとで利用するのでそれぞれ控えておきましょう。

f:id:takamii228:20200420215301p:plain

APIトークンを発行する

以後APIにてApp Centerのリソースにアクセスするため、ログインしたユーザのAPIトークンを発行しておきましょう。APIトークンはユーザのAccount Settingsのメニューの中で発行できます。

f:id:takamii228:20200420215755p:plain

2. apkファイル・ipaファイルを作成する

Visual Studio App Center上でもアプリのビルドは実施できますが、ここでは別環境にてビルドしたipaファイル・apkファイルを配布するというシナリオを説明します。

それぞれ個別に作成するのが面倒だったので、Flutterのプロジェクトを作成したときに最初に作られるサンプルアプリをベースにipaファイルとapkファイルを作成しておきます。こういうときはクロスプラットフォームは便利ですね。

apkの署名はデバッグプロファイルで、ipaは後でインストールする端末の情報を含んだprovisioning profileファイルで署名したものを用意します。

Flutterを使ってapk・ipaファイルを作成する手順はこちらを参考にしてください。

takamii.hatenablog.com

3. Visual Studio App Centerへapk・ipaファイルをアップロードする

公式のドキュメントを参考にアップロードに必要な処理を確認します。

docs.microsoft.com

ドキュメントにはcurlコマンドを使った手順がのっているので、今回はこれを参考にシェルスクリプトを組んで行きます。

なおnpmコマンド経由でもできるようですが、Node環境の準備が面倒なので今回は使いません。

docs.microsoft.com

追記(2021/10/18)

以下のアップロード方法ではアップロードに失敗するようになりました。代替手段としてappcenter cliを使う方法を記事に起こしましたのでそちらを参照ください。

takamii.hatenablog.com

手順を見ればわかりますが、やることは単純でアップロード用のURLを発行して、その発行したURLを使ってファイルをアップロードするだけです。ただしファイルをアップロードするだけだと配信は完了しないため、追加のAPIリクエストを実行して配信のリクエストも自動化してしまいましょう。

APIの仕様書はOpen APIにて公開されています。

openapi.appcenter.ms

なおVisual Studio App Centerで表示されるバージョンはアプリの組み込まれているバージョンで、プロジェクト上の通番はアップロードごとに自動的にRelease IDとしてインクリメントされます。

各Release IDに対してrelease_noteという説明欄を利用できるのですが、これはファイルアップロードのIFでは利用できません。

そのため、リリースとタグ名を紐付けるためにはアップロードが完了したあとに最新のRelease IDを取得し、そのReleaseに対してリリースのタグ名を紐付けるようなPATCHリクエストを投げるとよいでしょう。

最後に配信対象のグループを指定して配信APIを実行すれば配信が開始されます。

以上をまとめると、以下のようなAPIリクエストを順番に実行すればよいです。

  1. ファイルアップロード用のURLを発行する
  2. ファイルをアップロードする
  3. 最新のRelease ID(2で作成されたRelease)を取得する
  4. 3のRelease IDに対応するRelease Noteを更新する
  5. 3のRelease IDの配信を対象のグループに対して開始する

シェルスクリプトでまとめると以下のようになります。

#!/bin/sh

set -x
set -e

# タグ名
RELEASE_TAG_NAME=${1}

# APK ファイルパス
ANDROID_APK_FILE_PATH=${2}

# ipa ファイルパス
IOS_IPA_FILE_PATH=${3}

# Visual Studio App Centerのパラメータ
AZURE_APPCENTER_API_TOKEN='xxxxxxxx'
AZURE_APPCENTER_API_BASE_URL='https://api.appcenter.ms/v0.1/apps'
AZURE_APPCENTER_OWNER_NAME='takamii228'
AZURE_APPCENTER_ANDROID_PROJECT_NAME='AndroidSample'
AZURE_APPCENTER_IOS_PROJECT_NAME='iOSSample'
AZURE_APPCENTER_DISTRIBUTE_GROUP_ID='00000000-0000-0000-0000-000000000000'

# AppCenterにアップロードする一連の処理をまとめた関数
#
# $1: AppCenterのプロジェクト名
# $2: アップロードファイルパス 
# $3: タグ名
#
function upload_file_to_appcenter () {
  UPLOAD_API_BASE_URL=${AZURE_APPCENTER_API_BASE_URL}'/'${AZURE_APPCENTER_OWNER_NAME}'/'${1}

  # アップロード用のURLを発行する
  APP_CENTER_UPLOAD_URL=`curl -v -X POST -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'X-API-Token: '${AZURE_APPCENTER_API_TOKEN} \
    ${UPLOAD_API_BASE_URL}'/release_uploads' | jq -r .upload_url`

  # ファイルをアップロードする
  curl -v -F "ipa=@${2}" ${APP_CENTER_UPLOAD_URL}

  # アップロードしたアプリのリリースIDを取得する
  RELEASE_ID=`curl -v -X GET -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Token: '${AZURE_APPCENTER_API_TOKEN} \
  ${UPLOAD_API_BASE_URL}'/releases' | jq 'max_by(.id) | .id'`

  # アップロードの中でRelease Noteは更新できないため、作成されたリリースIDに対してPATCHリクエストを投げる
  curl -v -X PATCH -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'X-API-Token: '${AZURE_APPCENTER_API_TOKEN} \
    -d '{ "release_notes": "'"${3}"'" }' \
    ${UPLOAD_API_BASE_URL}'/releases/'${RELEASE_ID}

  # アップロードしたアプリをCollaboratorsに配信する
  curl -v -X POST -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'X-API-Token: '${AZURE_APPCENTER_API_TOKEN} \
    -d '{ "id": "'"${AZURE_APPCENTER_DISTRIBUTE_GROUP_ID}"'", "mandatory_update": false, "notify_testers": true }' \
    ${UPLOAD_API_BASE_URL}'/releases/'${RELEASE_ID}'/groups'

  echo "App file ${2} was released in Visual Studio App Center in Project: ${1} for TAG: ${3}, Release ID: ${RELEASE_ID}"
}

# apkファイルをアップロードする
upload_file_to_appcenter ${AZURE_APPCENTER_ANDROID_PROJECT_NAME} ${ANDROID_APK_FILE_PATH} ${RELEASE_TAG_NAME}

# ipaファイルをアップロードする
upload_file_to_appcenter ${AZURE_APPCENTER_IOS_PROJECT_NAME} ${IOS_IPA_FILE_PATH} ${RELEASE_TAG_NAME}

上記のシェルスクリプトをtag push契機で実行するようにCDパイプラインを組むとアップロードと配信を自動で実行できるようになります。

$ ./upload-app-to-appcenter.sh 1.0.0-dev app-release.apk Runner.ipa

4. Visual Studio App Centerからアプリをダウンロードする

配信が開始されると対象者にメール通知が飛んできます。 インストールしたい端末にてそのURLを開き、ログインをするとダウロードリンクを取得することができます。

ダウンロード画面のブラウザでの表示はデフォルトではビルド番号・バージョン番号順になっているため、開発中は固定にしている場合はファイルの識別が難しいです。なので3で説明したとおり、release_noteにタグ名を書いておくと識別しやすいでしょう。

Android上でapkファイルをインストールする

Androidの場合はそのままapkファイルをダウンロードすることでアプリを端末にインストールすることができます。

f:id:takamii228:20200420225129p:plainf:id:takamii228:20200420225135p:plainf:id:takamii228:20200420225140p:plainf:id:takamii228:20200420225145p:plain

iOS上でipaファイルをインストールする

iOSの場合はprovisioning profileやiPhoneApple IDのアカウントの設定にもよりますが、appcenterの構成プロファイルのインストールを端末上で求められるケースがあるようです。

f:id:takamii228:20200420224446p:plainf:id:takamii228:20200420224450p:plain f:id:takamii228:20200420224457p:plainf:id:takamii228:20200420224502p:plain

まとめ

以上がVisual Studio App Center経由でapk/ipaファイルを配信する手順になります。

ipaファイル・apkファイルを作成するCDパイプラインとシームレスに繋げば、tag push契機でテスト用アプリを配信することができるようになりますね。

以前紹介したFlutterのCDパイプラインと合わせてみると以下のようなイメージになります。便利〜!

f:id:takamii228:20200427110819p:plain

内部で手軽にアプリを配信できるような仕組みを用意しておくことで、モバイルアプリでもサーバサイドと同等レベルのよりEnd-to-Endの継続的デリバリーが実現でき、QAやUI確認等の開発のフィードバックライフサイクルをより短縮することができるでしょう。

余談

AppCenter便利やわ〜と思ってた矢先に、配信済みの資材が一斉に消えるという場面に遭遇しました。

え、やっぱ課金必要だったの!?とか焦ってたら公式から障害の連絡が出てました。

何があったかは書いてないですが、Distributeの部分に障害があったとのこと。焦りました。

App Center Status - Distribute is Experiencing Issues

サービスのステータスはこちらで確認できるようです。「あれ?」と思ったときはまずこちらを見てみるようにしましょう。

status.appcenter.ms