Jenkins+Gradle实现Android自动化构建

hensen725 8年前
   <p>Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。目前大部分公司都在使用Jenkins来持续构建。</p>    <h2><strong>Jenkins下载与安装配置</strong></h2>    <h3><strong>Jenkins下载</strong></h3>    <p>安装Jenkins有两种方式:</p>    <p>第一种就是下载安装包直接安装,下载地址: <a href="/misc/goto?guid=4959720375370965309" rel="nofollow,noindex">http://mirrors.jenkins-ci.org</a></p>    <p>第二种就是下载war包,放到Tomcat中启动。war包下载地址: <a href="/misc/goto?guid=4959720375470508594" rel="nofollow,noindex">http://mirrors.jenkins-ci.org/war/,</a></p>    <p>或者 <a href="/misc/goto?guid=4959720375556007500" rel="nofollow,noindex">http://updates.jenkins-ci.org/download/war/</a></p>    <p>这里因为我电脑上面之前装了Tomcat,所以我使用直接下载war包的方式进行安装。</p>    <h3><strong>Jenkins安装</strong></h3>    <p>将下载的jenkins.war放到Tomcat下的webapps目录下,然后启动Tomcat。在浏览器中访问”Tomcat访问地址/jenkins”即可安装,因为我的Tomcat装在本机,并且端口为8080,所以访问 <a href="/misc/goto?guid=4959720375641944263" rel="nofollow,noindex">http://localhost:8080/jenkins/即可进行安装。</a></p>    <h3><strong>Jenkins配置</strong></h3>    <p>Jenkins安装之后可以进行用户的权限设置、插件的安装等配置。</p>    <p><strong>用户权限设置</strong></p>    <p>系统管理–>Configure Global Security</p>    <p>如下图所示,在此处可以添加、删除用户以及配置用户权限。</p>    <p><img src="https://simg.open-open.com/show/6e5993892d0095d8330a6b11cd8f9236.png"></p>    <p><strong>插件安装</strong></p>    <p>搭建Android自动化打包环境需要安装Gradle插件,如果使用Git还需要Git的插件,安装Jenkins时默认已经安装了这两个插件。如果没有安装可以进入“系统管理>管理插件”进行插件的安装。</p>    <p><img src="https://simg.open-open.com/show/aa40ac89b202e3a874d32b5f626a665c.jpg"></p>    <h2><strong>创建Jenkins任务</strong></h2>    <p>要想Jenkins能够帮我们自动构建项目,我们需要创建一个任务,并且配置这个任务要它帮我们执行什么操作,以及什么时候执行等。</p>    <p><img src="https://simg.open-open.com/show/6d3fe6f5314ab5367dccbc2667b5a21b.jpg"></p>    <p>如上图所示,点击“新建”按钮并且选择“构建一个自由风格的软件项目”,完了之后会进入到任务的配置界面,配置好之后任务会出现在如上图右边的任务列表中。</p>    <h3><strong>任务配置</strong></h3>    <p>创建一个任务之后,会自动跳转到任务的配置界面对该任务进行配置,大概包括如下配置:</p>    <p>源码管理</p>    <p><img src="https://simg.open-open.com/show/3b0423d286ecb0d7da4000ebccd92ded.jpg"> 构建项目,当然得有代码了。Jenkins支持使用版本控制工具来进行源码管理,比如Git或者SVN。这里我使用的是Git,项目使用的是我的github上面的一个多渠道打包的demo。在Repository URL中输入项目地址,点击Add按钮添加认证信息,然后选择构建的分支,我这里使用的是master分支。</p>    <p><strong>构建触发器</strong></p>    <p><img src="https://simg.open-open.com/show/17c2e4ea8cc43622e0835f7a27d157c5.jpg"></p>    <p>Jenkins支持上图所示的触发时机配置,如果都不选,则为手动构建,需要点击“立即构建”按钮才构建。</p>    <p>Build periodically:周期进行项目构建(它不关心源码是否发生变化);</p>    <p>Build when a change is pushed to GItHub:表示只要GitHub上面源码一更新即进行构件;</p>    <p>Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作。</p>    <p>Build periodically和Poll SCM都支持日程表的设置,这个与Spring框架中定时器的日程表配置类似,有5个参数:</p>    <p>第一个参数代表的是分钟 minute,取值 0~59;</p>    <p>第二个参数代表的是小时 hour,取值 0~23;</p>    <p>第三个参数代表的是天 day,取值 1~31;</p>    <p>第四个参数代表的是月 month,取值 1~12;</p>    <p>最后一个参数代表的是星期 week,取值 0~7,0 和 7 都是表示星期天。</p>    <p>如:</p>    <p>选择Build periodically并设置日程表为“0 4 <em> </em></p>    <p>”,则表示每天凌晨4点构建一次源码。</p>    <p>选择Poll SCM并设置日程表为“</p>    <p>/10 ”,则表示每10分钟检查一次源码变化,如果有更新才进行构建。</p>    <p><strong>构建工具</strong></p>    <p>因为现在Android项目默认都是使用Gradle来进行构建的,所以在构建中我选择的是Invoke Gradle script。当然你也可以选择其它的构建工具,比如Ant。</p>    <p>选择Invoke Gradle script之后可以选Invoke Gradle和Use Gradle Wrapper,选择Invoke Gradle就是调用本地安装配置好的Gradle,此时需要指定Gradle路径。为了方便所有开发者同意Gradle版本,一般都使用Gradle Wrapper。关于Gradle和Gradlew的区别可以看这篇文章 <a href="/misc/goto?guid=4959720375731045565" rel="nofollow,noindex">https://www.zybuluo.com/xtccc/note/275168。</a></p>    <p><img src="https://simg.open-open.com/show/459596ebbd95d6a2b7111cbb41e80246.jpg"></p>    <p>Tasks中填上需要执行的gradle的task。上面我填的clean assembleRelease,即执行gradlew clean assembleRelease。</p>    <p><strong>构建后的操作</strong></p>    <p>配置构建后的操作可以让Jenkins在构建完之后执行什么操作,比如邮件通知、构建其它项目等。</p>    <p><img src="https://simg.open-open.com/show/1bb121b20cd787a5fc413d495915515a.jpg"></p>    <p>这里我配置了Archive the artifacts,在“用于存档的文件”中填写需要存档的文件名,可以使用通配符。比如上面我配置了app/build/outputs/apk/v*.apk,表示疑v开头的apk文件都存档。构建完之后在任务首页可以下载存档的文件。</p>    <p>任务配置完成之后,点击任务首页的“立即构建”按钮,即可开始构建,构建过程首先会将源码下载下来,位于jenkins目录下的workspace中。然后执行配置好的gradle命令,如果使用gradlew,第一次应该会下载gradlew设置的版本的gradle,最后执行构建任务。构建完之后,如下图,可以看到存档的文件,点击即可下载。</p>    <p><img src="https://simg.open-open.com/show/8294f2e4915dc265060207e3f8af5b32.jpg"></p>    <h2><strong>附:Android工程build.gradle文件</strong></h2>    <pre>  <code class="language-groovy">apply plugin: 'com.android.application'    android {      compileSdkVersion 23      buildToolsVersion "23.0.2"        defaultConfig {          applicationId "com.lauren.multichanneldemo"          minSdkVersion 17          targetSdkVersion 23          versionCode 1          versionName "1.0"      }        signingConfigs {          release {              def liulingStoreFile = System.getenv("LIULING_STORE_FILE")              def liulingKeyAlias = System.getenv("LIULING_KEY_ALIAS")              def liulingKeyPassword = System.getenv("LIULING_KEY_PASSWORD")              def liulingStorePassword = System.getenv("LIULING_STORE_PASSWORD")              def isSigning = (liulingStoreFile != null) && (liulingKeyAlias != null) && (liulingKeyPassword != null) && (liulingStorePassword != null)              if(isSigning){                  storeFile file(liulingStoreFile)                  keyAlias liulingKeyAlias                  keyPassword liulingKeyPassword                  storePassword liulingStorePassword              } else {                  storeFile file("debug.keystore")                  keyAlias "AndroidDebugKey"                  keyPassword "android"                  storePassword "android"              }          }          debug {              storeFile file("debug.keystore")              keyAlias "AndroidDebugKey"              keyPassword "android"              storePassword "android"          }      }        buildTypes {          release {              // 不显示Log              buildConfigField "boolean", "LOG_DEBUG", "false"              //启用混淆代码的功能              minifyEnabled true              //压缩对齐生成的apk包              zipAlignEnabled true              //指定混淆规则,需要压缩优化的混淆要把proguard-android.txt换成proguard-android.txt              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'              shrinkResources true              signingConfig signingConfigs.release //打包命令行:gradlew assembleRelease          }            debug {              signingConfig signingConfigs.debug          }      }        lintOptions {          abortOnError false      }    // productFlavors {  // _91 {  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "91"]  // }  // wandoujia {  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "wandoujia"]  // }  // xiaomi {  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "xiaomi"]  // }  //  // _360shoufa{  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "360shoufa"]  // }  // anzhi{  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "anzhi"]  // }  // baidushoufa{  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "baidushoufa"]  // }  // huaweishoufa{  // manifestPlaceholders = [MTA_CHANNEL_VALUE: "huaweishoufa"]  // }  // }        // 如果嫌上面写法麻烦,也可以这样简写,加上一个批量处理即可.      productFlavors {          _91 {}          wandoujia {}          xiaomi {}          _360shoufa{}          anzhi{}          baidushoufa{}          huaweishoufa{}      }      //批量处理      productFlavors.all {          flavor ->              def channel = name.startsWith("_") ? name.substring(1) : name              flavor.manifestPlaceholders = [MTA_CHANNEL_VALUE: channel]      }        applicationVariants.all { variant ->          variant.outputs.each { output ->              def outputFile = output.outputFile              if (variant.buildType.name.equals('release')) {                  //可自定义自己想要生成的格式                  def channel = variant.productFlavors[0].name.startsWith("_") ? variant.productFlavors[0].name.substring(1) : variant.productFlavors[0].name                  def fileName = "v${defaultConfig.versionName}_${releaseTime()}_${channel}.apk"                  output.outputFile = new File(outputFile.parent, fileName)              }          }      }      apply from: 'productFlavors.gradle'    }    def releaseTime() {      return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))  }    dependencies {      compile fileTree(dir: 'libs', include: ['*.jar'])      testCompile 'junit:junit:4.12'      compile 'com.android.support:appcompat-v7:23.1.1'      compile 'com.android.support:design:23.1.1'  }  </code></pre>    <p> </p>    <p>来自:http://www.liuling123.com/2016/10/jenkins-gradle-auto-build.html</p>    <p> </p>