Android
iOS
fabric
Bitrise
OriginalゆめみDay 11

[BITRISE][iOS][Android] BITRISE でブランチにpushされたらビルド→Fabric Betaにアップロード→テスターに通知→Slackに通知するようにしてみた

前回の続きです。
BITRISEで以下のようにします。

  1. 指定ブランチへのpushをトリガーにしてビルド開始
  2. Fabric Betaにアップロードし、テスターにメールで通知する
  3. Slackの特定のチャンネルにアプリの情報、FabricのリリースノートとURL、QRコードを通知する

これらを設定したymlのtriggers, workflow部分を抜粋して貼っておきます。

iOS

...

trigger_map:
- push_branch: master
  workflow: WORKFLOW_NAME

...

  WORKFLOW_NAME:
    steps:
    - activate-ssh-key@3.1.1:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@3.5.2: {}
    - cache-pull@1.0.0: {}
    - script@1.1.4:
        title: Do anything with Script step
    - certificate-and-profile-installer@1.8.8: {}
    - xcode-archive@2.3.7:
        inputs:
        - configuration: Debug
    - deploy-to-bitrise-io@1.3.7: {}
    - cache-push@1.1.4: {}
    - fabric-crashlytics-beta-deploy@2.2.1:
        inputs:
        - api_key: TBD_FABRIC_APIKEY
        - build_secret: TBD_FABRIC_SECRET
        - release_notes: "$BITRISE_GIT_MESSAGE"
        - group_aliases_list: "$FABRIC_GROUP_ALIASES"
    - ipa-info@1.0.1: {}
    - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x

            # write your script here

            buildNumber="$IOS_APP_VERSION_NAME ($IOS_APP_VERSION_NAME.$BITRISE_BUILD_NUMBER)"
            appName=$IOS_APP_NAME
            bundleId=$IOS_IPA_PACKAGE_NAME
            workflowId=$BITRISE_TRIGGERED_WORKFLOW_ID
            url="https://apps-ios.crashlytics.com/projects/"
            echo "$BITRISE_APP_TITLE $buildNumber $workflowId $url"
            message="The workflow \"$workflowId\" was succeeded!\n$appName $buildNumber\n$bundleId\n$BITRISE_GIT_MESSAGE\n$url"

            envman add --key SLACK_MESSAGE_BODY --value "$message"
            envman add --key SLACK_MESSAGE_URL --value "$url"
            echo "SLACK_MESSAGE_BODY is $SLACK_MESSAGE_BODY"
            echo "SLACK_MESSAGE_URL is $SLACK_MESSAGE_URL"

            # or run a script from your repository, like:
            # bash ./path/to/script.sh
            # not just bash, e.g.:
            # ruby ./path/to/script.rb
    - create-install-page-qr-code@0.1.2:
        inputs:
        - public_install_page_url: "$SLACK_MESSAGE_URL"
    - slack@2.6.3:
        is_always_run: false
        inputs:
        - message: "$SLACK_MESSAGE_BODY"
        - emoji: ":bitrise:"
        - webhook_url: https://hooks.slack.com/services/PATH_OF_IDS
        - channel: "#CHANNEL_NAME"
        - from_username: Bitrise CI
        - image_url: "$BITRISE_PUBLIC_INSTALL_PAGE_QR_CODE_IMAGE_URL"

Android

...

trigger_map:
- push_branch: master
  workflow: WORKFLOW_NAME

