GitHub
iOS
Jenkins
DeployGate
Slack

iOSアプリをGitリモートへのプッシュからJenkinsでビルドをしてDeployGateにアップロードをしてSlackに結果を通知してみた!

More than 1 year has passed since last update.


はじめに

スマートテック・ベンチャーズ Advent Calendar 23日目担当の @nnsnodnb です。

今回は、ビルド動作を自動化しようというものです。

GitHubにプッシュ操作(masterなどにPRマージなども含む)・Jenkinsなどの設定をしてからの動作です。プッシュは手動でお願いします。


お品書き


  1. Jenkins設定

  2. DeployGateアカウント取得・設定

  3. Slack設定

  4. UltraHook設定

  5. GitHub HookにてJenkinsに通知

  6. GitHubにプッシュ

  7. JenkinsでiOSアプリをビルド・アーカイブ

  8. DeployGateにアップロード

  9. DeployGateから通知


環境


  • OSX 10.11.6

  • Xcode 8.x

  • Jenkins 2.36

  • Homebrew 1.1.4


Jenkins設定

HomebrewからJenkinsおじさんをインストールしていきます。


Homebrewインストール

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


Jenkinsおじさんインストール

$ brew install jenkins

$ jenkins

あとはちょっと他のMac環境が手元にないのでターミナル等の指示に従ってインストールしてくださればと思います。

CIの勉強始めにMacにJenkinsを導入

上記記事がとても詳しく書かれていると思います。

私の場合は、ちょっと前のJenkins環境がなぜか残っていてほげほげしてしまったので、 https://jenkins.io/ からダウンロードしてインストールしました。

http://127.0.0.1:8080 にアクセスしてJenkinsおじさんのセットアップ画面がでてきたらOKです。

プラグイン等は Install suggested plugins を選んでおけばOKです。


プラグインインストール

Jenkinsの管理 -> プラグインの管理 -> 利用可能

GitHub関連のプラグインをインストール

Xcodeのプラグインもあるんですが、ぶっちゃけ意味ワカンネ状態になってしまったので、今回はパスです。

Slack Notification Plugin は入れておきます。


ジョブの追加

Jenkinsトップ画面の 新規ジョブ作成


  1. ジョブの名前を入力

  2. フリースタイル・プロジェクトのビルド

  3. OK

スクリーンショット 2016-12-22 17.14.20.png

次はジョブの設定

今回はSampleとしてジョブを追加しました。

GitHub projectにチェックを入れてリポジトリのURLを入力

スクリーンショット 2016-12-22 17.16.56.png

ソースコード管理 まで選ぶ必要はあるかはわかりませんが、とりあえず

スクリーンショット 2016-12-22 17.18.48.png

プライベートリポジトリの場合は上記2つともで高度な設定や Credentials などの設定が必要になります。

ビルド・トリガ は今回はmasterにプッシュされたときのみにしておきます。

Build when a change is pushed to GitHub

スクリーンショット 2016-12-22 17.20.37.png

ビルド環境もチェック

スクリーンショット 2016-12-22 17.21.51.png

今回はビルドするのにシェルスクリプトを実行するのでとりあえずこんな感じDeployGateのAPIキーなどはあとで各自設定お願いします。

スクリーンショット 2016-12-22 17.26.51.png

cd ${WORKSPACE}

export DG_USER="username"
export DG_API_KEY="API_KEY"
sh jenkins_build.sh

ビルド後の処理は 成果物を保存 及び Slack Notifications を設定しておきます。

スクリーンショット 2016-12-22 17.29.04.png

とりあえずJenkins側の操作は一旦終わりです。

まだ行ったり来たりするのでJenkinsは落とさないようにしましょう


DeployGateアカウント取得・設定

https://deploygate.com/users/signup

ここからサインインしておきましょう!

https://deploygate.com/settings

に行って、下の方に API key があるのでコピーしておきます。

スクリーンショット_2016-12-22_17_32_27.png

先程のJenkinsでジョブを設定したときにビルドの設定をした画面を開きます。

シェルスクリプトっぽいやつを書いたところです。

あそこの DG_USERDG_API_KEY が埋められます。

DeployGateのユーザ名と先ほどコピーした API key を入力します。


Slack設定

チームは作ってある前提

スクリーンショット_2016-12-22_17_41_37.png

完全に個人使用のものですが、一応モザイク処理しています。ご了承ください。

スクリーンショット 2016-12-22 17.43.31.png

Jenkins CI を選びます。

Add Configuration を押すと諸々設定画面がでます。


  • Post Channelは各自のSlackのプロジェクトのチャンネル

Slack Notificationsプラグインはすでにさっき入れたのでStep3までスキップします。

Jenkins側で Jenkinsの管理 -> システムの設定 -> Global Slack Notifier Settings で指示に従ってToken等を入力

スクリーンショット_2016-12-22_17_47_39.png

一応 Test Connection をしておくといいかと思います。

スクリーンショット_2016-12-22_17_49_27.png

こんな感じに通知が飛んで来るはずです。


UltraHook設定

今回はローカルで操作しているMacのJenkinsでビルドするためGitHubから http://127.0.0.1:8080 へのHookなどは物理的にも無理ということで UltraHook というものを使用します。

http://www.ultrahook.com/

ユーザ登録をするとAPI KEYが発行されます。

