我们在成都有很多后端、前端和测试岗位正在招人,欢迎投递简历:。建议学习一下Jenkins。构建 Jenkins 的方式也有很多种,现在比较常用的是自由式软件项目。针对这种情况,我们采用Pipeline构建方法来解决。当然,如果项目集成了React Native,还需要构建JsBundle。Native修改后,JsBundle可能不会更新。如果在构建Native的时候一起构建JsBundle,会造成很大的资源浪费。本文就是分享一个使用Pipeline解决此类问题的经验。事实上,Jenkins 提供了一种更优雅的方式来管理 Pipeline 脚本。配置项目Pipeline时,选择Pipeline script from SCM,如下图:。这样,当Jenkins启动作业时,会先去仓库拉取脚本,然后运行脚本。
本文作者来自美团成都研发中心(是的,我们正在成都建设研发中心)。 我们在成都有很多后端、前端和测试岗位正在招人,欢迎投递简历:。
背景
在日常开发中,我们经常有发布需求,遇到各种环境,比如:线上环境(Online)、模拟环境(Staging)、开发环境(Dev)等,最简单的方法就是手动搭建并上传服务器,但是这个方法太麻烦了。 使用持续集成可以完美解决这个问题。 建议学习一下Jenkins。
构建 Jenkins 的方式也有很多种,现在比较常用的是自由式软件项目(一种构建 Jenkins 的方式,它结合了 SCM 和构建系统来构建你的项目,甚至可以构建软件以外的系统)。 对于单个项目的简单构建来说,这种方法已经足够了,但是对于多个相似且不同的项目,就很难满足要求了,否则需要大量的作业来支撑,这是存在的,一个小小的改动,就可以了当很多工作需要修改时,维护起来很困难。 我们的团队以前也遇到过这个问题。
目前我们团队主要负责开发和维护多个Android项目,每个项目都需要构建。 每个构建过程都非常相似,但也存在一定的差异。 例如,构建流程大致如下:
总体流程大致相同,但也存在一些差异。 例如,有些构建可能没有单元测试,有些构建不需要触发自动化测试,构建结果通知的负责人也不同。 在自由式软件项目的正常构建中,每个项目都会创建一个作业来处理该过程(可能调用其他作业)。
这种处理方式也是可以的,但是必须考虑到可能会有新的进程接入(比如二次签名),并且构建过程中可能会出现bug等各种问题。 无论哪种情况,一旦修改了主构建流程,每个项目的作业都需要修改和测试,势必会浪费大量时间。 针对这种情况,我们采用Pipeline构建方法来解决。
当然,如果项目集成了React Native,还需要构建JsBundle。 Native修改后,JsBundle可能不会更新。 如果在构建Native的时候一起构建JsBundle,会造成很大的资源浪费。 而且直接把JsBundle这样的大文件放到Native Git仓库中也不是特别合适。 本文就是分享一个使用Pipeline解决此类问题的经验。
管道简介
管道也是施工管道。 对于程序员来说,最好的解释是:用代码来控制项目的构建、测试、部署等。 使用它的好处有很多,包括但不限于:
舞台视图
s3Client = AmazonS3ClientProvider。 创建AmazonS3Conn();
uploadObject(args[0], args[1], args[2]);
公共静态无效 uploadObject(字符串输入文件,字符串存储桶名称,字符串对象名称){
尝试 {
文件 文件 = 新文件(inputFile);
if (!file.exists()) {
System.out.println("文件不存在:" + file.getPath());
返回;
s3Client.putObject(new PutObjectRequest(bucketName, objectName, file));
System.out.printf("成功上传%s到MSS:%s/v1/%s/%s/%se", inputFile, AmazonS3ClientProvider.url, TenantId, bucketName, objectName);
} catch (AmazonServiceException ase) {
System.out.println("捕获了一个 AmazonServiceException,其中 " +
“表示您的请求已实现” +
“发送至 Amazon S3,但因错误响应而被拒绝”+
“因为某些原因。”);
System.out.println("错误消息:" + ase.getMessage());
System.out.println("HTTP 状态代码:" + ase.getStatusCode());
System.out.println("AWS 错误代码:" + ase.getErrorCode());
System.out.println("错误类型:" + ase.getErrorType());
System.out.println("请求ID:" + ase.getRequestId());
} catch (AmazonClientException ace) {
System.out.println("捕获了一个 AmazonClientException,其中 " +
"表示客户端遇到" +
“尝试时出现内部错误” +
“与 S3 通信,”+
“例如无法访问网络。”);
System.out.println("错误消息:" + ace.getMessage());
我们直接在Pipeline中构建之后,就可以调用这个工具了。
当然,JsBundles也是分类型的,在调试过程中可能需要随时更新。 这些JsBundle不需要永久保存,一段时间后可以删除。 删除时参考MSS生命周期管理。 因此,我们在构建JsBundle的工作中添加一个参数来区分。
//根据TYPE,上传到不同的bucket
def Bucket =“rn-bundle-prod”
if ("${TYPE}" == "dev") {
bucket = "rn-bundle-dev" //具有生命周期管理,一段时间后会自动删除
echo "开始上传JsBundle到MSS"
//jar地址需要替换成自己的
sh“curl -s -S -L -o upload.jar”
sh "java -jar upload.jar ${archiveZip} ${bucket} ${PROJECT}/${targetZip}"
echo "上传 JsBundle 到 MSS:${archiveZip}"
Native构建时下载JsBundle
为了实现构建时的自动下载,我们编写了一个Gradle插件。
首先在build.gradle中配置JsBundle信息:
类路径 'com.zjiecode:rn-bundle-gradle-plugin:0.0.1'
将插件应用到所需的模块:
应用插件:'mt-rn-bundle-download'
在build.gradle中配置JsBundle信息:
RN下载配置 {
//远程文件目录,因为有多种类型,所以这里可以填写多种。
路径=[
'',
”
version = "1"//版本号,这里使用JsBundle的BUILD_NUMBER
fileName = 'xxxx.android.bundle-%s.zip' //远程文件的文件名,%s会填上面的版本
outFile = 'xxxx/src/main/assets/JsBundle/xxxx.android.bundle.zip' // 下载的存放路径,相对于项目根目录
插件会在打包的任务前面插入一个下载的任务,该任务会读取上述配置信息,并在打包阶段检查该版本的JsBundle是否已经存在。 如果不存在,就会去存档的JsBundle中,下载我们需要的JsBundle。 当然,这里的版本可以使用上面介绍的注入构建信息的方法,通过作业参数注入。 这样Jenkins在构建Native的时候就可以动态填写需要JsBundle的版本了。
我们已经把这个Gradle插件放到了github仓库中,大家可以在此基础上进行修改,当然也欢迎PR。 地址:
总结
我们将一个构建分为几个部分,好处如下:
当然,Pipeline也有一些缺点,比如:
当项目集成React Native和Pipeline时,我们可以将JsBundle构建产品上传到MSS存档。 构建Native时,可以动态下载。
关于作者
张杰,美团点评高级Android工程师,2017年加入餐饮平台成都研发中心,主要负责餐饮平台B端应用开发。
王浩,美团点评高级Android工程师,2017年加入餐饮平台成都研发中心,主要负责餐饮平台B端应用开发。
还没有评论,来说两句吧...