好奇心是學習的第一步
前言:
只因在人羣中多看了你一眼,於是我決定深挖一下這個標籤,一不小心邊打開了Android持續集成的大門,其實除了CircleCI大家也應該有聽過一個本地版本的Jenkins,Jenkins是筆者去年就嘗試使用過,因爲個人能力不足,最終放棄了。而CircleCI的配置得益於GitHub上開源案例,這個項目start並不多,而且筆者嘗試部署的時候幾經一些摸不着頭腦的問題,差點放棄了,最後也是因爲一些摸不着頭腦的變化突然又通過編譯了。不得不說想成功,需要持之以恆的毅力,和水到渠成是的一波運氣。
優勢
- 顧名思義,持續集成,減少發佈的最後5分鐘
- CircleCI 支持 GitHub 和 Bitbucket 帳號的登錄,授權登錄完成後,就可以添加 Projects 了,支持 GitHub 和 Bitbucket 的公有及私有倉庫
- 提供App外鏈下載地址
Android Studio 配置
目錄結構
AndroidStudio所需要存儲的文件就這麼多。
config.yml
項目下新建 your project\.circleci\config.yml
version: 2
jobs:
build:
working_directory: ~/code
docker:
- image: circleci/android:api-28-alpha
environment:
JVM_OPTS: -Xmx4G
steps:
- checkout
- run: echo "Build process is started 👯"
- run:
name: Create debug.keystore.jks
command: openssl aes-256-cbc -d -in "${debugKeyStore}.encrypted" -k $DEBUG_ENCRYPT_SECRET_KEY -md md5 >> $debugKeyStore
- run:
name: Create release.keystore.jks
command: openssl aes-256-cbc -d -in "${releaseKeyStore}.encrypted" -k $RELEASE_ENCRYPT_SECRET_KEY -md md5 >> $releaseKeyStore
- run:
name: Create keystore.properies
command: printf 'debugKeyAlias=%s\ndebugKeyPassword=%s\ndebugKeyStore=%s\ndebugStorePassword=%s\nreleaseKeyAlias=%s\nreleaseKeyPassword=%s\nreleaseKeyStore=%s\nreleaseStorePassword=%s' $debugKeyAlias $debugKeyPassword $debugKeyStore $debugStorePassword $releaseKeyAlias $releaseKeyPassword $releaseKeyStore $releaseStorePassword > keystore.properties
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Run Tests
command: ./gradlew lint test
- store_test_results:
path: app/build/test-results
destination: test-results/
- run:
name: Initial build
command: ./gradlew clean assembleRelease --no-daemon --stacktrace
- store_artifacts:
path: app/build/outputs/apk/
destination: apks/
- deploy:
name: "Deploy to Fabric 🎉🎉"
command: |
echo "Run gradle task to upload generated APK to Fabric"
相關命令行
//獲取 祕鑰 MUCH 是你自定義的
//2637652043830B52C4F3A7DE89671BAD9AD5C7B6731DC2B30A8263A6C64737AB 爲生成的祕鑰
openssl enc -aes-256-cbc -k MUCH -P -md sha1
//-e 加密 生成 encrypted加密文件 (放到前臺:AS)
openssl aes-256-cbc -e -in release.keystore.jks -out release.keystore.jks.encrypted -k 2637652043830B52C4F3A7DE89671BAD9AD5C7B6731DC2B30A8263A6C64737AB
// -d 解密 生成 jks (放到後臺:CircleCI)
openssl aes-256-cbc -d -in release.keystore.jks.encrypted -k 2637652043830B52C4F3A7DE89671BAD9AD5C7B6731DC2B30A8263A6C64737AB -md md5 >> release.keystore.jks
//同上
openssl aes-256-cbc -d -in debug.keystore.jks.encrypted -k 2637652043830B52C4F3A7DE89671BAD9AD5C7B6731DC2B30A8263A6C64737AB -md md5 >> debug.keystore.jks
//同上
openssl aes-256-cbc -e -in debug.keystore.jks -out debug.keystore.jks.encrypted -k 2637652043830B52C4F3A7DE89671BAD9AD5C7B6731DC2B30A8263A6C64737AB
- 我們需要加密保護我們的jks不被複制
- -md md5 兼容openssl 版本兼容的問題
參考:Is there a standard for OpenSSL-interoperable AES encryption?
keystore.properties
debugKeyAlias=Debug
debugKeyPassword=1234567
debugKeyStore=debug.keystore.jks
debugStorePassword=1234567
releaseKeyAlias=dae.rounder
releaseKeyPassword=dae.rounder
releaseKeyStore=release.keystore.jks
releaseStorePassword=dae.rounder
build.gradle
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
debug {
keyAlias keystoreProperties['debugKeyAlias']
keyPassword keystoreProperties['debugKeyPassword']
storeFile file(rootDir.getCanonicalPath() + '/' + keystoreProperties['debugKeyStore'])
storePassword keystoreProperties['debugStorePassword']
}
release {
keyAlias keystoreProperties['releaseKeyAlias']
keyPassword keystoreProperties['releaseKeyPassword']
storeFile file(rootDir.getCanonicalPath() + '/' + keystoreProperties['releaseKeyStore'])
storePassword keystoreProperties['releaseStorePassword']
}
}
buildTypes {
debug {
minifyEnabled false
signingConfig signingConfigs.debug
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
}
AS端配置基本就這些了
CircleCI 配置
配置
- 註冊賬號 目前只支持 Github和Bitbucket
- 添加項目,添加完成會自動編譯一次( 關於上傳和新建項目本篇不做討論)
- 添加變量,是keystore.properties中的參數,無需上傳
自動編譯
-
編譯進度查看
每一個步驟都對應config.yml一個command命令行 -
APP線上下載地址
-
編譯標籤
總結
能講的就這麼多,運氣好的幾分鐘搞定,運氣不好的話也不要氣餒,過段時間再看,學習本來就是循環往復的過程。
參考文章:
- https://github.com/farukcankaya/ciappsigningexample
- https://medium.com/@farukcankaya/android-automated-build-with-circle-ci-ded9c0a4d931
- https://github.com/farukcankaya/ciappsigningexample/tree/feature/encrypted-keystore
- https://stackoverflow.com/questions/39637388/encryption-decryption-doesnt-work-well-between-two-different-openssl-versions