
好奇心是学习的第一步
前言:
只因在人群中多看了你一眼,于是我决定深挖一下这个标签,一不小心边打开了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