使用 Jenkins 優化打包提測流程

涉及知識點

  • 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'
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章