运维|devops|Jenkins Pipeline流程构建

基于 jenkins Version 2.541.3 实操案例

Jenkins Pipeline

基于 Groovy 的持续交付流水线代码(Pipeline as Code)

Pipeline script vs Pipeline script from SCM(实操)

Jenkinsfile 脚本内容的语法格式如下两种

前置条件

git、ssh、jdk、ma ven 等配置

服务器端开启ssh登录

Jenkinsfile文件和脚本创建

Jenkinsfile位置放入项目pom同级别

创建Pipeline任务

构建相关pipeline

执行构建结果

优化脚本

增加git 打印、和后台应用日志
pipeline {
agent any

options {
disableConcurrentBuilds()
timeout(time: 20, unit: 'MINUTES')
timestamps()
buildDiscarder(logRotator(numToKeepStr: '10'))
}

parameters {
booleanParam(
name: 'AUTO_DEPLOY',
defaultValue: false,
description: '构建完成自动推送Jar并重启远程服务'
)
}

environment {
SERVICE_DIR = 'app'
SERVICE_NAME = 'app'
JAR_VERSION = '1.0.0-SNAPSHOT'
JAR_FILE = "${SERVICE_NAME}-${JAR_VERSION}.jar"
REMOTE_SUB_DIR = "${SERVICE_NAME}"
REMOTE_FULL_DIR = "/usr/local/${REMOTE_SUB_DIR}"
LOCAL_JAR_PATH = "${SERVICE_DIR}/target/${JAR_FILE}"
JA VA_HOME = '/usr/local/jdk21'
M2_HOME = '/usr/local/ma ven'
REMOTE_HOST = '192.168.0.66'
REMOTE_USER = 'test'
SSH_CREDENTIALS_ID = 'test'
}

stages {
stage('1. 环境信息 & Git提交日志打印') {
steps {
sh '''#!/bin/bash
echo "==================== Git 最新提交信息 ===================="
echo "短提交号: $(git rev-parse --short HEAD)"
echo "完整commit: $(git rev-parse HEAD)"
echo "提交人姓名: $(git log -1 --pretty=%an)"
echo "提交备注:"
git log -1 --pretty=%B
echo "=========================================================="
'''

echo "【构建信息】服务名:${env.SERVICE_NAME}|Jar包:${env.JAR_FILE}"
echo "本地路径:${env.LOCAL_JAR_PATH}"
echo "远端目录:${env.REMOTE_FULL_DIR}"
}
}

stage('2. Ma ven编译打包') {
steps {
sh '''#!/bin/bash
test -d ${JA VA_HOME} || { echo " JA VA_HOME目录不存在"; exit 1; }
test -d ${M2_HOME} || { echo " M2_HOME目录不存在"; exit 1; }
${JA VA_HOME}/bin/ja va -version
${M2_HOME}/bin/mvn -v
cd ${SERVICE_DIR}
${M2_HOME}/bin/mvn clean package -DskipTests
'''
}
}

stage('3. 归档构建产物') {
steps {
archiveArtifacts artifacts: "${env.LOCAL_JAR_PATH}", fingerprint: true, onlyIfSuccessful: true
}
}

stage('4. 远程发布部署') {
when {
expression { params.AUTO_DEPLOY }
}
steps {
echo "开始推送Jar包并远程重启服务"

withCredentials([sshUserPrivateKey(
credentialsId: "${env.SSH_CREDENTIALS_ID}",
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
// ===== 使用三双引号 """ 允许Groovy解析Jenkins环境变量 =====
sh """#!/bin/bash
set -e -x
scp -i $SSH_KEY -o StrictHostKeyChecking=no ${LOCAL_JAR_PATH} ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_FULL_DIR}/${JAR_FILE}

ssh -i $SSH_KEY -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} << EOF
SERVICE_NAME=${SERVICE_NAME}
REMOTE_FULL_DIR=${REMOTE_FULL_DIR}
JAR_FILE=${JAR_FILE}

mkdir -p ${REMOTE_FULL_DIR}
cd ${REMOTE_FULL_DIR}

echo "【1】优雅停止旧服务进程"
pgrep -f "ja va.*${SERVICE_NAME}" | xargs kill -15 2>/dev/null || true
sleep 2
pgrep -f "ja va.*${SERVICE_NAME}" | xargs kill -9 2>/dev/null || true
sleep 1

echo "【2】启动新服务 >> 追加日志,不再清空日志文件"
# 远端服务器JA VA路径【硬编码】,彻底避开变量冲突大坑
nohup /usr/local/jdk-21.0.11/bin/ja va -Dfile.encoding=UTF-8 -jar ${JAR_FILE} >> app.log 2>&1 &
sleep 3

echo "========== 远端应用启动日志(尾部30行) =========="
[ -f app.log ] && tail -30 app.log || echo "app.log 文件尚未生成"
echo "===================================================="

echo "【3】校验进程状态"
if pgrep -f "ja va.*${SERVICE_NAME}" > /dev/null; then
echo " 服务进程启动成功"
else
echo " 服务启动失败!"
exit 1
fi
EOF
"""
}

echo "远程部署流程执行完毕"
}
}
}

post {
always {
echo "【Post钩子】流水线构建结束"
}
success {
cleanWs()
echo " 流水线全部执行成功!"
}
failure {
echo " 流水线执行失败,请查看日志排查问题!"
}
}
}

优化脚本之后


本文转载于:https://segmentfault.com/a/1190000048093086 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。