...
  WORKFLOW_NAME:
    steps:
    - activate-ssh-key@3.1.1:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@3.5.2: {}
    - cache-pull@1.0.0: {}
    - script@1.1.4:
        title: Do anything with Script step
    - generate-text-file@0.0.3:
        inputs:
        - file_name: "$FABRIC_GROUP_ALIASES_FILE_PATH"
        - file_content: "$FABRIC_GROUP_ALIASES"
    - generate-text-file@0.0.3:
        inputs:
        - file_name: "$FABRIC_PROPERTIES_FILE_PATH"
        - file_content: |-
            apiSecret=$FABRIC_API_SECRET
            apiKey=$FABRIC_API_KEY
            betaDistributionReleaseNotes=\"$BITRISE_GIT_MESSAGE\"
            betaDistributionGroupAliasesFilePath=$FABRIC_GROUP_ALIASES_FILE_PATH
    - install-missing-android-tools@2.0.2: {}
    - gradle-runner@1.7.7:
        inputs:
        - gradle_file: "$GRADLE_BUILD_FILE_PATH"
        - gradle_task: assembleDebug crashlyticsUploadDistributionDebug
        - gradlew_path: "$GRADLEW_PATH"
    - deploy-to-bitrise-io@1.3.7: {}
    - cache-push@1.1.4: {}
    - apk-info@1.3.0: {}
    - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x

            # write your script here
            plistPath=$BITRISE_INFO_PLIST_PATH
            echo "Writing to $plistPath"

            versionNumber=$ANDROID_APP_VERSION_NAME
            packageName=$ANDROID_APP_PACKAGE_NAME
            buildNumber="$versionNumber ($BITRISE_BUILD_NUMBER)"
            workflowId=$BITRISE_TRIGGERED_WORKFLOW_ID
            url="https://apps-ios.crashlytics.com/projects/"
            echo "$BITRISE_APP_TITLE $buildNumber $workflowId $packageName $url"
            message="The workflow \"$workflowId\" was succeeded!\n$BITRISE_APP_TITLE $buildNumber\n$packageName\n$BITRISE_GIT_MESSAGE\n$url"

            envman add --key SLACK_MESSAGE_BODY --value "$message"
            envman add --key SLACK_MESSAGE_URL --value "$url"
            echo "SLACK_MESSAGE_BODY is $SLACK_MESSAGE_BODY"
            echo "SLACK_MESSAGE_URL is $SLACK_MESSAGE_URL"

            # or run a script from your repository, like:
            # bash ./path/to/script.sh
            # not just bash, e.g.:
            # ruby ./path/to/script.rb
    - create-install-page-qr-code@0.1.2:
        inputs:
        - public_install_page_url: "$SLACK_MESSAGE_URL"
    - slack@2.6.3:
        is_always_run: false
        inputs:
        - message: "$SLACK_MESSAGE_BODY"
        - emoji: ":bitrise:"
        - webhook_url: https://hooks.slack.com/services/CHANNEL_OF_PATH
        - channel: "#CHANNEL_NAME"
        - from_username: Bitrise CI
        - image_url: "$BITRISE_PUBLIC_INSTALL_PAGE_QR_CODE_IMAGE_URL"

以上!

というわけにもいかないので以下説明になります。

1. 指定ブランチへのpushをトリガーにしてビルド開始

BITIRISEからWebhook URLをコピー

  1. アプリ > Workflow > Codeタブを選択します。
  2. WEBHOOKSでGitHubを選択し、Webhook URLをコピーします。 webhook_setting.png

1-1. GitHubの設定 - webhook URLの追加

  1. プロジェクトをブラウザで開きます。
  2. Settingsタブを選択します。
  3. 左メニューのWebhooksを選択します。
    github_webhook.png

  4. 右上のAdd webhookを選択して、以下の値で設定します。
    Payload URL: BITRISEでコピーしたWebhook URL
    Content type: application/json
    Which events would you like to trigger this webhook?: Let me select individual events.
    github_webhook_add_1.png

  5. Let me select individual events.で必要なイベントにチェックを入れます。

  6. Add webhookを選択して追加します。
    github_webhook_add_2.png

1-2. BITRISEの設定 - トリガーの追加

add_triggers.png
1. アプリ > Workflow > Triggersタブを選択します。
2. PUSH タブを選択します。
3. + ADD TRIGGERボタンを押下してトリガーを追加します。
4. 左側でブランチ名を指定します。
5. 右側に実行したいWorkflowを選択します。

