Jenkins 配置gitlab的 pipeline流水线任务

配置jenkins到gitlab仓库权限

1,jenkins拉取代码的3种方式

需要拉取gitlab仓库的权限。这里有三种方法,按环境自己选择。

  • 1, 在gitlab创建专属Jenkins的账号密码。最简单,但是不怎么安全。
  • 2,配置 Jenkins 的 SSH 公钥到 GitLab。主要用于 git 命令拉取 git@gitlab.com:... 仓库。安全
  • 3, 配置 GitLab Personal Access Token(PAT)到 Jenkins。HTTPS 访问 GitLab API。

在jenkins只拉取仓库的话,推荐第二种。安全,没有时间限制,不暴露其他信息。

注意这种方式,拉取代码仓库,只能用git用户 命令拉取git仓库名,如:git@198.19.249.92:project-1/xxl-job.git。

2,配置SSH密钥公钥

Jenkins >>. 系统管理 >> 凭证管理 >> 全局 >> add credentials

gitlab ssh key添加jenkins对应的公钥即可。

jenkins 全局工具配置

java项目,主要两个工具,jdk和maven。

1,JDK

jdk可以下载指定版本放在服务器,解压后,指定文件夹即可。

也可以选择自动安装,触发java命令就会自动安装。

2,maven

maven也可以下载配置,会自动安装。

小坑,创建 自由项目,并不会自动安装。maven任务 和pipline任务,测试可以自动安装。

流水线pipeline任务

这里以xxl job 项目测试,这个也是java项目,可以练练手。先将源码上传至gitlab仓库。

项目地址:https://github.com/xuxueli/xxl-job/

1,Pipeline script 基础语法

流水线,只需要这一个文件即可,相当于界面配置换成命令配置。

基础语法

|-------------------------------------------------------------------------------------------------------------------------------------|
| pipeline { ``agent any ``stages { ``stage(``'Hello'``) { ``steps { ``echo 'Hello World' ``} ``} ``} } |

pipeline 定义一个流水线脚本

agent 指示 Jenkins 为整个流水线分配一个执行器(在 Jenkins 环境中的任何可用代理/节点上)和工作区。

stages 全部的工作都在这里执行

stage 每个工作开始

steps jenkinsfile 声明式脚本往这里面写

echo 写一个简单的字符串到控制台输出。

默认提供了示例,可自行参考。"流水线语法" 可以自动生成命令。如下,自动生成了,拉取代码仓库命令。

2,xxl job 构建部署的pipeline文件

四个步骤,拉取代码 >> 构建 >> 复制拷贝 >> 远程运行。

environment 环境参数,主要是服务器相关信息。jar包位置根据安装的方式可能有所不一样,注意一下。

tools 需要用到的工具,配置好了会自动调用或安装。

拉取代码 :git拉取

构建命令: mvn clean package -Dmaven.test.skip=true

拷贝: rsync命令拷贝

