目录
pipeline是什么
具体有什么用
pipeline语法
声明式语法
pipeline是什么
从某种抽象层次上讲,部署流水。是指从版本控制库到用户手中这一过程的自动化表现形,并且可以做到持续交付。
具体有什么用
人话就是,Pipeline可以做到从版本库下载代码,进行编译打包,发送至目标机器,并部署,整个流程就被称为Jenkins的Pipeline。
pipeline语法
分为两种:
- 脚本式语法
- 声明式语法(Jenkins社区推荐)
Jenkins团队在一开始实现Jenkinspipelin时,Groovy语言被选择作为基础来实现pipeline,所以写pipeline脚本时,就是在写Groovy,被称为脚本式语法。
pipeline插件从2.5版开始,同时支持了声明式语法,是一种更简单,更结构化的语法。
声明式语法
pipeline {
// 表示任何可以执行的节点均可
// agent any
agent{
// 通过Manage Jenkins -> Manage Nodes增加节点配置
// 指定由哪个节点机器执行这个pipeline
// master默认为安装Jenkins所在的机器
node{
label 'master'
customWorkspace '/home/jenkins/workspace/webflux/' //默认工作空间
}
}
tools {
// 检测maven-3.6.3,自动下载,并将其加入PATH变量中
// maven-3.6.3名称在全局工具配置里的Maven中指定
maven 'maven-3.6.3'
}
options {
// 重试次数
retry(4)
// 超时 HOURS MINUTES SECONDS
timeout(time: 10; unit: 'SECONDS')
// 保存最近历史构建记录的数量,只能在pipeline下使用
buildDiscarder(logRotator(numToKeepStr: '10'))
// 从版本库下去源码时检出到工作空间的根目录名称
checkoutToSubdirectory('subdir')
// 禁止当前pipeline同时多次执行
disableConcurrentBuilds()
}
parameters {
// booleanParam(name: 'booleanTest', description: '', defaultValue: true)
// password(name: 'passwordTest', description: '', defaultValue: 'passwordTest')
// text(name: 'textTest', description: '', defaultValue: '其中\n表示换行')
choice(name: 'publish_host', description: '发布节点', choices: '192.168.1.101\n192.168.1.102\n')
choice(name: 'branches_version', description: '发布版本', choices: '1.0.1\n1.0.2\n')
string(name: 'Mail_recipient', description: '通知邮件', defaultValue: '')
}
stages {
stage('回显阶段') {
steps {
echo "echo hello"
// 打印环境变量,sh执行shell命令
sh "printenv"
}
post {
always {
echo "回显阶段执行完成"
// 主动报错,终止当前pipeline
// error('模拟报错')
}
}
}
stage {
steps {
// 写Groovy代码需要在scropt中,否则报错
script {
def list = ['Java', 'C++']
for (int i = 0; i < list.size(); ++i) {
// 双引号才可以作插值${}
echo "开发语言: ${list[i]}"
}
}
}
}
stage {
steps {
script {
// Jenkins Pipeline内置步骤
// 切换目录
dir()
// 删除当前目录,无参步骤
deleteDir()
// 判断文件是否存在
fileExists('/tmp/a.jar')
// 是否Unix系统
isUnix()
// 当前目录
pwd()
// 写文件
writeFile file: './test', text: '要写入的文件内容', encoding: 'UTF-8'
// 读文件
readFile file: './test', encoding: 'UTF-8')
// 使用预定义工具(在全局工具配置中配置的工具)
def t = tool name: 'maven'
echo "${t}" // 打印maven路径
// 睡眠5秒
sleep time: '5', unit: 'SECONDS'
}
}
}
// 以下是工程只需交付流程实例
stage('代码下载') {
steps {
// 定位到./code目录下执行后面代码
dir('code'){
echo '代码下载'
// 可以在编辑pipeline时的下方点击Pipeline Syntax,接着
// 进入片段生成器,选择checkout: Check out from version control,进行生成
// 配置版本库使用到账号密码,需要添加凭证,凭证 -> 系统 -> 全局凭证 -> Add Credentials,选择Username with password
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'svn', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: '192.168.1.103/Branches/$branches_version/Src/yiling']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])
}
}
}
stage('编译打包') {
steps {
dir('code/yiling-server'){
echo '编译打包'
// 使用Maven编译
sh 'source /etc/profile && mvn clean package -Dmaven.test.skip=true -Dyiling-version=$branches_version'
// 打包成tar.gz文件
sh 'cd target/ && tar -czvf yiling-server.tar.gz yiling-server_lib yiling-server.jar conf/bex conf/mapper && cp yiling-server.tar.gz /opt/yiling-jar/yiling-server.$branches_version.tar.gz'
}
}
}
stage('发布到192.168.1.101环境') {
// 当publish_host是192.168.1.101时才执行steps
when { environment name: 'publish_host', value: '192.168.1.101' }
steps {
dir('code/yiling-server'){
echo '发布到192.168.1.101环境'
// 将资源包推送到目标机器的指定路径下
// 进入片段生成器,选择sshPublisher: Send build artifacts over SSH,进行生成。
// 需要配置ssh,通过Manage Jenkins -> Configure System -> Publish over SSH增加SSH Servers,配置主机ip、port为22,登录用户名和密码即可
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.1.101', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'E:\\yiling-jar\\yiling-server', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/yiling-server.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
stage('发布到192.168.1.102环境') {
when { environment name: 'publish_host', value: '192.168.1.102' }
steps {
dir('code/yiling-server'){
echo '发布到192.168.1.102环境'
sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.1.102', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh /opt/yiling-jar/yiling-server/deploy.sh', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/opt/yiling-jar/yiling-server', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/yiling-server.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
stage('192.168.1.101启动服务') {
when { environment name: 'publish_host', value: '192.168.1.101' }
agent{
// 表示这个steps在指定label的从节点执行
// 通过Manage Jenkins -> Manage Nodes增加从节点配置
// 并且需要保证从节点与主节点的连通性,需要把jenkins.jar拷贝至从节点,并运行指定命令
node{
label 'Node192.168.1.101'
}
}
steps {
// 切换目录,执行deploy.bat脚本
dir('E:\\yiling-jar\\yiling-server') {
withEnv(['JENKINS_NODE_COOKIE=dontkillme']) {
echo '启动服务'
bat "deploy.bat"
}
}
}
}
}
//构建后操作
post {
always {
echo "things always to run"
}
// 终止状态就执行
aborted {
echo "things to run only for when the pipeline is aborted"
}
success {
echo "things to run only for when the pipeline is Successful"
}
/*
// 与上次不同就执行
changed {
echo "与上次不同就执行"
}
*/
failure {
echo "things to run only for when the pipeline is Failed"
// 安装Email Extension插件
// 进入Manage Jenkins→Configure System→Extended E-mail Notificatio配置
emailext body: '$DEFAULT_CONTENT', subject: '$DEFAULT_SUBJECT', to: '$Mail_recipient'
// Extended E-mail Notification配置模板
/*
Default Subject:
$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
Maximum Attachment Size:
5
Default Content:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
offset="0">
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
本邮件由系统自动发出,无需回复!<br/>
各位同事,大家好,以下为${PROJECT_NAME }项目构建信息</br>
<td><font color="#CC0000">构建结果 - ${BUILD_STATUS}</font></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">构建信息</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}次构建</li>
<li>触发原因: ${CAUSE}</li>
<li>构建状态: ${BUILD_STATUS}</li>
<li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
详细提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/>
</td>
</tr>
</table>
</body>
</html>
Default Pre-send Script:
import hudson.model.*;
*/
}
}
}