2. Fabric Betaにアップロードする

2-1. iOS

プロジェクトにFabricを導入済みの前提です。
導入していない方はこちらを参照してください。

2-1-1. Archive

Fabricにあげるためにipaを作る必要があります。
初めからdeployというWorkflowが作られていますが、もし下記のstepが見当たらない場合追加しなければなりません。
Xcode Archive & Export
add_archive_step.png

2-1-2. Fabric Beta

非常に便利なstepが用意されています。
Fabric / Crashlytics deployer
add_fabric_step.png

:arrow_up: Uploading Distribution

Fabric: API KeyFabric: Build Secretを設定するだけでOK!
set_fabric_step.png

:pencil: Release Notes

Release NotesはFabric上のRelease Notesにそのまま反映されます。
自分の場合は、$BITRISE_GIT_MESSAGE を入れています。
こうしておけば、マニュアルでビルドした場合にはMessageで指定した文字列がセットされ、Triggerでビルドした場合はgitのcommitメッセージがそのまま反映されます。

:bell: Notify

Fabricアップロード時の通知は、Notify: Emailsを指定します。

複数人に配布したい場合、Notify: Group Aliasesでグループ名を指定します。
グループはFabric上で編集します(後述)

2-2. Android

プロジェクトにFabricを導入済みの前提です。
Fabricの導入はここここなどをご参照ください。

2-2-1. Fabric Beta

iOSとは異なり便利なstepはありません。

:arrow_up: Uploading Distribution

Gradle Runner stepのGradle task to runで設定します。
gradle taskを指定する形になります。
gradletasktorun.png

指定可能なtaskは以下のコマンドで確認可能です。

./gradle tasks

Fabric Betaへのdistributionは、

./gradle assemble[Flavor]Debug crashlyticsUploadDistribution[Flavor]Debug

の形で行いますので、Gradle task to runでの指定は以下のようにになります。

assemble[Flavor]Debug crashlyticsUploadDistribution[Flavor]Debug

もしくは

assemble[Flavor]Release crashlyticsUploadDistribution[Flavor]Release

API KeyとBuild Secretの指定は、プロジェクトにapp/fabric.propertiesというファイルを追加してそこに記述します。
ただし、リポジトリで直接fabric.propertiesを管理するのは良くないらしいので、BITRISE上でファイルを生成します。

  1. Git Clone Repository から Gradle Runner の間に適当に Generate Text File というstepを追加します。

  2. ConfigのContent of the text fileにファイルの内容を記述します。
    ファイルの内容は以下です。

apiSecret=$FABRIC_API_SECRET
apiKey=$FABRIC_API_KEY
betaDistributionReleaseNotes=\"$BITRISE_GIT_MESSAGE\"
betaDistributionGroupAliasesFilePath=Fabric上で設定したグループのAlias

android_fabric.png

$FABRIC_API_SECRET$FABRIC_API_KEYは直接描いてもいいですが環境変数に定義します。

:pencil: Release Notes

betaDistributionReleaseNotesで指定します。
$BITRISE_GIT_MESSAGEは前述の通りです。

:bell: Notify

betaDistributionGroupAliasesbetaDistributionGroupAliasesFilePathで指定します。
例ではファイルの内容から取得しています。

3. Slackの特定のチャンネルにアプリの情報、FabricのリリースノートとURL、QRコードを通知する

3-1. SlackでWebhook URLを取得する

  1. SlackのIncoming WebHooksにアクセスする。
  2. "Post to Channel"で投稿先のチャンネルを選択する、もしくは新規作成。
  3. "Add Incoming WebHooks integration"ボタンを押下
  4. "Webhook URL"に表示されているURLを控える slack_webhook.png

参考:
SlackのWebhook URL取得手順

3-2. BITRISEでSlackのステップを追加する

