之前采用Jenkins的自由风格构建的项目,每个步骤流程都要通过不同的方式设置,并且构建过程中整体流程是不可见的,无法确认每个流程花费的时间,并且问题不方便定位问题。
Jenkins的Pipeline(流水线)可以让项目的发布整体流程可视化,明确执行的阶段,可以快速的定位问题。并且整个项目的生命周期可以通过一个Jenkinsfile文件管理,而且Jenkinsfile文件是可以放在项目中维护的。
所以Pipeline相对自由风格或者其他的项目风格更容易操作。
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 声明全局环境变量方便后面使用,key = 'value'形式,指定变量名=变量值信息
environment{
host = '192.168.2.211'
}
// 存放所有任务的合集
stages {
// 单个任务
stage('任务1:拉取git仓库代码') {
// 实现任务的具体流程
steps {
echo '拉取代码成功'
}
}
// 单个任务
stage('任务2:通过maven构建项目') {
// 实现任务的具体流程
steps {
echo '通过maven构建项目-SUCCESS'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
echo '通过sonarqube做代码质量检测-SUCCESS'
}
}
stage('任务4:通过docker制作自定义镜像') {
steps {
echo '通过docker制作自定义镜像-SUCCESS'
}
}
stage('任务5:将自定义镜像推送到harbor') {
steps {
echo '将自定义镜像推送到harbor-SUCCESS'
}
}
stage('任务6:通过publish over ssh通知目标服务器') {
steps {
echo '通过publish over ssh通知目标服务器-SUCCESS'
}
}
}
}
Ps:涉及到特定脚本,Jenkins给予了充足的提示,可以自动生成命令
在Jenkins上维护Groovy脚本成本过高,因此就衍生出了Jenkinsfile方式。Jenkinsfile方式需要将脚本内容编写到gitlab项目中的Jenkinsfile文件中,Jenkins每次构建都会自动从gitlab上拉取项目并且获取项目中Jenkinsfile文件对项目进行构建。
从这里开始就是把Jenkins的每一步流程转换成代码去执行。流程就是在Jenkins流水线语法中生成对应的代码,然后用代码把gitlab上Jenkinsfile文件中对应的内容替换掉,然后再在Jenkins上构建。
将*/main更改为标签${tag},表示引用配置中的Git参数tag,这里只是列出了修改拉取Git代码的部分,其余部分不修改,直接保存
pipeline {
agent any
environment{
host = '192.168.2.211'
}
stages {
stage('任务1:拉取git仓库代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
}
通过脚本执行mvn的构建命令 :
pipeline {
agent any
environment{
host = '192.168.2.211'
}
stages {
stage('任务1:拉取git仓库代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
stage('任务2:通过maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
}
}
一样是三步走,先自动生成代码,再修改gitlab上的Jenkinsfile文件,最后立即构建查看效果。
/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff
通过脚本执行sonar-scanner命令进行代码检测 :
pipeline {
agent any
environment{
host = '192.168.2.211'
}
stages {
stage('任务1:拉取git仓库代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
stage('任务2:通过maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff'
}
}
}
}
通过自定义镜像脚本构建自定义镜像 :
pipeline {
agent any
environment{
host = '192.168.2.211'
}
stages {
stage('任务1:拉取git仓库代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
stage('任务2:通过maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff'
}
}
stage('任务4:通过docker制作自定义镜像') {
steps {
sh '''mv ./target/*.jar ./
docker build -t ${JOB_NAME}:${tag} .'''
}
}
}
}
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 声明全局环境变量方便后面使用,key = 'value'形式,指定变量名=变量值信息
environment{
harborUser = 'admin'
harborPassword = 'Harbor12345'
harborAddress = '192.168.2.211:80'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
// 单个任务
stage('任务1:拉取git仓库代码') {
// 实现任务的具体流程
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
// 单个任务
stage('任务2:通过maven构建项目') {
// 实现任务的具体流程
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff'
}
}
stage('任务4:通过docker制作自定义镜像') {
steps {
sh '''mv ./target/*.jar ./
docker build -t ${JOB_NAME}:${tag} .'''
}
}
stage('任务5:将自定义镜像推送到harbor') {
steps {
sh '''docker login -u ${harborUser} -p ${harborPassword} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
}
}
deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $container_port $host_port
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 声明全局环境变量方便后面使用,key = 'value'形式,指定变量名=变量值信息
environment{
harborUser = 'admin'
harborPassword = 'Harbor12345'
harborAddress = '192.168.2.211:80'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
// 单个任务
stage('任务1:拉取git仓库代码') {
// 实现任务的具体流程
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
// 单个任务
stage('任务2:通过maven构建项目') {
// 实现任务的具体流程
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff'
}
}
stage('任务4:通过docker制作自定义镜像') {
steps {
sh '''mv ./target/*.jar ./
docker build -t ${JOB_NAME}:${tag} .'''
}
}
stage('任务5:将自定义镜像推送到harbor') {
steps {
sh '''docker login -u ${harborUser} -p ${harborPassword} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
stage('任务6:通过publish over ssh通知目标服务器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $container_port $host_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
Ps:由于采用变量,记得使用双引号
通过上述操作,Jenkins将从gitlab上拉取的代码打包、构建,做质量检测,再制作成自定义镜像推送到harbor仓库,再通知目标服务器从harbor仓库拉取镜像执行Groovy脚本文件,最后再由Jenkins通过钉钉或者企业微信通知项目组成员结果。
在程序部署成功后,可以通过钉钉的机器人及时向群众发送部署的最终结果通知
https://oapi.dingtalk.com/robot/send?access_token=6e0a83d43a65b925cf9ece0e242944f5de1c40fd04143e03dcb850557f378cde
Jenkinsfile文件内容 :
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 声明全局环境变量方便后面使用,key = 'value'形式,指定变量名=变量值信息
environment{
harborUser = 'admin'
harborPassword = 'Harbor12345'
harborAddress = '192.168.2.211:80'
harborRepo = 'repo'
}
// 存放所有任务的合集
stages {
// 单个任务
stage('任务1:拉取git仓库代码') {
// 实现任务的具体流程
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://192.168.2.210/root/test.git']]])
}
}
// 单个任务
stage('任务2:通过maven构建项目') {
// 实现任务的具体流程
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTest'
}
}
stage('任务3:通过sonarqube做代码质量检测') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=7e47cd48d08789e76ba106dd772f9bfaa15d46ff'
}
}
stage('任务4:通过docker制作自定义镜像') {
steps {
sh '''mv ./target/*.jar ./
docker build -t ${JOB_NAME}:${tag} .'''
}
}
stage('任务5:将自定义镜像推送到harbor') {
steps {
sh '''docker login -u ${harborUser} -p ${harborPassword} ${harborAddress}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
stage('任务6:通过publish over ssh通知目标服务器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $harborAddress $harborRepo $JOB_NAME $tag $container_port $host_port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post {
success {
dingtalk(
robot: 'Jenkins-DingDing',
type: 'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
failure{
dingtalk(
robot: 'Jenkins-DingDing',
type: 'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 失败构建:${JOB_NAME}项目!\n- 版本:${tag}\n- 持续时间:${currentBuild.durationString}\n- 任务:#${JOB_NAME}"]
)
}
}
}