Travis CIでAndroidアプリをビルドしてDeployGateに置く
継続的インテグレーションをAndroidでもしたい!ということで、
- Travis CI - Free Hosted Continuous Integration Platform for the Open Source Community
- DeployGate - An incredibly easy way to deploy apps in development!
ここらへんを使い、
ということを実現したいと思います。
対象は、現在全リファクタリング中のこちら。
https://github.com/noboru-i/kyouen-android/tree/renew
.travis.yml の設定
language: android env: global: # deploygate - DEPLOYGATE_USER=noboru-i - secure: "SOev0rrhdJ6fp5CkJeQAh6mm6EmmWEWCVrSt7hn3mvjSbaz/yKdmiGsHp8NcTeLZrXuk6ay6mFee3TVqsT17Xn5+cGG5nnWFPqI2Os3AlSWdHkhLrv8f3KdfwJeTiBSymw4TDWSd/kVCB42q51BdnODda+GozCymA6qoZpf/GQs=" # secret_strings.xml - secure: "ZXnouETJ67n/DCjCFPdWoIm3eo0WsYhfuy9Y25IjYn6gij4F8v038bjYr+Z5QBsnLri1mU0QQeNy14cPaaYBoblTsmPm0cZ+Vv0wmYgAkVc2C+E67k/YUAD0puvUzUGsQ1z6N7gQ0tFjL4l4map/4iEkGtney6OYdyuljE75D2g=" - secure: "Sqi+dwZcd6qGpBLYUq+deqQBSX056N0eoQ9RfMjWB7gG/WfQn4XQaTF13jKdqp0MKzRj8P61uunoxZIpHNYNWeqzxfIpXKrzOdGv85r8PnbjDgH87N22ufqwPdbfAVydUEPP8hEEJ5vbCN2Fyoq1CHPNjwBpMIiD27LMVjiytn8=" - secure: "iUO0ldYPT3jYjoRafH0Milc3DNhgqzZQGk7tFkvg7WPF+YPEYDOMjwmhY0kTDjbxU+iqkHE7WOL66MtJSlvTJjNfs2uWqrXrmgMAXLusbRukscJmL2ZwGhNwBi4tOOl4V1FO8NRqYcdRkkHgJRUXyKAafLrdNePVm7uWUwjl2e0=" - secure: "PCeJAQ8/XrDWktlTbKtJLCcjhjOfsw/tcPPCrG1urvQMJrgzi6m6pTWo62RSpWVo1iYePiqvDgPGACrT082vtnoJ7TJ3FZEhty1xsDUhDBJ9qvmHEPpxLrtLGwZ1+doT/yxinQAqqucx8vsFJcTh8zOrGLknwEvqxhNj5HHKzkg=" - secure: "MyGGNdkyv+qEf8yhORcSzjsHbDjT2yILka/aMYgInt0oyF3T6O6JwwRvrXHEulPVHWsWu4LCxX8e3HeyyQ0OkIjc67nwIsajCDwDlVUcnkjqyV3r9xPn0HlltwvS63QuQGln6NQIUBk9nVIuaA+vno7bod1Px0VESu9kDgUiqgI=" notifications: email: false android: components: - build-tools-19.1.0 - android-19 - sysimg-19 - extra-android-support licenses: - android-sdk-license-5be876d5 - '.*intel.+' before_install: - android list sdk --no-ui --all --extended script: - ./gradlew uploadDeployGateDebug
env.globalには下記を記載しています。
作成については、下記のコマンドで。
travis encrypt GCM_SENDER_ID=9999999999999
これを、後述のgradle taskでxmlに書き込みます。
Projectのbuild.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.12.+' // deploygate classpath 'com.deploygate:gradle:0.6' } } allprojects { repositories { jcenter() } }
DeployGateのgradle pluginをここで設定しています。
アプリのbuild.gradle
apply plugin: 'com.android.application' apply plugin: 'deploygate' android { // Error:duplicate files during packaging of APK /XXX/app-debug-unaligned.apk 対策 packagingOptions { exclude 'META-INF/license.txt' exclude 'META-INF/notice.txt' } compileSdkVersion 19 buildToolsVersion "19.1.0" defaultConfig { applicationId "hm.orz.chaos114.android.tumekyouen" minSdkVersion 12 targetSdkVersion 19 versionCode 18 versionName "0.10.0" } buildTypes { release { runProguard false // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } lintOptions { abortOnError false } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:19.0.+' compile 'com.android.support:appcompat-v7:19.+' // deploygate compile 'com.deploygate:sdk:3.1' } apt { arguments { androidManifestFile variant.processResources.manifestFile resourcePackageName 'hm.orz.chaos114.android.tumekyouen' } } deploygate { userName = "$System.env.DEPLOYGATE_USER" token = "$System.env.DEPLOYGATE_TOKEN" apks { debug { sourceFile = file("${project.buildDir}/outputs/apk/app-debug-unaligned.apk") } } } uploadDeployGateDebug.dependsOn assembleDebug task secretKeyReplace { description 'Replace secret keys from system environment.' doLast { def filePath = "app/src/main/res/values/secret_strings.xml" def br = new BufferedReader(new FileReader(filePath)) def lines = br.readLines() br.close() // key情報の抽出 def secretKeys = new HashSet() def rExpression = /INPUT_YOUR_([A-Z_]+)/ for (String line : lines) { if (line.contains("INPUT_YOUR_")) { def matcher = (line =~ rExpression) secretKeys << matcher[0][1] } } // 文字列の置換 def newLines = new ArrayList<String>() for (String line : lines) { String newLine = line for (String key : secretKeys) { if (!System.getenv()[key]) { continue } newLine = newLine.replace("INPUT_YOUR_" + key, System.getenv()[key]) } newLines << newLine } def pw = new PrintWriter(new BufferedWriter(new FileWriter(filePath))) for (def line : newLines) { pw.println(line) } pw.close() } } preBuild.dependsOn secretKeyReplace
buildToolsVersion は、最新が20.0.0だけど、ymlに書いた android-sdk-license-5be876d5
がまだ対応してないようなので、19.1.0になってます。
deploygateタスクの設定(ユーザ名 / パスワード)は環境変数から取得しています。
環境変数への設定は.travis.ymlに書いてあります。
DEPLOYGATE_TOKEN も、暗号化して書いてあります。
secretKeyReplace taskで、secret_strings.xmlにある、"INPUT_YOUR_XXX"を取得、その"XXX"をキーとして環境変数を取得、replaceして同じファイルを置き換えます。
きっと、もっと良いやり方あると思うんだけど、ググっても出てこなかったので、力技です。
Publicリポジトリにキー情報は置けないけど、Travis CIでapkを作るときには必要。みんなどうやってるんだろう?
まとめ
というわけで、GitにPUSHするとDeployGateでアプリが配布されるところまで出来ました。
Publicリポジトリに置けない認証情報を設定する方法が、あんまりいけてないのはなんとかしたいところ。
あとは、テストコード書いて、リグレッションテストを回していきたいと思います。
Robolectricを使うつもりで書いてるので、まとまったらまた書こうと思います。