3-2-1. Slackに投げるメッセージに含む情報を取得する

  1. IPA Infoステップを追加
    このステップを追加しておくと、アプリ名やファイルサイズ、バージョンなど規定の環境変数に格納してくれる
  2. Scriptステップを追加
    以下のようにSlackメッセージに含むための要素を生成しておく
// アプリのバージョンとビルド番号
buildNumber="$IOS_APP_VERSION_NAME ($IOS_APP_VERSION_NAME.$BITRISE_BUILD_NUMBER)"
// アプリ名
appName=$IOS_APP_NAME
// Bundle ID
bundleId=$IOS_IPA_PACKAGE_NAME
// 実行したworkflow ID
workflowId=$BITRISE_TRIGGERED_WORKFLOW_ID
// FabricのURL
url="https://apps-ios.crashlytics.com/projects/"
echo "$BITRISE_APP_TITLE $buildNumber $workflowId $url"
// workflow ID、アプリ名、ビルド番号、バンドルID、リリースノート、URLを連結してSlack用のメッセージにする
message="The workflow \"$workflowId\" was succeeded!\n$appName $buildNumber\n$bundleId\n$BITRISE_GIT_MESSAGE\n$url"

envman add --key SLACK_MESSAGE_BODY --value "$message"
envman add --key SLACK_MESSAGE_URL --value "$url"
echo "SLACK_MESSAGE_BODY is $SLACK_MESSAGE_BODY"
echo "SLACK_MESSAGE_URL is $SLACK_MESSAGE_URL"

それぞれ$SLACK_MESSAGE_BODY, $SLACK_MESSAGE_URLという環境変数に格納しておく

ipainfo.png

3-2-2. QRを生成するステップを追加

qrstep_icon.png
このステップの追加しておけば、MacのSlackで見ていてもiPhoneでQRを撮影すればすぐにアクセスできる。いちいちiOSのSlackで表示し直す必要がなくなる。

  1. Install page QR codeステップを追加する
  2. Input variables に以下の値を設定する
    Public Install Page URL : 3-2で生成した$SLACK_MESSAGE_URLを指定
    Public Install Page QR Code Image size : 適当なサイズを指定 qrstep_variabled.png

3-2-3. Slackに投稿するステップを追加する

sendslack_icon.png

  1. Send a Slack messageステップを追加する
  2. Input variables に以下の値を設定する
    Slack Webhook URL : 1-1で控えたURLを指定 Target Slack channel, group or username : 投稿先のSlackチャンネル名を指定 The message you want to send : 3-2で生成した$SLACK_MESSAGE_BODYを指定 Image URL : 3-2-2でoutputされる$BITRISE_PUBLIC_INSTALL_PAGE_QR_CODE_IMAGE_URLを指定 Emoji Icon : Slack側でBITRISEのアイコンを絵文字登録したものを指定しておいた send_slack_variables.png

次回は、リリースビルドの iTunes Connect へのDeployでコケた箇所 について纏めたいと思います。(時期未定:sweat_smile:


https://www.bitrise.io/

                              MMMMMMMMMMMM                                
                              MMMMddddNMMM                                
                              MMMM    mMMM                                
                              MMMMssssNMMM                                
                              MMMMMMMMMMMM                                
                                 sMMMMd                                   
                                 yMMMMd                                   
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMdhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhdMMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
     MMMMM                                                      MMMMMM    
  MMMMMMMM                                                      MMMMMMMM  
 MMM' MMMM           .yy.                        .yy.           MMM  'MMM 
MMMh  MMMM         .MMMMMMl.                  .lMMMMMMM.        MMM   hMMM
MMM   MMMM       .MMMMMmNMMMl.               .MMMMNmMMMM.       MMM    MMM
MMMs  MMMM       .hhhh   yhhh.               .hhhh   hhh+       MMM   sMMM
 MMM. MMMM                                                      MMM  .MMM 
  MMMNMMMM                                                      MMMMNMMM  
    MMMMMM                                                      MMMMMM    
      MMMM                                                      MMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM