什么是持续集成?
频繁的(一天多次)将代码集成到主干
优点
1、每完成一点更新就就集成到对应的分支,可以快速发现错误,定位错误也比较容易
2、如果不是经常集成,分支或者主干又在不断更新,会导致以后集成的难度变大,甚至难以集成
持续集成(CI)管理工具
以jenkins为例,首先是
jenkins搭建与使用配置
官方地址:https://www.jenkins.io/doc/
首先拉去jenkins
使用docker部署
docker volume create jenkins_wangtong
创建实例
docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -v jenkins_wangtong:/var/jenkins_home jenkins/jenkins:Its
获得初始管理密码
docker exec jenkins_wangtong cat /var/jenkins_home/secrets/initialAdminPassword
之后启动jenkins即可,windows本地直接输入http://localhost:8080/即可
Jenkins Job管理
可以修改系统配置
1、修改默认的Shell为bash
2、默认邮箱:邮箱地址与账户
3、默认地址:服务器域名
4、安全:设置安全制度
5、时区:时区修改
6、插件:设置代理、安装插件、更新插件
7、slave节点:添加slave节点
等等
一个job的组成部分
General:项目的描述信息等
源码管理:比如代码的地址等
构建触发器
构建环境
构建:执行哪些命令
构建后操作
节点管理
jenkins的任务可以分布在不同的节点上运行
节点上需要配置java运行时环境。java_version>1.5
jenkins运行的主机在逻辑上是master节点
首先在jenkins》Manage Node and Clouds》新建节点
随意填写一个节点名称
填写相关信息保存
权限控制
jenkins初始化过程中会先注册一个管理员用户
管理员用户再创建后续的一般用户,Manage Jenkins》Configure Global Security
注册用户的操作的权限控制1、由管理员来完成 2、用户自由注册
管理员可以从管理控制页面直接添加用户Manage jenkins》manager user
用户的权限控制是在授权策略里面
jenkins常用的插件
jenkins强大的原因之一就是插件众多,插件能帮助jenkins丰富自身原有功能
插件的安装方法:Manage Jenkins》Manage plugins
报警机制
一般指的是邮件报警
Jenkins可以根据配置的邮件模板格式发送结果邮件
通过Jenkins的参数定制自己的email模板,常用的参数key如下:
-$BUILD_STATUS ——构建结果
PROJECT_NAME ——构建脚本名称
BUILD_NUMBER ——构建脚本编号
JOB_DESCRIPTION ——构建项目描述
CAUSE ——脚本启动原因
BUILD_URL ——脚本构建详情URL地址
一般是先下载插件Email Extension,Email Extension Template,这两个插件的作用是帮助用户方便的设置格式化邮件
Jenkins配置管理员邮箱:
往下来可以看到邮件的配置信息
模板配置,在系统配置里面找到我们的插件Extended E-mail Notification
Default Subject——邮件标题
Default Recipients——默认接收人
Default Triggers——默认失败会发送邮件——这里可以设置报警规则,比如说成功和失败的时候都可以报警
一个简约的模板:
Subject
Jenkins运行提示:$BUILD_STATUS | 脚本名称:$PROJECT_NAME | 运行编号:$BUILD_NUMBERContent
Content
<hr/>(本邮件是程序自动下发,请勿回复!)<br/><hr/>
项目名称:$PROJECT_NAME<br/><br/>
项目描述:$JOB DESCRIPTION<br/><br/>
运行编号:$BUILD_NUMBER<br/><br/>
运行结果:$BUILD STATUS<br/><br/>
触发原因:$(CAUSE}<br/><br/>
构建日志地址:<a href=“${BUILD_URL}console” > ${BUILD_URL}console</a><br/><br/>
构建地址:<a href=“$BUILD_URL” > $BUILD_URL</a><br/><br/>
详情:${JELLY_SCRIPT,template=*html"}<br/><hr/>
最后我们还需要在job里面配置构建后发送邮件选择Editable Email Notification
可以在 Triggers里面配置成功和失败发送给哪些人
矩阵jobyu 父子job
Jenkins父子多任务运行
任务启动的触发条件:其他任务的运行结果,包括前驱任务成功条件下被触发,前驱任务失败的条件下被触发,前驱任务不稳定的条件下被触发;适用的场景:有先后次序关系的任务,比如部署环境任务》验收测试任务
举例:
新建第一个job
再新建第二个job,选择依赖其他job进行触发
Jenkins API接口
Jenkin是对外暴露的动作交互入口
主要是为外部程序提供入口,可以控制Jenkins
支持http协议
API接口支持用户名、密码认证
Jenkins API支持典型的功能有:运行job、查看任务状态、返回任务编号等等
1、远程调用Jenkins API启动任务
我们使用这个任务名进行调用
import requests
url = "http://hewangtong:hewangtong@localhost:8080/job/First_test/build"
ret = requests.post(url)
print(ret)
运行结果:
在这里的用户名密码添加方法:username:password@hostname:port
2、远程调用Jenkins API返回最新任务编号
import requests
url = "http://hewangtong:hewangtong@localhost:8080/job/First_test/lastBuild/buildNumber"
ret = requests.get(url)
print(ret.text)
运行结果:
实际最新的运行编号也是2
3、远程调用Jenkins API查询任务状态
import requests
import json
url = "http://hewangtong:hewangtong@localhost:8080/job/First_test/2/api/json"
ret = requests.get(url)
print(json.dumps(ret.json(), indent=2))
运行结果:
4、Jenkinsapi库
当然,我们也可以使用已有的Jenkinsapi库
pip install jenkinsapi
from jenkinsapi.jenkins import Jenkins
jk = Jenkins(url, username, password, useCrumb=True)
Jenkins Pipeline
Jenkins Pipeline一种高内聚低耦合的工具;只有Jenkins2.0以上才会有
一系列Jenkins插件将整个持续集成用解释性代码Jenkinsfile来描述
Jenkinsfile使用方法:1、Jenkins任务页面输入 2、源代码工程中编辑
1、Jenkins中创建一个pipeline任务
Definition中选择Pipeline Script
在Pipeline模块添加如下代码
pipeline{
agent any
stages{
stage(‘begin’){
steps{
echo “hello pipeline”
}
}
}
post {
always {
echo ‘say goodbye’
}
}
}
构建之后可以看到不同阶段的视图
2、Pipeline Script from SCM
Pipeline的代码也可以放入git源代码库进行管理,如下
Jenkinsfile语法
Jenkinsfile支持两种语法形式1、Declarative pipeline——2.5版本之后,结构化方式;2、Scripts pipeline——基于groovy的语法
1、Declarative pipeline
必须包含在一个pipeline块内,具体来说是 pipeline{}
基本的部分是“steps” steps告诉Jenkins要做什么
语句分类具体包含Section,Directives, Steps,赋值等等几大类
语句树
pipeline{
agent any //定义pipeline执行节点,必须出现的指令,any表示可以在任意agent上执行pipeline
environment { //环境变量
cc = "test"
}
stages{ //包含一个或者多个stage的序列,Pipeline的大部分工作在此执行;必须出现的指令,无参数,每一个pipeline代码区间必须只有一个stages
stage('begin'){ //包含在stages中,pipeline完成的所有实际工作都需要包含到stage中,必须出现的指令,无参数,需要定义stage的名字
steps{ //必须出现的指令,无参数,具体执行步骤,包含在stage代码区间中
echo "hello pipeline"
}
}
}
post {
always {
echo 'say goodbye'
}
}
}
agent none:pipeline将不分配全局agent,每个stage分配自己的agent
label:指定运行节点的label
node:自定义运行节点配置,可以指定label,指定customWorkspace
docker:控制目标节点上的docker运行相关内容
如:
pipeline{
agent{
node{
label "myslave"
customWorkspace "myWorkspace"
}
}
}
在之前出现的post中
post:定义Pipeline或stage运行结束时的操作
参数:
- 不是必须出现的指令
- always:无论Pipline运行的完成状态如何都会运行
- changed:只有当前Pipeline运行的状态与先前完成的Pipeline的状态不同时,才会运行
- failure:仅当当前Pipeline处于“失败”状态时才运行
- success:仅当当前Pipeline处于“成功”状态时才运行
- unstable:只有当前Pipeline具有不稳定状态才能运行
- aborted:只有当前Pipeline处于中止状态时才能运行
options:定义Pipeline的专有属性
参数 - 不是必须出现的指令
- buildDiscarder:保持构建的最大个数
- disableConcurrentBuilds:不允许并行执行pipeline任务
- timeout:Pipeline超时时间
- retry:失败后,重试整个Pipeline的次数
- timestamps:预定义由Pipeline生成的所有控制台输出时间
- skipStagesAfterUnstable:一旦构建状态进入了“Unstable”状态,就跳过此stage
options {
timeout(time: 30, unit:'SECONDS')
buildDiscarder(logRotator(numTokeepStr:'2'))
retry(5)
}
parameters:定义Pipeline的专有参数列表
参数
- 不是必须出现的指令
- 支持数据类型:booleanParam,choice,credentials,file,text,password,run,string
- 类似参数化构建的选项
parameters{
string(name:'PERSON', defaultValue:'Jenkins', description:'输入的文本参数'
}
Stages {
stage('Test Parameters'){
steps {
echo "Hello ${params. PERSON}"
}
}
}
trigger:定义了Pipeline自动化触发的方式
参数
- 不是必须出现的指令
- cron:接受一个cron风格的字符串来定义Pipeline触发的常规间隔
- pollSCM:接受一个cron风格的字符串来定义Jenkins检查SCM源更改的常规间隔;如果存在新的更改,则Pipeline将被重新触发
triggers{
pollSCM('H */4 * * 1-5')
}
2、Scripts Pipeline
基于groovy语法定制的一种DSL语言,灵活性更高、可扩展性更好、与Declarative pipeline程序构成方式有雷同之处,基本语句也有相似之处
语句树
stage('Build'){
node {
echo "build stage"
}
}
stage('Test') {
node('slvae'){
echo "run on slave"
try {
echo "this is try"
}catch (exc) {
echo "Somethingfailed, I'in the catch block"
}finally {
echo "Finally, I am in the finally block"
}
}
}
Blue Ocean应用
可以重新定义用户使用Jenkins的习惯;代码更加图形化、直观化;流程更加可视化
创建一个Pipeline script任务,利用parallel参数控制代码的并行运行
pipeline{
agent none
stages{
stage('并行执行的stage'){
parallel{
stage('stage2.1') {
agent{label "myslave"}
steps{
echo "并行任务1"
sleep 10
}
}
stage('stage2.2') {
agent{label "master"}
steps{
echo "并行任务2"
sleep 10
}
}
}
}
}