持续集成不仅包含了Jenkins或者相关其它的CI工具,也包含了包含代码如何控制,采用的什么分支策略等。
不同的组织可能采用不同的类型的策略来完成CI,策略类型和项目的类型的有很大的关系。

一 分支策略

1.1 本实验分支

分支能够有效的对代码较好的管理,也是能够把工作的代码和开发环境的代码隔离的有效方式。主要有三种的分支策略类型
– master分支
– integration 分支
– feature 分支

1.master分支

master分支也叫做生产分支,该分支的代码全部是经过测试OK的代码。任何没有经过测试OK的代码都不会出现在该分支上。

2. Integration分支

集成分支也叫做mainline分支,该分支存放着所有功能的集成,并进行构建和测试。开发人员不能在该分支上直接开发,然而开发人员可以在集成分支上创建feaure分支,并在上面进行开发。

3. feature分支

最后是feature分支,这也是开发人员所在的分支,可以有多个feature分支。

下图展现了常用的分支策略。

在feature分支或者集成分支上进行构建、静态代码分析、集成测试等,假如代码测试通过,那么把打好的包上传到Artifactory(二进制库)

1.2 CI的管道

在Jenkins中创建多分支管道有以下步骤:
(1)从版本控制系统中拉取代码,并触发一个事件(CI管道的初始化)

(2)执行静态分析并把结果上传到SonarQube,假如发现的bug超过在quality gate的阀值,那么管道构建将会失败。

(3)执行集成测试和在Jenkins上公布单元测试报告。

(4)上传构建的artifacts,并附加一些相关的属性信息。

持续集成的目的就是把持续构建、测试(单元测试和集成测试),静态代码性能分析,和上传构建的artifacts到二进制库,这个过程是完全自动化的。 并且报告每一步是否成功或者失败。

1.3 持续集成工具集下面是持续集成的要用到的工具

Technology Characteristic
Java Primary programming language used for coding
Maven Build tool
Junit Unit testing and integration testing tools
Jenkins Continuous Integration tool
GitHub Version control system
SoanrQube Static code analysis tool
Artifactory Binary repository mananger

二 构建一个集成管道

创建执行集成管道,将会执行下面步骤:

  1. 在GitHub上创建源代码库
  2. 创建Jenkinsfile去描述构建、单元测试、静态代码分析、集成测试、和上分布到构建的二进制文件到Artifactory.
  3. 利用Docker去产生构建的agents去运行我们的持续集成管道。
  4. 在jenkins中创建多分支的管道。

2.1 node块

本实验依然使用master构建

node('master'){

}

并且将会在master的节点上执行以下步骤:

  • 执行构建
  • 执行单元测试并推送单元测试报告
  • 执行代码分析并把它的结果上传到SonarQube
  • 执行集成测试并把发布集成测试报告
  • 推送artifacts到Artifactory

2.2 获取源代码

从版本控制器中下载最新的源代码,代码如下

  1. stage(‘Poll’) {
  2. scm checkout
  3. }

2.3 管道代码去执行构建和单元测试

  1. sh mvn clean verify -DskipITs=true’;
  2. junit ‘**/target/surefire-reports/TEST-.xml
  3. archive target/.jar

-DskipITs=ture代表跳过集成测试仅执行构建和单元测试,junit ‘/target/surefire-reports/TEST-*.xml’ 命令是开启Jenkins去公布单元测试报告,/target/surefire-reports/TEST-*.xml’ 此处存放的是单元测试报告所存在的目录位置。

管道代码去执行静态代码分析

通过运行Maven的命令,就是一个简单的shell脚本去执行静态代码的分析,这是使用针对maven的SonarQube scanner工具来进行配置的。

sh ‘mvn clean verify sonar:sonar -Dsonar.projectName=example-project

-Dsonar.projectKey=example-project -Dsonar.projectVersion=$BUILD_NUMBER’;

-Dsonar.projectName=example-project 这是传送给SonarQube项目名称的一个选项,测试的所有结果将会显示在projectName=example-project下

相似的-Dsonar.projectKey=example-project,这个选项是针对Maven的SonarQube Sanner去确认projectkey=example-project

-Dsonar.projectVersion=$BUILD_NUMBER这个选项是指关联到Jenkins的构建分析的号码,并把它上传到SonarQube。$BUILD_NUMBER是针对构建序列的环境变量。

2.4 静态代码分析

  1. stage('Static Code Analysis'){
  2. sh 'mvn clean verify sonar:sonar -Dsonar.host.url=http://192.168.132.133:9000 -Dsonar.login=278c0c5ddadca63754f0fa9ce50ba99c20214fb5';
  3. }