スクリーンショット_2016-12-22_17_52_20.png

$ gem install ultrahook

$ ultrahook stripe 8080

ちなみに

curl http://stripe.hoge.ultrahook.com -X POST -d 'key=value'

みたいにすると確認ができます。

今回はJenkinsのデフォルトで使用している8080ポートにHookしたいので8080を選択しています。


GitHub HookにてJenkinsに通知

GitHubのリポジトリ設定画面 -> Integration & services -> Add service -> Jenkins (GitHub plugin) を選択

先程 UtlraHook コマンドを実行してきたときにでてきたURLを設定

スクリーンショット_2016-12-22_17_58_59.png


GitHubにプッシュ

masterに向けてプッシュしてみます。

スクリーンショット_2016-12-22_18_06_47.png

こんな感じにHookが来ていることがわかりました。

あとJenkins側も動作していることを確認しましょう!

リポジトリの構成によってはビルドは失敗しているかと思います。仕方ありません。説明していませんもの...

├── project

│   ├── project
│   ├── project.xcodeproj
│   ├── project.xcworkspace
│   ├── hogehoge
│   └── Pods
├── .gitignore
├── ProvisioningProfile.mobileprovision
└── jenkins_build.sh


JenkinsでiOSアプリをビルド・アーカイブ


DeployGateにアップロード

この2つに関しては一気に説明します。

説明というよりシェルスクリプトを置くだけですが...

#!/bin/sh

#### Set On Jenkins ###

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
WORKSPACE=`pwd`

SCHEME=project
CONFIGURATION=Debug # Debug, Release and so on

PROVISIONING_NAME=ProvisioningProfile
IPA_FILE_NAME=develop-adhoc.ipa
iOS_SDK=iphoneos

# Get the ProvisioningProfile UUID
echo "************** Get the ProvisioningProfile UUID ***************"
KEYCHAIN=${HOME}/Library/Keychains/login.keychain
security cms -D -k ${KEYCHAIN} -i ${PROVISIONING_NAME}.mobileprovision > mobileprovision
plutil -extract 'UUID' xml1 mobileprovision
MPNAME=`/usr/libexec/PlistBuddy -c "Print $UUID" mobileprovision`
rm mobileprovision

# Install ProvisioningProfile
cp ${PROVISIONING_NAME}.mobileprovision ${HOME}/Library/MobileDevice/Provisioning\ Profiles/${MPNAME}.mobileprovision
PROVISIONING_PATH=\"${HOME}/Library/MobileDevice/Provisioning\ Profiles/${MPNAME}.mobileprovision\"
echo $PROVISIONING_PATH

# Unlock keychain
echo "************** Unlock keychain ****************"
/usr/bin/security default-keychain -d user -s ${KEYCHAIN}
/usr/bin/security unlock-keychain -p user ${KEYCHAIN}
/usr/bin/security find-identity -p codesigning -v

# Build project
echo "************** Build project ****************"
BUILD_DIR=${WORKSPACE}/build
/usr/bin/xcodebuild -scheme ${SCHEME} -workspace ${WORKSPACE}/project/project.xcworkspace -sdk ${iOS_SDK} -configuration ${CONFIGURATION} clean build CODE_SIGN_IDENTITY="iPhone Developer" PROVISIONING_PROFILE=${MPNAME} CONFIGURATION_BUILD_DIR=${BUILD_DIR}

# Create ipa
echo "************** Create ipa file ****************"
IPA_FILE=${BUILD_DIR}/${IPA_FILE_NAME}
/usr/bin/xcrun -sdk ${iOS_SDK} PackageApplication -v ${BUILD_DIR}/${SCHEME}.app -o ${IPA_FILE} --embed ${PROVISIONING_PATH}

# Upload to DeployGate
echo "************** Upload ipa to DeployGate ****************"
NOTE="hoge"
MESSAGE=`git log --pretty=format:%x0a%s%x0a%b -1`

curl -F "token=${DG_API_KEY}" \
-F "message=${GIT_BRANCH}-${MESSAGE}" \
-F "distribution_key=${DG_DISTRIBUTION_KEY}" \
-F "release_note=${NOTE}" \
-F "file=@${IPA_FILE}" \
https://deploygate.com/api/users/${DG_USER}/apps

PROVISIONING_NAME はリポジトリに配置している名前の .mobileprovision を取り除いた名前を入力

あとはworkspaceなどのパスは各々変更


DeployGateから通知

アップロードが完了したらDeployGateのアプリ画面に移動して以下のような設定するところがあるので選択

スクリーンショット_2016-12-22_18_25_46.png

スクリーンショット 2016-12-22 18.26.37.png

設定自体は簡単なので特に説明はいらないかと思います。

スクリーンショット_2016-12-22_18_27_25.png

スクリーンショット_2016-12-22_18_27_33.png

上記画像のように通知が来るようになります。


最後に

GitHubに限らず他のGitサービスなどとも連携ができますが、一番てっとり早くて個人でも使える範囲での説明でした。

何か不備などがありましたらコメント等していただければ幸いです。

DeployGateへのアップロードなどで毎回作業を中断してちょっと不便だなぁって思ったりしている方に少しでも貢献できたらと思います。


明日は、 @Nick_paper さんのクリスマスっぽいお話です。