DEVOPS技术实践_12:创建持续集成的管道

持续集成不仅包含了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 获取源代码

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

stage(‘Poll’) {
scm checkout
}

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

sh ‘mvn clean verify -DskipITs=true’;
junit ‘**/target/surefire-reports/TEST-.xml’
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 静态代码分析

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

管道代码去执行集成测试

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

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

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

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

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

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

“files”: [
{
“pattern”: “[Mandatory]”,
“target”: “[Mandatory]”,
“props”: “[Optional]”,
“recursive”: “[Optional, Default: ‘true’]”,
“flat” : “[Optional, Default: ‘true’]”,
“regexp”: “[Optional, Default: ‘false’]”
}
]

上面各参数的代码解释:

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代码示例:

def server = Artifactory.server ‘Default Artifactory server‘
    def uploadSpec = """{
      "files": [
        {
          "pattern": "target/hello-0.0.1.war",
          "target": "example-project/${BUILD_NUMBER}/",
          "props": "Integration-Tested=Yes;Performance-Tested=No"
        }
      ]
    }"""

下面是对代码的解释:

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代码

node(‘master‘) {
  stage(‘Poll‘) {
    checkout scm
  }
  stage(‘Build & Unit test‘){
    sh ‘mvn clean verify -DskipITs=true‘;
    junit ‘**/target/surefire-reports/TEST-*.xml‘
    archive ‘target/*.jar‘
  }
  stage(‘Static Code Analysis‘){
    sh ‘mvn clean verify sonar:sonar -Dsonar.host.url=http://192.168.132.133:9000 -Dsonar.login=278c0c5ddadca63754f0fa9ce50ba99c20214fb5‘;
  }
  stage (‘Integration Test‘){
    sh ‘mvn clean verify -Dsurefire.skip=true‘;
    junit ‘**/target/failsafe-reports/TEST-*.xml‘
    archive ‘target/*.jar‘
  }
  stage (‘Publish‘){
    def server = Artifactory.server ‘Default Artifactory server‘
    def uploadSpec = """{
      "files": [
        {
          "pattern": "target/hello-0.0.1.war",
          "target": "example-project/${BUILD_NUMBER}/",
          "props": "Integration-Tested=Yes;Performance-Tested=No"
        }
      ]
    }"""
    server.upload(uploadSpec)
  }
}

三 jenkins流水线任务

3.1 添加一个pipeline的任务

3.2 流水线配置

3.3 尝试构建

第一次构建失败

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

直接安装一个mvn

3.4 再次构建

成功

3.5 查看sonar

3.7 查看artifcatory

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

3.8 查看日志

Started by user darren ning
Obtained Jenkinsfile from git http://192.168.132.132/root/hello-world-greeting.git
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /root/.jenkins/workspace/pipelin-jenkinsfile
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Poll)
[Pipeline] checkout
using credential e3e48ed7-dbce-4642-bb18-28e0c71ab962
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url http://192.168.132.132/root/hello-world-greeting.git # timeout=10
Fetching upstream changes from http://192.168.132.132/root/hello-world-greeting.git
 > git --version # timeout=10
using GIT_ASKPASS to set credentials
 > git fetch --tags --progress http://192.168.132.132/root/hello-world-greeting.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision d8a642e6869e108fcada44e0dd2de7b5e882fe1d (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f d8a642e6869e108fcada44e0dd2de7b5e882fe1d
Commit message: "Update Jenkinsfile"
 > git rev-list --no-walk d8a642e6869e108fcada44e0dd2de7b5e882fe1d # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Build & Unit test)
[Pipeline] sh
+ mvn clean verify -DskipITs=true
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Hello Maven Webapp 0.0.1
[INFO] ------------------------------------------------------------------------
。。。。。。
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ hello ---
[debug] execute contextualize
[INFO] Using ‘UTF-8‘ encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.19:test (default-test) @ hello ---
。。。。。。。
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running hello.DateTimeTest
3
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.014 sec - in hello.DateTimeTest
Running hello.MessageTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec - in hello.MessageTest

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-war-plugin:2.1.1:war (default-war) @ hello ---

[INFO] Packaging webapp
[INFO] Assembling webapp [hello] in [/root/.jenkins/workspace/pipelin-jenkinsfile/target/hello-0.0.1]
[INFO] Processing war project
[INFO] Copying webapp resources [/root/.jenkins/workspace/pipelin-jenkinsfile/src/main/webapp]
[INFO] Webapp assembled in [19 msecs]
[INFO] Building war: /root/.jenkins/workspace/pipelin-jenkinsfile/target/hello-0.0.1.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO]
[INFO] --- maven-failsafe-plugin:2.19:integration-test (default) @ hello ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-failsafe-plugin:2.19:verify (default) @ hello ---
[INFO] Tests are skipped.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 47.640s
[INFO] Finished at: Sun Oct 27 03:54:45 EDT 2019
[INFO] Final Memory: 18M/159M
[INFO] ------------------------------------------------------------------------
[Pipeline] junit
Recording test results
[Pipeline] archive
The archive step is deprecated, please use archiveArtifacts instead.
No files found to archive for pattern "target/*.jar"; continuing.
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Static Code Analysis)
[Pipeline] sh
+ mvn clean verify sonar:sonar -Dsonar.host.url=http://192.168.132.133:9000 -Dsonar.login=278c0c5ddadca63754f0fa9ce50ba99c20214fb5
[INFO] Scanning for projects...、
。。。。。。
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Hello Maven Webapp 0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ hello ---
[INFO] Deleting /root/.jenkins/workspace/pipelin-jenkinsfile/target
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ hello ---
[debug] execute contextualize
[INFO] Using ‘UTF-8‘ encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ hello ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ hello ---
[debug] execute contextualize
[INFO] Using ‘UTF-8‘ encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /root/.jenkins/workspace/pipelin-jenkinsfile/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to /root/.jenkins/workspace/pipelin-jenkinsfile/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.19:test (default-test) @ hello ---
。。。。。。。
[INFO] User cache: /root/.sonar/cache
[INFO] SonarQube version: 6.7.7
[INFO] Default locale: "en_US", source code encoding: "UTF-8"
[INFO] Publish mode
[INFO] Load global settings
[INFO] Load global settings (done) | time=420ms
[INFO] Server id: 8AB2C9A6-AWyV7Ii4gK-saCFcgAZW
[INFO] User cache: /root/.sonar/cache
[INFO] Load plugins index
[INFO] Load plugins index (done) | time=123ms
。。。。。
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:11.733s
[INFO] Finished at: Sun Oct 27 03:55:58 EDT 2019
[INFO] Final Memory: 34M/218M
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Integration Test)
[Pipeline] sh
+ mvn clean verify -Dsurefire.skip=true
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Hello Maven Webapp 0.0.1
。。。。。。。
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

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

原文地址:https://www.cnblogs.com/zyxnhr/p/11782703.html

时间: 2024-08-01 11:22:20

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

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

1. 分支策略 持续集成中使用的分支策略包括以下三个: The master branch The integration branch The feature branch 而CD只在Integration的release上分支上执行即可. 2. Release 分支 一些团队采用发布分支的策略.release分支是在所有代码在生产环境中经过验证之后创建的.也就是从master上面拉取的.创建release分支的目的就是在相应的版本上进行bug修复. 3. CD 管道 在此处,不会再创建新的p

DEVOPS技术实践_08:Jenkins多分支管道

简介 多分支的管道是在jenkins2.x中新增的功能 . 多分支管道允许你针对分布式的控制器的每个分支创建一个管道. 下图是对它的一个描述.使用jenkinsfile去创建多分支的管道,jenkinsfile可以存放在代码仓库中. Jenkinsfile只是定义CI管道的一个脚本. 另外,多分支管道的设计初衷就是当Git仓库中的代码改变时,去自动触发构建.下图是对它的一个描述. 一. 准备工作 (1)在[全局工具配置]中Maven工具已经配置好.(2)安装了[Pipeline Maven In

DEVOPS技术实践_11:Jenkins集成Sonar

前言 前面已经有介绍sonar的安装,简单应用,下面在简答的研究一下sonar和jenkins集成的简单使用,对于sonar的安装不做介绍 一 sonar的简单介绍 持续检查避免了低质量的代码,比如SonarQube工具就能够帮助我们完成此项.每次代码提交后,在代码上就会执行代码分析. 分析是基于代码分析工具中定义的一些规则,如果代码通过了错误阀值,那么它会允许到生命周期的下一步,如果超过了设定的阀值,那么直接返回错误. SonarQube是代码质量管理工具,允许团队去管理,追踪和改善他们的源代

DEVOPS技术实践_08:声明式管道语法

简介 前面简单的做了管道的实验,看了一下的它的效果 声明式管道是Groovy语法中的一个更简单和结构化的语法.下面主要学习明式管道语法. 一 声明式管道的基本结构 以上节的代码为例 node { def mvnHome stage('Preparation') { // for display purposes // Get some code from a GitHub repository git 'https://github.com/jglick/simple-maven-project

DEVOPS技术实践_10:安装部署Artifactory

需要一种机制去存储所有的二进制代码(build,packages,third-party plugins等)到类似于版本控制系统的系统. 像Git,SVN存储代码,它们存储的往往是源代码,不是二进制文件.Artifactory或者Nexus就是和Jenkins紧密集成的二进制文件存储库系统. 可以带来以下好处:追踪构建(谁触发?谁构建)依赖关系部署历史 jfrog artifactory是一款二进制存储管理工具,用来管理构建工具(如:maven.gradle)等所依赖的二进制仓库,以方便管理第三

持续集成与Devops关系

什么是持续集成 持续集成(Continuous Integration,简称CI),是一种软件开发实践,在实践中指只要代码有变更,就自动运行构建和测试,反馈运行结果.通俗一点来讲,就是绑定项目的代码仓库,SVN或者Git库,自动抓取新的代码,完成构建,甚至执行测试,部署到服务器. 持续集成的好处: 能够快速暴露错误. 保证代码提交质量. 定位错误更加容易. 降低整体集成风险. 促进产品快速迭代. 持续集成的特点: 统一的代码库 自动构建/测试 每个人每天都要向代码库主干提交代码 每次代码递交后都

持续集成与持续部署宝典Part 3:创建集成环境

通过前两篇文章<持续集成与持续部署宝典Part 1:将构建环境容器化>和<持续集成与持续部署宝典Part 2:创建持续集成流水线>,我们使用Docker创建了一个集中管理的构建环境,它可以应用到任意数量的机器上.接着,我们将环境设置到了Jenkins CI上,自动化处理了源代码的持续构建.打包和测试.在本章中,我们将进一步对流水线进行研究(如下所示),了解如何将项目持续部署到一个长时间运行的测试环境中.除了自动验收测试外,它还将允许人工测试代码.有了这样的环境,你就可以在产品投入生

研发协同平台持续集成之Jenkins实践

导读 研发协同平台有两个核心目标,一是提高研发效率 ,二是提高研发质量,要实现这两个核心目标,实现持续集成是关键之一. 什么是持续集成 在<持续集成>一书中,对持续集成的定义如下:持续集成是一种软件开发实践.在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以多次.每次集成会经过自动构建(包括自动测试)的检验,以尽快发现集成错误.自从在团队中引入这样的实践之后,Martin Fowler发现这种方法可以显著减少集成引起的问题,并可以加快团队合作软件开发的速度. 1.集

持续集成方案

大纲 构建 版本控制 部署 单元测试 架构文档化 命名约定 数据库伸缩性 自动化 反馈 实践 引言: 持续集成的前身: 在使用持续集成之前,很多开发团队都是用每日构建(nightly build).当时,微软使用这个实践很多年了.谁破坏了构建,就要负责监视后续的构建构成,直至发现下一个破坏了构建的人. 为什么要使用持续集成? 对于大多数项目来说,采纳持续集成实践是向高效率和高质量迈进的一大步.它保证那些创建大型复杂系统的团队具有高度的自信心和控制力.一旦代码提交引入了问题,持续集成就能为我们提供