运行:远程运行服务器的start.sh脚本启动服务。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| pipeline { ``agent any ``environment { ``APP_NAME = ``'xxl-job-admin' ``BUILD_NAME = ``'xxl_job_pip' ``REMOTE_IP_LIST = ``'198.19.249.107' //``支持多个IP集群 ``PORT = ``'8080' ``REMOTE_DIR = ``"/app/${APP_NAME}" ``JAR_PATTERN = ``"${JENKINS_HOME}/workspace/${BUILD_NAME}/${APP_NAME}/target/${APP_NAME}-*.jar" ``} ``tools { ``maven ``"maven-3.9.6" ``jdk ``'jdk17' ``} ``stages { ``stage(``'gitlab代码拉取'``) { ``steps { ``git branch: ``'dev'``, credentialsId: ``'25238080-093d-4e3c-884c-f70a027eb1c9'``, url: ``'git@198.19.249.92:project-1/xxl-job.git' ``echo '拉取dev分支成功' ``} ``} ``stage(``'mvn执行构建'``) { ``steps { ``sh ``"mvn -v" ``sh ``"java --version" ``sh ``"mvn clean package -Dmaven.test.skip=true" ``echo "构建完成" ``} ``} ``stage(``'拷贝 JAR 到远程服务器'``) { ``steps { ``script { ``def jarFile = sh(script: ``"ls ${JAR_PATTERN} 2>/dev/null | head -n 1"``, returnStdout: ``true``).trim() ``if (!jarFile) { ``error(``"未找到 JAR 包: ${JAR_PATTERN}"``) ``} ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 拷贝到远程 IP: ${ip}" ``// 检查并创建目录 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'mkdir -p ${REMOTE_DIR} /app/logs /app/shell' ``""``" ``// 拷贝 jar 包 ``sh ``""``" ``rsync -az ${jarFile} root@${ip}:${REMOTE_DIR}/ ``""``" ``} ``echo "拷贝完成" ``} ``} ``} ``stage(``'远程部署服务'``) { ``steps { ``script { ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 部署到远程 IP: ${ip}" ``// 生成并执行远程启动命令 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'/bin/bash /app/shell/start.sh ${APP_NAME} ${PORT}' ``""``" ``} ``} ``echo "服务部署完成" ``} ``} ``} } |

流水线编写完成后,并不能马上构建,需要Approve script,同意脚本后才能生效,相当于多了个审核步骤。

3,构建pipeline

构建完成后,可以在Pipeline看到每个步骤命令,从而更精确的排查问题。

构建完成,也可以选择其中一个步骤重新运行,更加灵活

扩展

1,参数化选择部署模式

虽然pipeline流水构建完成后,可以选择其中一个步骤重新执行。但是如果想简单点,构建的时候就选择,比较方便。就用到参数化选择。

需求:可以把 DEPLOY_MODE 扩展为 3 种模式:

  • build_and_deploy:构建 + 拷贝 + 部署(完整流程)
  • only_deploy:仅拷贝 + 部署(跳过构建)
  • only_build:仅构建(不部署)

修改后流程如下(以xxl job演示为例) :

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| pipeline { ``agent any ``parameters { ``choice( ``name: ``'DEPLOY_MODE'``, ``choices: [``'build_and_deploy'``, ``'only_deploy'``, ``'only_build'``], ``description: ``'选择执行模式' ``) ``} ``environment { ``APP_NAME = ``'xxl-job-admin' ``BUILD_NAME = ``'xxl_job_pip' ``REMOTE_IP_LIST = ``'198.19.249.107' ``PORT = ``'8080' ``REMOTE_DIR = ``"/app/${APP_NAME}" ``JAR_PATTERN = ``"${JENKINS_HOME}/workspace/${BUILD_NAME}/${APP_NAME}/target/${APP_NAME}-*.jar" ``} ``tools { ``maven ``"maven-3.9.6" ``jdk ``'jdk17' ``} ``stages { ``stage(``'gitlab代码拉取'``) { ``when { ``expression { params.DEPLOY_MODE != ``'only_deploy' } ``} ``steps { ``git branch: ``'dev'``, credentialsId: ``'25238080-093d-4e3c-884c-f70a027eb1c9'``, url: ``'git@198.19.249.92:project-1/xxl-job.git' ``echo '拉取dev分支成功' ``} ``} ``stage(``'mvn执行构建'``) { ``when { ``expression { params.DEPLOY_MODE != ``'only_deploy' } ``} ``steps { ``sh ``"mvn -v" ``sh ``"java --version" ``sh ``"mvn clean package -Dmaven.test.skip=true" ``echo "构建完成" ``} ``} ``stage(``'拷贝 JAR 到远程服务器'``) { ``when { ``expression { params.DEPLOY_MODE != ``'only_build' } ``} ``steps { ``script { ``def jarFile = sh(script: ``"ls ${JAR_PATTERN} 2>/dev/null | head -n 1"``, returnStdout: ``true``).trim() ``if (!jarFile) { ``error(``"未找到 JAR 包: ${JAR_PATTERN}"``) ``} ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 拷贝到远程 IP: ${ip}" ``// 检查并创建目录 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'mkdir -p ${REMOTE_DIR} /app/logs /app/shell' ``""``" ``// 拷贝 jar 包 ``sh ``""``" ``rsync -az ${jarFile} root@${ip}:${REMOTE_DIR}/ ``""``" ``} ``echo "拷贝完成" ``} ``} ``} ``stage(``'远程部署服务'``) { ``when { ``expression { params.DEPLOY_MODE == ``'build_and_deploy' || params.DEPLOY_MODE == ``'only_deploy' } ``} ``steps { ``script { ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 部署到远程 IP: ${ip}" ``// 生成并执行远程启动命令 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'/bin/bash /app/shell/start.sh ${APP_NAME} ${PORT}' ``""``" ``} ``} ``echo "服务部署完成" ``} ``} ``} } |

保存后,修改下描述就可以构建了

2,参数化选择部署环境

需求:手动选择分支(如 dev, test, main),让每个分支构建时部署到不同服务器。

每个分支构建后部署到指定环境(如测试、预发布、生产)。

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| //``定义全局变量,不能定义environment中,因为``env``变量的赋值是只读的,scripe块中修改``env``值不会生效。 def REMOTE_IP_LIST = ``'' pipeline { ``agent any ``parameters { ``choice(name: ``'BRANCH_NAME'``, choices: [``'dev'``, ``'test'``, ``'main'``], description: ``'请选择构建分支'``) ``} ``environment { ``APP_NAME = ``'xxl-job-admin' ``BUILD_NAME = ``'xxl_job_pip' ``PORT = ``'8080' ``REMOTE_DIR = ``"/app/${APP_NAME}" ``JAR_PATTERN = ``"${JENKINS_HOME}/workspace/${BUILD_NAME}/${APP_NAME}/target/${APP_NAME}-*.jar" ``// 各环境服务器 IP(后期只改这里) ``DEV_IPS = ``'198.19.249.107' ``TEST_IPS = ``'198.19.249.102' ``MAIN_IPS = ``'198.19.249.103 198.19.249.104' ``} ``tools { ``maven ``"maven-3.9.6" ``jdk ``'jdk17' ``} ``stages { ``stage(``'设置部署服务器'``) { ``steps { ``script { ``switch (params.BRANCH_NAME) { ``case 'dev'``: ``REMOTE_IP_LIST = ``env``.DEV_IPS ``break ``case 'test'``: ``REMOTE_IP_LIST = ``env``.TEST_IPS ``break ``case 'main'``: ``REMOTE_IP_LIST = ``env``.MAIN_IPS ``break ``default: ``error ``"未知分支:${params.BRANCH_NAME}" ``} ``echo "当前分支:${params.BRANCH_NAME}" ``echo "部署服务器:${REMOTE_IP_LIST}" ``} ``} ``} ``stage(``'gitlab代码拉取'``) { ``steps { ``git branch: ``"${params.BRANCH_NAME}"``, credentialsId: ``'25238080-093d-4e3c-884c-f70a027eb1c9'``, url: ``'git@198.19.249.92:project-1/xxl-job.git' ``echo '拉取dev分支成功' ``} ``} ``stage(``'mvn执行构建'``) { ``steps { ``sh ``"mvn -v" ``sh ``"java --version" ``sh ``"mvn clean package -Dmaven.test.skip=true" ``echo "构建完成" ``} ``} ``stage(``'拷贝 JAR 到远程服务器'``) { ``steps { ``script { ``def jarFile = sh(script: ``"ls ${JAR_PATTERN} 2>/dev/null | head -n 1"``, returnStdout: ``true``).trim() ``if (!jarFile) { ``error(``"未找到 JAR 包: ${JAR_PATTERN}"``) ``} ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 拷贝到远程 IP: ${ip}" ``// 检查并创建目录 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'mkdir -p ${REMOTE_DIR} /app/logs /app/shell' ``""``" ``// 拷贝 jar 包 ``sh ``""``" ``rsync -az ${jarFile} root@${ip}:${REMOTE_DIR}/ ``""``" ``} ``echo "拷贝完成" ``} ``} ``} ``stage(``'远程部署服务'``) { ``steps { ``script { ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "==> 部署到远程 IP: ${ip}" ``// 生成并执行远程启动命令,根据脚本选择参数,我个人脚本运行需要传2个参数 ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'/bin/bash /app/shell/start.sh ${APP_NAME} ${PORT}' ``""``" ``} ``} ``echo "服务部署完成" ``} ``} ``} } |

3,版本控制选择发布

对于以往打包过的jar 保存好,然后动态获取所有的包,选择发布。

Active Choices Plugin 是在 Jenkins 中动态生成参数(如版本号列表)最推荐、最灵活的方式之一,特别适合"从已构建产物目录中选择版本进行部署"的场景。

系统管理 >> 插件管理 >> Active Choices Plugin 安装即可。

在任务配置"参数化构建过程",多出三个参数:

参数类型 用途 典型表现形式
Active Choices Parameter 独立生成选项 如动态下拉框,构建版本号列表
Active Choices Reactive Parameter 依赖其他参数生成选项 如根据"分支"选择对应"模块"列表
Active Choices Reactive Referenced Parameter 依赖其他参数生成一段 只读文本(非选项) 如动态提示用户选择的版本描述或告警

一般用得多的是第1个和第2个。

不需要根据其他参数来匹配就用第1个,参数化选择Active Choices Parameter,然后Groovy script 写脚本即可。

示例Groovy脚本:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #获取目标文件夹的jar包,并以版本号,只显示数字:3.1.0 def ``dir = new File(``"/var/lib/jenkins/workspace/xxl_job_pip/xxl-job-admin/target"``) if (!``dir``.exists()) ``return [``"无可用版本"``] def files = ``dir``.listFiles().findAll { it.name.endsWith(``".jar"``) } def versions = files.collect { it.name.replaceAll(``"xxl-job-admin-(.*)\\.jar"``, ``"\$1"``) } return versions.``sort``().reverse() #获取目标文件夹的jar包,并以整个包名显示:xxl-job-admin-3.1.0.jar def ``dir = new File(``"/var/lib/jenkins/workspace/xxl_job_pip/xxl-job-admin/target"``) if (!``dir``.exists()) ``return [``"无可用版本"``] def files = ``dir``.listFiles().findAll { it.name.endsWith(``".jar"``) } def filenames = files*.name return filenames.``sort``().reverse() |

这里介绍主要使用第二个参数Active Choices Reactive Parameter

需求:根据其他参数选择显示版本号。

1 :选择"全新构建发布",显示 "不适用"或者"空"

2:选择"以往版本发布",显示所有包名。

添加一个普通 选项参数:

名称 :RELEASE_TYPE,选项:全新构建发布 以往版本发布

添加另一个Active Choices Reactive Parameter参数:

name: APP_VERSION

Script: Groovy Script

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| // 判断是否为"以往版本发布" if (RELEASE_TYPE != ``"以往版本发布"``) { ``return [``"不适用"``] } // 读取存储目录下的所有 jar 文件 def ``dir = new File(``"/opt/jar/xxl-job-admin"``) if (!``dir``.exists()) ``return [``"目录不存在"``] def files = ``dir``.listFiles().findAll { it.name.endsWith(``".jar"``) } if (files.isEmpty()) ``return [``"无可用版本"``] return files*.name.``sort``().reverse() |

Fallback Script ,只有在脚本执行失败或者返回的类型不是上面提到的类型时执行,可以填可以空着。

Choice Type: Single Select (单选即可)

Referenced Parameters :填写 RELEASE_TYPE(关键!表示依赖此参数)

配置完成后,可以选择 Build with Parameters,查看是否显示成功.

Pipeline script :

最新流程为: 部署环境 >> Git 拉取代码 >> Maven 构建 >> 存储备份 JAR 包 >> 拷贝 JAR 到远程服务器 >> 远程启动服务

相对比前面的脚本,增加了 存储备份 步骤,备份以时间戳重命名(如果构建版本带版本号,可以不要时间戳)。

将构建的包复制到指定文件夹,都从此文件夹部署相应的包至服务器。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| def REMOTE_IP_LIST = ``'' pipeline { ``agent any ``parameters { ``choice(name: ``'BRANCH_NAME'``, choices: [``'dev'``, ``'test'``, ``'main'``], description: ``'请选择构建分支'``) ``choice(name: ``'RELEASE_TYPE'``, choices: [``'全新构建发布'``, ``'以往版本发布'``], description: ``'发布方式'``) ``} ``environment { ``APP_NAME = ``'xxl-job-admin' ``BUILD_NAME = ``'xxl_job_pip' ``PORT = ``'8080' ``JAR_PATTERN = ``"${JENKINS_HOME}/workspace/${BUILD_NAME}/${APP_NAME}/target/" ``JAR_PATH = ``"/opt/jar/${APP_NAME}" ``REMOTE_DIR = ``"/app/${APP_NAME}" ``DEV_IPS = ``'198.19.249.107' ``TEST_IPS = ``'198.19.249.102' ``MAIN_IPS = ``'198.19.249.103 198.19.249.104' ``} ``tools { ``maven ``"maven-3.9.6" ``jdk ``'jdk17' ``} ``stages { ``stage(``'部署环境'``) { ``steps { ``script { ``switch (params.BRANCH_NAME) { ``case 'dev'``: REMOTE_IP_LIST = ``env``.DEV_IPS; ``break ``case 'test'``: REMOTE_IP_LIST = ``env``.TEST_IPS; ``break ``case 'main'``: REMOTE_IP_LIST = ``env``.MAIN_IPS; ``break ``default: error ``"未知分支:${params.BRANCH_NAME}" ``} ``echo "部署环境分支:${params.BRANCH_NAME}" ``echo "部署方式:${params.RELEASE_TYPE}" ``if (params.RELEASE_TYPE != ``'全新构建发布'``) { ``echo "部署版本包: ${params.APP_VERSION}" ``} ``echo "部署服务器:${REMOTE_IP_LIST}" ``} ``} ``} ``stage(``'Git 拉取代码'``) { ``when { ``expression { ``return !params.APP_VERSION } ``// 如果是空,表示全新构建 ``} ``steps { ``git branch: ``"${params.BRANCH_NAME}"``, ``credentialsId: ``'25238080-093d-4e3c-884c-f70a027eb1c9'``, ``url: ``'git@198.19.249.92:project-1/xxl-job.git' ``echo "拉取 ${params.BRANCH_NAME} 分支成功" ``} ``} ``stage(``'Maven 构建'``) { ``when { ``expression { ``return !params.APP_VERSION } ``// 只在构建新版本时执行 ``} ``steps { ``sh ``"mvn -v" ``sh ``"java --version" ``sh ``"mvn clean package -Dmaven.test.skip=true" ``echo "构建完成" ``} ``} ``stage(``'存储备份 JAR 包'``) { ``when { ``expression { ``return !params.APP_VERSION } ``// 只在构建新版本时执行 ``} ``steps { ``script { ``def regex = ``"^${env.APP_NAME}(-[0-9.]+)?\\.jar\$" ``def jarFile = sh( ``script: ``"ls -t ${env.JAR_PATTERN} | grep -E '${regex}' | head -n 1"``, ``returnStdout: ``true ``).trim() ``if (!jarFile) { ``error(``"未找到构建生成的 jar 包"``) ``} ``// 获取当前时间戳 ``def timestamp = sh(script: ``"date +%Y%m%d%H%M"``, returnStdout: ``true``).trim() ``// 生成带时间的备份文件名 ``def newFileName = jarFile.replace(``".jar"``, ``"-${timestamp}.jar"``) ``sh ``""``" ``mkdir -p ${``env``.JAR_PATH} ``cp ${``env``.JAR_PATTERN}${jarFile} ${``env``.JAR_PATH}/${newFileName} ``ls -tp ${``env``.JAR_PATH}/*.jar | ``grep -``v '/\$' | ``tail -n +11 | ``xargs -r ``rm -- ``""``" ``echo "备份完成,保留最新 10 个版本:${jarFile}" ``} ``} ``} ``stage(``'拷贝 JAR 到远程服务器'``) { ``steps { ``script { ``def jarFileName ``def jarFilePath ``if (params.APP_VERSION?.trim()) { ``// 指定了版本:用选定的版本文件名 ``jarFileName = params.APP_VERSION.trim() ``jarFilePath = ``"${env.JAR_PATH}/${jarFileName}" ``} ``else { ``// 未指定版本:自动找最新的 ``jarFileName = sh(script: ``"ls -t ${env.JAR_PATH}/*.jar | head -n 1"``, returnStdout: ``true``).trim().tokenize(``"/"``).last() ``jarFilePath = ``"${env.JAR_PATH}/${jarFileName}" ``} ``if (!jarFileName || !fileExists(jarFilePath)) { ``error(``"未找到 JAR 包用于部署: ${jarFilePath}"``) ``} ``echo "部署使用 JAR 包:${jarFilePath}" ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "拷贝到远程 IP: ${ip}" ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'mkdir -p ${REMOTE_DIR} /app/logs /app/shell' ``rsync -az ${jarFilePath} root@${ip}:${REMOTE_DIR}/ ``""``" ``} ``} ``} ``} ``stage(``'远程启动服务'``) { ``steps { ``script { ``for (ip ``in REMOTE_IP_LIST.``split``()) { ``echo "部署到远程 IP: ${ip}" ``// ``sh ``""``" ``ssh -o StrictHostKeyChecking=no root@${ip} ``'/bin/bash /app/shell/start.sh ${APP_NAME} ${PORT}' ``""``" ``} ``} ``echo "${env.APP_NAME}服务部署完成" ``} ``} ``} } |

相关推荐
鸥梨菌Honevid3 天前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet
小白的码BUG之路3 天前
Jenkins -- 配置jdk和maven
java·jenkins·maven
9144062323 天前
安装jenkins遇到的问题总结
运维·jenkins
小白的码BUG之路3 天前
Jenkins -- 配置ssh
运维·ssh·jenkins
王琦03184 天前
jenkins使用手册
运维·jenkins
不老刘4 天前
Maven 多医院分支场景下 groupId 的设计与 Jenkins 落地实践
servlet·jenkins·maven
有同事要进步4 天前
如何在github或者是gitlab上创建空文件
gitlab·github
GoodStudyAndDayDayUp6 天前
gitlab私有化跑CICD
gitlab·gitlab私有化跑cicd
成为你的宁宁6 天前
【Gitlab测试项目】
gitlab·devops
wangfenglei1234566 天前
jenkins权限配置
运维·jenkins