Bitrise API で、Bitrise ワークフローのビルドを再利用する

CI

Bitrise でモバイルアプリのテストを走らせる時などに、ワークフローでビルドしたアプリを再利用したい。
そんなお話。

TL;DR

Personal Access Token を発行して、getAppステップを使う
以下の備忘録は、実際に API を使ってみたい時や、他の CI に Artifacts を取り込みたい時のもの。

Bitrise API

Bitrise API
まだ v0.1 の段階で、メジャーとの互換性は保証されていないし、 limit とかも特に書いてない。
Discussion を見ると 2017 年ぐらいからずっと v0.1 なので、そういうものだと割り切って使う。

下準備

Artifact にアクセスするには Personal Access Token の発行が必要。
Bitrise マイページのセキュリティ設定 に移動して、"Personal access tokens (BETA)" の項目から "Generate Now" を押すと画面が開く。

Bitriseのセキュリティ画面。Generate newというラベルのボタンがあるので押す

トークンの期限は 1 時間〜 1 ヶ月。一応無期限も設定できる。再表示は不可。

※ このまま Bitrise のステップに乗っかる場合は、以下をとばしてgetAppステップを使うへ。

Bitrise API を使って Artifact をダウンロードする

Bitrise の Deploy to Bitrise.io ステップを実行すると、ビルドの成果物が Artifact として保存される。
この Artifact のスラッグは、ビルド毎にランダムで生成され、一見特定は難しい。
しかし Bitrise はアプリ毎に ID を持ってるので、そこからビルド履歴をたどって Artifact の URL を特定できる。

アプリ ID というのは、対象アプリのページ URL "https://app.bitrise.io/app/foo/" から "foo" の部分。 BitriseのアプリページのURLから、アプリIDを特定できる

1. ビルドスラッグの取得

まずは Personal Access Token とアプリ ID を使って API にアクセスし、最新ビルドのスラッグを取得する。

ビルド一覧は https://api.bitrise.io/v0.1/apps/{app-slug}/builds で取得する。
{app_slug} にはアプリ ID が入る。

今回は特定の環境に絞りたいので、その環境でビルドしているワークフロー名 ${workflow} も加える。
また、最新かつ成功したビルドが欲しいので、limit=1status=1 パラメーターも加える。

shell

curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds?workflow=${workflow}\&limit=1\&status=1

data 配列の最初にある slug がビルドのスラッグなので、jq を使って取得。

shell

curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds?workflow=${workflow}\&limit=1\&status=1 \
 | jq -r '.data[0].slug'
# > abcde123456890

2. Artifact スラッグの取得

今度は Artifacts を https://api.bitrise.io/v0.1/apps/{app-slug}/builds/${build_slug}/artifacts から取得する。
${build_slug} には、1 で取得したビルドのスラッグが入る。

次に取りたいのは、Artifact のスラッグ。
Artifact の title からダウンロードしたいファイル名(拡張子含む)を jq の select で引っ張ってくる。

shell

curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds/${build_slug}/artifacts | jq -r ".data[] | select(.title | inside(\"${app_name}\")).slug"
# > artifact123456890

これで Artifact のスラッグが取れる。

3. Artifact の URL 取得

Artifact の情報は https://api.bitrise.io/v0.1/apps/{app-slug}/builds/${build_slug}/artifacts/${artifact_slug} にある。
そこの data.expiring_download_url に格納される URL が、最終的に取りたい値。

shell

curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds/${build_slug}/artifacts/${artifact_slug} | jq ".data.expiring_download_url"
# > "https://bitrise-prod-build-storage.s3.amazonaws.com/builds/abcde123456890/artifacts/123456/app.apk?params=iroiro"

4. URL からダウンロード

あとは、3 で取得した URL にアクセスし、ダウンロードして保存するだけ。

shell

# ※ 実際に取得される S3 の URL は事前署名付き
curl "https://bitrise-prod-build-storage.s3.amazonaws.com/builds/abcde123456890/artifacts/123456/app.apk?params=iroiro" > "app.apk"

5. まとめ

bash で最初から最後まで実行するとこうなる。

download_artifact.sh

#!/bin/bash

# $BITRISE_PERSONAL_ACCESS_TOKEN に personal access token があり、
# deploy ワークフローで生成された app-release.apk を取りたい時。
readonly access_token=$BITRISE_PERSONAL_ACCESS_TOKEN \
  app_slug=abcd123456 \
  workflow=deploy \
  app_name=app-release.apk

# ビルドスラッグ
build_slug=`curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds?workflow=${workflow}\&limit=1\&status=1 | jq -r '.data[0].slug'`

# アーティファクトスラッグ
artifact_slug=`curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds/${build_slug}/artifacts | jq -r ".data[] | select(.title | inside(\"${app_name}\")).slug"`

# ダウンロード URL
app_download_url=`curl -H "accept: application/json" -H "Authorization: ${access_token}" -X GET https://api.bitrise.io/v0.1/apps/${app_slug}/builds/${build_slug}/artifacts/${artifact_slug} | jq -r '.data.expiring_download_url'`

# ダウンロード
curl $app_download_url > $app_name

getAppステップを使う

前項目でやった作業は、Bitrise の getApp ステップで再現可能。
"Artifact Name" にファイル名(拡張子含む)、"Access Token" に Personal Access Token を指定、"App ID" にアプリ ID を入れる。

アプリ ID というのは、対象アプリのページ URL "https://app.bitrise.io/app/foo/" から "foo" の部分。 BitriseのアプリページのURLから、アプリIDを特定できる

デフォルトでは /Users/vagrant/git/getApp/ 内に Artifact がダウンロードされる。
試しに、ダウンロードした .apk ファイルを、Bitrise の [BETA] Virtual Device Testing for Android ステップで Firebase Test Lab に投げ、Robo テストを実行する。
とりあえず動くことはわかった。

テスト結果の動画の一部。アプリの画面にはフォームがあり、テキスト入力の部分をタップしている。

終わり

事前に仕込みが必要なものの、Test Lab 込みで速く・安く済ませるのには良さそう。