管道代码去执行集成测试

-Dsurefire.skip=true是跳过单元测试,仅执行集成测试的junit ‘/target/failsafe-reports/TEST-*.xml’ 命令是开启jenkins去发布Junit unit 测试报告到Jenkins管道页面。/target/failsafe-reports/TEST-*.xml 这是产生的集成报告所在的目录。

集成测试阶段所包含的代码如下:

  1. stage (‘Integration Test’){
  2. sh mvn clean verify -Dsurefire.skip=true’;
  3. junit ‘**/target/failsafe-reports/TEST-*.xml
  4. archive target/*.jar’
  5. }

注意:针对单元测试和集成测试必须安装Jenkins Junit Plugin.

2.5  管道代码去发布构建的artifacts到Artifactory

去上传构建的artifacts到Artifactory,使用是File Specs。代码如下

  1. files”: [
  2. {
  3. pattern”: “[Mandatory]”,
  4. target”: “[Mandatory]”,
  5. props”: “[Optional]”,
  6. recursive”: “[Optional, Default: true’]”,
  7. flat : “[Optional, Default: true’]”,
  8. regexp”: “[Optional, Default: false’]”
  9. }
  10. ]

上面各参数的代码解释:

Parameters Condition Description
pattern [Mandatory] 指定应该上传到Artifactory的本地artifacts的的路径,可以通过反掩码或者正则表达式指定多个artifacts,假如使用正则表达式,需要使用\逃义保留的字符(比如.,?等,从版本2.9.0之后所有的路径分隔符均以/进行分隔,包含winows系统
target [Mandatory] 指定artifactory目录的路径,格式:[repository_name]/[repository_path],假如模式的如何是以/结尾,那么b就会被认为是目录。假如repo-name/a/b,那么上传的文件就会以b在artifactory命名,上传路径建议使用{1},{2},{3}…这样代替,具体参考(https://www.jfrog.com/confluence/display/RTF/Using+File+Specs#UsingFileSpecs-UsingPlaceholders).
Props [Optional] 是以Key=value的方式指定上传属性的值,如果有多个值,用,分隔。如 key1=value1;key2=value21,value22;key3=value3
flat [Default:true] 假如指定为true,那么上传的artifactory里面的源系统文件层级就会被忽略,设置为true,才会保留源系统的文件层级
recursive [Default:true] |如果为true,那么artifacts将会收集上传源目录的子目录,如果为faluse,仅会指定的源目录会被上传  
regexp [Default:false] 命令将会依据模式进行解释,就是正则表达式不会生效。如果为false,将会依正则表达式进行解释

下面是File Specs代码示例:

  1. def server = Artifactory.server 'Default Artifactory server'
  2. def uploadSpec = """{
  3. "files": [
  4. {
  5. "pattern": "target/hello-0.0.1.war",
  6. "target": "example-project/${BUILD_NUMBER}/",
  7. "props": "Integration-Tested=Yes;Performance-Tested=No"
  8. }
  9. ]
  10. }"""

下面是对代码的解释:

Parameters Description
def server = Artifactory.server ‘Default Artifactory Server’ This line tells Jenkins to use the existing Artifactory server configured in Jenkins. In our example, it is the default Artifactory server.
Default Artifactory Server This is the name of the Artifactory server configured inside Jenkins
“pattern”: “target/hello-0.0.1.war” This line of code will look at a file named hello-0.0.1.war inside the directory target, which is again inside the Jenkins workspace directory
“target”: “example-project/${BUILD_NUMBER}/”, This line of code will try to upload the build artifacts to the Artifactory repository named helloworld-greeting-project. It will place the inside a folder named after the build number inside the Artifactory repository.
${BUILD_NUMBER} The Jenkins environment variable for the build number.
“props”: “Integration-Tested=Yes;Performance-Testd=No” This code creates two key-value paris and assigns them to the uploaded artifacts. These key-value paris can be used as labels for code promotion in Artifactory

2.6 合并pipeline代码

  1. node('master') {
  2. stage('Poll') {
  3. checkout scm
  4. }
  5. stage('Build & Unit test'){
  6. sh 'mvn clean verify -DskipITs=true';
  7. junit '**/target/surefire-reports/TEST-*.xml'
  8. archive 'target/*.jar'
  9. }
  10. stage('Static Code Analysis'){
  11. sh 'mvn clean verify sonar:sonar -Dsonar.host.url=http://192.168.132.133:9000 -Dsonar.login=278c0c5ddadca63754f0fa9ce50ba99c20214fb5';
  12. }
  13. stage ('Integration Test'){
  14. sh 'mvn clean verify -Dsurefire.skip=true';
  15. junit '**/target/failsafe-reports/TEST-*.xml'
  16. archive 'target/*.jar'
  17. }
  18. stage ('Publish'){
  19. def server = Artifactory.server 'Default Artifactory server'
  20. def uploadSpec = """{
  21. "files": [
  22. {
  23. "pattern": "target/hello-0.0.1.war",
  24. "target": "example-project/${BUILD_NUMBER}/",
  25. "props": "Integration-Tested=Yes;Performance-Tested=No"
  26. }
  27. ]
  28. }"""
  29. server.upload(uploadSpec)
  30. }
  31. }

