涉及知識點
- Jenkins
- Android Studio(Gradle)
- 蒲公英
Jenkins
我的理解,就是可以幫我們減少重複工作的一個流程化執行工具。詳見百度
安裝 Jenkins
我使用了最簡單方式,下載純的 war 文件,然後使用 java -jar jenkins.war 的方式執行
我用的 macOs 系統,至於爲什麼不使用 dmg 安裝的後面補充說明
配置 Jenkins
- 默認訪問:http://localhost:8080/ 就可以打開 Jenkins
- 解鎖:
cat ~/.jenkins/secrets/initialAdminPassword
輸入密碼,建議後續使用這個密碼登錄 admin 後修改 admin 密碼 - 安裝插件:可以在第一次解鎖配置後安裝,也可以後面用到再安裝
- Gradle Plugin
- Git plugin
- description setter plugin
在 插件管理->立即獲取 操作中你可能會遇到 ssl 握手失敗問題,有經驗的人看下錯誤的堆棧信息就知道是這個問題。Fix:“高級” 這個tab,把升級站點的 https 修改爲 http
創建 Jenkins 打包任務
- 名字隨意,選擇:構建一個自由風格的軟件項目
- general tab:我選擇了“參數化構建過程”,添加了兩個文本參數 verName,verCode,爲了以後可能會需要再不改變代碼的情況下打一個升級了版本名和版本號的新包
源碼管理,安裝了 Git plugin 後會出現 git 選項,填入你的遠程倉庫地址,構建的分支,私有庫還需要授權信息
在使用 dmg 安裝的前提下,在私有庫填入了正確的授權信息拉取時,可能會遇到 fetch stuck 的問題,你會看到很多以 # timeout=10 結尾的日誌,並且一直卡在 clone 上
解決方案:正如前面提到的,卸載 dmg 安裝的 Jenkins,然後使用 war 的。原因在https://groups.google.com/forum/#!topic/jenkinsci-users/L23XG2LLha0 已經有人解釋清楚了,結論就是 macOs 下的 user 不一致
構建觸發器,可以不選擇,只在自己需要構建的情況下使用:Build with Parameters 構建
- 構建,這裏我用到了 Gralde Plugin 和 蒲公英提供的 API。如下圖所示
- 提測我只構建了 Alpha 版本的包
- 寫了一個 shell,在 app/ 這個目錄下找到我構建的 apk,然後使用 curl 以 form 的形式通過 API 提到蒲公英以便給測試下載提測
- 注意:這裏截圖裏沒有的,要傳遞參數到 build.gradle 裏面處理必須在 Invoke Gradle script 這一欄的“高級”裏面勾選上 “Pass all job parameters as System properties”
- 最後,我定義了歸檔文件夾,以及使用了 description setter plugin,抽取了 curl 提交後返回的下載頁面短地址
build.gradle 代碼
apply plugin: 'com.android.application'
android {
def verName = System.getProperties().getProperty("verName")
def verCode = System.getProperties().getProperty("verCode")
def alphaVersionName = verName ? verName : alphaVerName
def alphaVersionCode = verCode ? verCode : alphaVerCode
println alphaVersionName
println alphaVersionCode
// 以上是我獲取到構建參數的代碼
compileSdkVersion 27
defaultConfig {
applicationId "xxxx"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField('String', 'HOST', '\"xxx\"')
manifestPlaceholders = [
GETUI_APP_ID : "xxx",
GETUI_APP_SECRET: "xxx",
GETUI_APP_KEY : "xxx",
UMENG_APP_KEY : "xxx",
UMENG_CHANNEL : "android"
]
}
signingConfigs {
release {
storeFile file('../xxx.jks')
storePassword bcStorePassword
keyAlias bcKeyAlias
keyPassword bcKeyPassword
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
ext.enableCrashlytics = false
signingConfig signingConfigs.release
}
}
dexOptions {
preDexLibraries true
maxProcessCount 8
javaMaxHeapSize '2g'
}
flavorDimensions("app")
productFlavors {
dev {
applicationIdSuffix '.dev'
versionName "2.0.6"
minSdkVersion 21
buildConfigField('String', 'HOST', '\"xxx\"')
manifestPlaceholders = [
GETUI_APP_ID : "xxx",
GETUI_APP_SECRET: "xxx",
GETUI_APP_KEY : "xxx",
UMENG_APP_KEY : "xxx",
]
}
alpha {
versionCode alphaVersionCode as Integer //注意這裏的處理
versionName alphaVersionName
buildConfigField('String', 'HOST', '\"test.xxx\"')
manifestPlaceholders = [
GETUI_APP_ID : "xxx",
GETUI_APP_SECRET: "xxx",
GETUI_APP_KEY : "xxx",
UMENG_APP_KEY : "xxx",
]
}
// xiaomi {}
// vivo {}
// c360 {}
// tencent {}
// baidu {}
// others {}
// fenx {}
// weixin{}
// huawei{}
}
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "xx-${variant.name}-${variant.versionCode}-${variant.versionName}.apk"
}
}
productFlavors.all { flavor ->
if (flavor.name != 'dev' && flavor.name != 'alpha') {
flavor.manifestPlaceholders = [UMENG_CHANNEL: name]
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:support-v4:27.0.2'
implementation 'com.android.support:design:27.0.2'
implementation 'com.android.support:cardview-v7:27.0.2'
implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.github.chrisbanes:PhotoView:1.3.1'
// test
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
// third part
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.getui:sdk:2.10.2.0'
implementation 'com.umeng.analytics:analytics:latest.integration'
implementation files('libs/SocialSDK_QQ_Simplify.jar')
// local lib
implementation project(path: ':swipeloadlayout')
implementation project(path: ':httplib')
implementation project(path: ':glide')
implementation project(path: ':chart')
implementation files('libs/SocialSDK_QQ_Simplify.jar')
implementation('cn.qqtheme.framework:WheelPicker:1.4.4') {
exclude group: 'com.android.support'
}
}