三 jenkins流水线任务

3.1 添加一个pipeline的任务

3.2 流水线配置

3.3 尝试构建

第一次构建失败

没有mvn命令,是因为master节点上,没有安装mvn工具,同时在jenkinsfile也没有使用参数调用mvn

直接安装一个mvn

3.4 再次构建

成功

3.5 查看sonar

3.7 查看artifcatory

构建的管道基本满足实验要求

3.8 查看日志

  1. Started by user darren ning
  2. Obtained Jenkinsfile from git http://192.168.132.132/root/hello-world-greeting.git
  3. Running in Durability level: MAX_SURVIVABILITY
  4. [Pipeline] Start of Pipeline
  5. [Pipeline] node
  6. Running on Jenkins in /root/.jenkins/workspace/pipelin-jenkinsfile
  7. [Pipeline] {
  8. [Pipeline] stage
  9. [Pipeline] { (Poll)
  10. [Pipeline] checkout
  11. using credential e3e48ed7-dbce--bb18-28e0c71ab962
  12. > git rev-parse --is-inside-work-tree # timeout=
  13. Fetching changes from the remote Git repository
  14. > git config remote.origin.url http://192.168.132.132/root/hello-world-greeting.git # timeout=10
  15. Fetching upstream changes from http://192.168.132.132/root/hello-world-greeting.git
  16. > git --version # timeout=
  17. using GIT_ASKPASS to set credentials
  18. > git fetch --tags --progress http://192.168.132.132/root/hello-world-greeting.git +refs/heads/*:refs/remotes/origin/*
  19. > git rev-parse refs/remotes/origin/master^{commit} # timeout=
  20. > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=
  21. Checking out Revision d8a642e6869e108fcada44e0dd2de7b5e882fe1d (refs/remotes/origin/master)
  22. > git config core.sparsecheckout # timeout=
  23. > git checkout -f d8a642e6869e108fcada44e0dd2de7b5e882fe1d
  24. Commit message: "Update Jenkinsfile"
  25. > git rev-list --no-walk d8a642e6869e108fcada44e0dd2de7b5e882fe1d # timeout=
  26. [Pipeline] }
  27. [Pipeline] // stage
  28. [Pipeline] stage
  29. [Pipeline] { (Build & Unit test)
  30. [Pipeline] sh
  31. + mvn clean verify -DskipITs=true
  32. [INFO] Scanning for projects...
  33. [INFO]
  34. [INFO] ------------------------------------------------------------------------
  35. [INFO] Building Hello Maven Webapp 0.0.
  36. [INFO] ------------------------------------------------------------------------
  37. 。。。。。。
  38. [INFO] Changes detected - recompiling the module!
  39. [INFO] Compiling source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/classes
  40. [INFO]
  41. [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ hello ---
  42. [debug] execute contextualize
  43. [INFO] Using 'UTF-8' encoding to copy filtered resources.
  44. [INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/test/resources
  45. [INFO]
  46. [INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello ---
  47. [INFO] Changes detected - recompiling the module!
  48. [INFO] Compiling source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/test-classes
  49. [INFO]
  50. [INFO] --- maven-surefire-plugin:2.19:test (default-test) @ hello ---
  51. 。。。。。。。
  52. -------------------------------------------------------
  53. T E S T S
  54. -------------------------------------------------------
  55. Running hello.DateTimeTest
  56.  
  57. Tests run: , Failures: , Errors: , Skipped: , Time elapsed: 0.014 sec - in hello.DateTimeTest
  58. Running hello.MessageTest
  59. Tests run: , Failures: , Errors: , Skipped: , Time elapsed: sec - in hello.MessageTest
  60.  
  61. Results :
  62.  
  63. Tests run: , Failures: , Errors: , Skipped:
  64.  
  65. [INFO]
  66. [INFO] --- maven-war-plugin:2.1.:war (default-war) @ hello ---
  67.  
  68. [INFO] Packaging webapp
  69. [INFO] Assembling webapp [hello] in [/root/.jenkins/workspace/pipelin-jenkinsfile/target/hello-0.0.]
  70. [INFO] Processing war project
  71. [INFO] Copying webapp resources [/root/.jenkins/workspace/pipelin-jenkinsfile/src/main/webapp]
  72. [INFO] Webapp assembled in [ msecs]
  73. [INFO] Building war: /root/.jenkins/workspace/pipelin-jenkinsfile/target/hello-0.0..war
  74. [INFO] WEB-INF/web.xml already added, skipping
  75. [INFO]
  76. [INFO] --- maven-failsafe-plugin:2.19:integration-test (default) @ hello ---
  77. [INFO] Tests are skipped.
  78. [INFO]
  79. [INFO] --- maven-failsafe-plugin:2.19:verify (default) @ hello ---
  80. [INFO] Tests are skipped.
  81. [INFO] ------------------------------------------------------------------------
  82. [INFO] BUILD SUCCESS
  83. [INFO] ------------------------------------------------------------------------
  84. [INFO] Total time: .640s
  85. [INFO] Finished at: Sun Oct :: EDT
  86. [INFO] Final Memory: 18M/159M
  87. [INFO] ------------------------------------------------------------------------
  88. [Pipeline] junit
  89. Recording test results
  90. [Pipeline] archive
  91. The archive step is deprecated, please use archiveArtifacts instead.
  92. No files found to archive for pattern "target/*.jar"; continuing.
  93. [Pipeline] }
  94. [Pipeline] // stage
  95. [Pipeline] stage
  96. [Pipeline] { (Static Code Analysis)
  97. [Pipeline] sh
  98. + mvn clean verify sonar:sonar -Dsonar.host.url=http://192.168.132.133:9000 -Dsonar.login=278c0c5ddadca63754f0fa9ce50ba99c20214fb5
  99. [INFO] Scanning for projects...、
  100. 。。。。。。
  101. [INFO]
  102. [INFO] ------------------------------------------------------------------------
  103. [INFO] Building Hello Maven Webapp 0.0.
  104. [INFO] ------------------------------------------------------------------------
  105. [INFO]
  106. [INFO] --- maven-clean-plugin:2.4.:clean (default-clean) @ hello ---
  107. [INFO] Deleting /root/.jenkins/workspace/pipelin-jenkinsfile/target
  108. [INFO]
  109. [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ hello ---
  110. [debug] execute contextualize
  111. [INFO] Using 'UTF-8' encoding to copy filtered resources.
  112. [INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/main/resources
  113. [INFO]
  114. [INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ hello ---
  115. [INFO] Changes detected - recompiling the module!
  116. [INFO] Compiling source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/classes
  117. [INFO]
  118. [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ hello ---
  119. [debug] execute contextualize
  120. [INFO] Using 'UTF-8' encoding to copy filtered resources.
  121. [INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/test/resources
  122. [INFO]
  123. [INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello ---
  124. [INFO] Changes detected - recompiling the module!
  125. [INFO] Compiling source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/test-classes
  126. [INFO]
  127. [INFO] --- maven-surefire-plugin:2.19:test (default-test) @ hello ---
  128. 。。。。。。。
  129. [INFO] User cache: /root/.sonar/cache
  130. [INFO] SonarQube version: 6.7.
  131. [INFO] Default locale: "en_US", source code encoding: "UTF-8"
  132. [INFO] Publish mode
  133. [INFO] Load global settings
  134. [INFO] Load global settings (done) | time=420ms
  135. [INFO] Server id: 8AB2C9A6-AWyV7Ii4gK-saCFcgAZW
  136. [INFO] User cache: /root/.sonar/cache
  137. [INFO] Load plugins index
  138. [INFO] Load plugins index (done) | time=123ms
  139. 。。。。。
  140. [INFO] BUILD SUCCESS
  141. [INFO] ------------------------------------------------------------------------
  142. [INFO] Total time: :.733s
  143. [INFO] Finished at: Sun Oct :: EDT
  144. [INFO] Final Memory: 34M/218M
  145. [INFO] ------------------------------------------------------------------------
  146. [Pipeline] }
  147. [Pipeline] // stage
  148. [Pipeline] stage
  149. [Pipeline] { (Integration Test)
  150. [Pipeline] sh
  151. + mvn clean verify -Dsurefire.skip=true
  152. [INFO] Scanning for projects...
  153. [INFO]
  154. [INFO] ------------------------------------------------------------------------
  155. [INFO] Building Hello Maven Webapp 0.0.
  156. 。。。。。。。
  157. [Pipeline] }
  158. [Pipeline] // stage
  159. [Pipeline] }
  160. [Pipeline] // node
  161. [Pipeline] End of Pipeline
  162. Finished: SUCCESS

参考:https://edu.csdn.net/course/play/9051/188016  臧雪园老师视频课程

DEVOPS技术实践_12:创建持续集成的管道的更多相关文章

  1. [持续交付实践] 开篇:持续集成&持续交付综述

    前言 随着微服务架构与容器虚拟化技术的发展,持续集成与持续交付的概念又重新回到了大家的视野,越来越多的公司开始使用持续集成的系统来解决频繁发布带来的质量问题:使用持续交付的工具来实现代码在不同环境上的 ...

  2. DEVOPS技术实践_13:使用Jenkins持续传送设计-CD基础

    1. 分支策略 持续集成中使用的分支策略包括以下三个: The master branch The integration branch The feature branch 而CD只在Integra ...

  3. 使用 Visual Studio Team Services 和 IIS 创建持续集成管道

    若要将应用程序开发的生成.测试和部署阶段自动化,可以使用持续集成和部署 (CI/CD) 管道. 本教程介绍如何在 Azure 中使用 Visual Studio Team Services 和 Win ...

  4. DEVOPS技术实践_05:sonar静态代码扫描

    一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...

  5. DEVOPS技术实践_09:Jenkins多分支管道

    简介 多分支的管道是在jenkins2.x中新增的功能 . 多分支管道允许你针对分布式的控制器的每个分支创建一个管道. 下图是对它的一个描述.使用jenkinsfile去创建多分支的管道,jenkin ...

  6. DEVOPS技术实践_07:Jenkins 管道工作

    一 简介 由于在公司构建很多工作,都是使用的maven工作构建的,这种构建方式很大缺点就是所有的工作都需要一步一步的配置,当项目较多,需求变动时,需要很大的精力去修改配置,很费劲 Pipeline即为 ...

  7. DEVOPS技术实践_11:Jenkins集成Sonar

    前言 前面已经有介绍sonar的安装,简单应用,下面在简答的研究一下sonar和jenkins集成的简单使用,对于sonar的安装不做介绍 一 sonar的简单介绍 持续检查避免了低质量的代码,比如S ...

  8. DEVOPS技术实践_06:sonar与Jenksin集成

    代码质量管理平台 一.checkout和打包功能 1.1 gitlab在新建一个文件 后续在写入内容 1.2 Jenkins新建一个任务 两个参数 1.3 流水线配置 copy仓库地址: http:/ ...

  9. DEVOPS技术实践_01:jenkins集成平台

    一.准备环境 准备三台机器 角色 IP地址 用户名 密码 jenkins-master   172.25.254.130    admin   meiyoumima gitlab 172.25.254 ...

随机推荐

  1. ModuleNotFoundError: No module named 'tools.nnwrap' pytorch 安装

    https://pytorch.org/get-started/locally/ pytorch 主页选择后安装

  2. Libev源码分析05:Libev中的绝对时间定时器

    Libev中的超时监视器ev_periodic,是绝对时间定时器,不同于ev_timer,它是基于日历时间的.比如如果指定一个ev_periodic在10秒之后触发(ev_now() + 10),然后 ...

  3. Jquery常用方法汇总(转)

    https://blog.csdn.net/lucky___star/article/details/87883888

  4. @noi.ac - 490@ game

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Q 和小 T 正在玩一种双人游戏.m 张木牌从左往右排成一排 ...

  5. jQuery仿迅雷图片轮换效果

    jQuery仿迅雷图片轮换效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  6. better-scroll在移动端绑定click事件失效

    在做一个列表的时候需要点击列表将列表信息输出,给<li>加个一个很简单的@click,可是没有反应. 原因是使用了better-scroll,默认它会阻止touch事件.所以在配置中需要加 ...

  7. [转]Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  8. springboot 2.1.6.RELEASE pom 第一行报错

    eclipse创建springboot 2.1.6.RELEASE  pom第一行报错 在pom.xml 文件的properties中加入maven jar插件的版本号 <maven-jar-p ...

  9. java StringBuffer 与 StringBuilder

    String是不可变类,一旦String对象被创建,包含在对象中的字符序列是不可变的,直到对象被销毁: StringBuffer 与 StringBuilder对象则是可变的! 举例说明这两个的好处: ...

  10. [转]WebApi 后端文件传输至远程服务器

    /* 功能说明:微信退款需要有数字证书,而我们公司是做小程序平台的,会帮商家自动退款,所以会要求商家把微信证书上传至我们服务器,以便 微信退款. 使用HttpPostedFile 接受前端上传的文件, ...