jenkins-share-library/vars/pipelineGolangService.groovy
2026-01-14 21:30:20 +08:00

364 lines
20 KiB
Groovy
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 导入在 Pipeline 中需要使用的共享库类
// 这些类通常在 Jenkins 的共享库 (Shared Libraries) 中定义,提供了可重用的功能
import com.golang.ResolverService
import com.golang.DeploymentService
import com.common.StageService
import com.common.NotificationService
/**
* 主管道入口点
* 提供完整的CI/CD流水线功能实现从配置加载到部署的全流程自动化
* 这是一个 Jenkins 共享库 (Shared Library) 中的全局变量 (Global Variable) 或直接在 Pipeline 脚本中定义的方法
*
* @param orgName 组织名称,用于标识不同的组织配置和环境。这是调用此流水线时必须传入的主要参数。
*
* 功能特性:
* - 动态配置加载:支持根据 orgName 加载多环境配置管理
* - 多阶段流水线:清晰的构建、测试、部署、验证流程
* - 错误恢复机制:完善的异常处理和回滚功能 (虽然在当前代码示例中未完全展示,但框架支持)
* - 资源清理:自动清理工作空间和临时资源,避免磁盘空间耗尽
* - 通知机制:构建结果通知(成功、失败、中止、不稳定)
*
* 示例用法:
* @Library ('share-library@master')_
* orgName = 'xiaomayi'
* pipelineJDKService(orgName)
*/
def call(String orgName) { // Jenkins Pipeline 的入口方法通常命名为 call
// 定义管道参数变量,用于在不同阶段间传递配置信息。初始化为 null。
def pipelineParams = null
// 声明服务类变量,将在后续阶段初始化
def resolverService = null // 配置解析服务实例
def deploymentService = null // 部署服务实例
def stageService = null // 阶段服务实例
def notificationService = null // 通知服务实例
// Jenkins代理标签指定流水线特定阶段在哪个代理节点上运行
def jenkinsAgent = ''
// 启动流水线定义。这是 Declarative Pipeline 的语法开始
pipeline {
// 指定流水线执行代理any表示可在任何可用代理上运行。
// 注意:这里定义的 agent 会被后面 stage 中定义的 agent 覆盖。
agent any
// 流水线全局配置选项块
options {
// 构建历史保留策略,用于管理 Jenkins 服务器磁盘空间
buildDiscarder(logRotator(
artifactDaysToKeepStr: '', // 构建产物保留天数(空字符串表示不按天数限制,可能使用数量限制)
artifactNumToKeepStr: '2', // 保留最近2个构建的产物如生成的jar包、docker镜像等
daysToKeepStr: '7', // 构建记录元数据日志、状态等保留7天
numToKeepStr: '3' // 保留最近3个构建记录无论天数
))
// 全局超时设置整个流水线最多运行2小时超时则自动终止防止无限运行
timeout(time: 2, unit: 'HOURS')
// 还可以添加其他选项,例如: disableConcurrentBuilds() 防止并行运行等
}
// 流水线阶段定义块,包含按顺序执行的一系列阶段 (stages)
stages {
/**
* 第一阶段:初始化配置和环境
* 加载环境配置、解析参数、初始化服务实例。
* 此阶段仍在 pipeline 顶部定义的 agent any 上运行。
*/
stage('Setup Parameters & ENV') {
steps {
// 执行Git检出操作 (checkout SCM),获取流水线配置文件或所需的配置仓库
checkout scmGit([ // scmGit 是一种 checkout 方式
// 指定要检出的分支,这里检出 master 分支
branches: [[name: '*/master']],
// 配置远程仓库信息包括认证和URL
userRemoteConfigs: [[
credentialsId: 'c9b5eae2-5df5-485f-bebd-9cd5393b03e1', // 存储在 Jenkins 中的 Git 认证凭据ID
url: 'http://192.168.10.102:3000/cicd/jenkins-pipeline-files.git' // 配置仓库的URL地址
]],
// 扩展配置:指定检出到非默认工作目录的子目录中,避免与后续可能检出的应用代码冲突
extensions: [[
$class: 'RelativeTargetDirectory', // Jenkins checkout 扩展的类名,用于设置相对目标目录
relativeTargetDir: '.pipeline-files' // 将配置仓库检出到工作空间下的 .pipeline-files 目录
]],
])
script {
echo "=== 开始初始化配置 ==="
echo "组织名称: ${orgName}" // 打印传入的组织名称参数
try { // 使用 try-catch 进行异常处理,确保配置失败时能妥善处理
// 初始化阶段服务实例this 代表当前的流水线脚本对象,用于访问 Jenkins 步骤
stageService = new StageService(this)
// 记录 '初始化配置' 阶段的开始时间
stageService.recordStageStart('初始化配置')
// 初始化配置解析服务实例,传入当前脚本对象和组织名称
resolverService = new ResolverService(this, orgName)
// 调用解析服务的方法,加载所有配置文件(如环境相关的配置和主配置)
resolverService.loadConfigurations()
// 调用解析服务的方法,解析加载的配置并设置管道运行所需的参数集合
// 返回的 pipelineParams 可能包含 Maven 设置、镜像仓库地址、目标服务器配置、环境变量等
pipelineParams = resolverService.setupParameters()
// 处理环境 profile 选择逻辑
// params.PROFILES 可能是一个通过 Jenkins 输入参数parameters {} 块)传入的值
// 如果用户选择了 profile则使用它否则使用配置文件中定义的默认 profile (pipelineParams.PROFILES)
def selectedProfile = params.PROFILES ?: pipelineParams.PROFILES
pipelineParams.PROFILES = selectedProfile // 将最终确定的 profile 设置回参数Map中
// 设置后续构建和部署阶段使用的 Jenkins 代理标签
// 优先使用配置文件中指定的代理标签,如果未配置则默认使用 'master' 节点Jenkins Controller
jenkinsAgent = pipelineParams?.jenkinsAgent ?: 'master'
echo "本次使用代理节点: ${jenkinsAgent}"
// 初始化部署服务实例,传入当前脚本对象和从配置中获取的环境配置
deploymentService = new DeploymentService(this, pipelineParams.envConfig)
// 初始化消息通知服务实例,传入当前脚本对象、管道参数和阶段服务实例
notificationService = new NotificationService(this, pipelineParams, stageService)
// ✅ 关键步骤:将配置文件 stash 起来
stash name: 'pipeline-files', includes: '.pipeline-files/**'
// 记录 '初始化配置' 阶段的成功结束
stageService.recordStageEnd('初始化配置', 'SUCCESS')
} catch (Exception e) { // 捕获初始化过程中可能抛出的任何异常
// 打印错误信息到流水线日志
echo "配置初始化失败: ${e.message}"
// 记录 '初始化配置' 阶段的失败结束
stageService.recordStageEnd('初始化配置', 'FAILURE')
// 抛出错误,终止整个流水线的执行,并标记为 FAILURE 状态
error("管道初始化失败: " + e.getMessage())
}
echo "=== 结束初始化配置 ==="
}
}
}
/**
* 第二阶段:代码构建
* 执行Maven构建编译、测试、打包生成可部署的JAR包和Docker镜像。
* 此阶段在指定的 Jenkins 代理节点 (jenkinsAgent) 上运行,以分担主节点负载或使用特定环境。
*/
stage('Build') {
// 指定在此阶段使用的 Jenkins 代理节点标签
agent {
label jenkinsAgent // 使用前面计算得到的代理标签
}
steps {
script {
echo "=== 🔨 开始代码构建 ==="
// ✅ 关键步骤:在节点上 unstash 配置文件
unstash 'pipeline-files'
// 记录 '构建镜像' 阶段的开始时间
stageService.recordStageStart('构建镜像')
// 调用部署服务的方法,执行具体的构建逻辑
// 该方法内部可能包含mvn clean compile/test/package、docker build/push 等步骤
deploymentService.executeBuildStage(pipelineParams)
// 记录 '构建镜像' 阶段的成功结束
stageService.recordStageEnd('构建镜像', 'SUCCESS')
echo "=== 🔨 完成代码构建 ==="
}
}
}
/**
* 第三阶段:容器构建阶段
* 负责将JAR包构建为Docker镜像并推送到镜像仓库
* 此阶段同样在指定的 Jenkins 代理节点 (jenkinsAgent) 上运行。
*/
stage('Container Build') {
agent {
label jenkinsAgent
}
steps {
script {
echo "=== 🐳 开始容器构建 ==="
// ✅ 关键步骤:在节点上 unstash 配置文件
unstash 'pipeline-files'
// 记录 '应用部署' 阶段的开始时间
stageService.recordStageStart('容器构建')
// 调用部署服务的方法,执行具体的容器构建逻辑
deploymentService.executeContainerBuildStage(pipelineParams)
// 记录 '应用部署' 阶段的成功结束
stageService.recordStageEnd('容器构建', 'SUCCESS')
echo "=== 🚀 完成容器构建 ==="
}
}
}
/**
* 第四阶段:应用部署
* 将Docker镜像部署到目标服务器如测试、预生产、生产环境
* 此阶段同样在指定的 Jenkins 代理节点 (jenkinsAgent) 上运行。
*/
stage('Deploy') {
// 指定在此阶段使用的 Jenkins 代理节点标签
agent {
label jenkinsAgent
}
steps {
script {
echo "=== 🚀 开始应用部署 ==="
// ✅ 关键步骤:在节点上 unstash 配置文件
unstash 'pipeline-files'
// 记录 '应用部署' 阶段的开始时间
stageService.recordStageStart('应用部署')
// 调用部署服务的方法,执行具体的部署逻辑
// 该方法内部可能包含:通过 SSH 连接到目标服务器、执行部署脚本、更新容器docker compose/k8s
deploymentService.executeDeployStage(pipelineParams)
// 记录 '应用部署' 阶段的成功结束
stageService.recordStageEnd('应用部署', 'SUCCESS')
echo "=== 🚀 完成应用部署 ==="
}
}
}
/**
* 第五阶段:健康检查
* 负责验证部署的应用是否正常运行,确保部署的服务的可用性和功能性
* 这是CI/CD流程中的重要质量关卡防止有缺陷的部署进入生产环境
*/
stage('Health Check') {
agent {
// 使用配置文件中指定的代理标签,如果未配置则默认使用'master'节点
// 健康检查可能需要访问部署环境网络或使用特定工具
label jenkinsAgent
}
steps {
script {
echo "=== 🏥 开始健康检查 ==="
// ✅ 关键步骤:在节点上 unstash 配置文件
unstash 'pipeline-files'
// 记录健康检查阶段的开始时间和状态
stageService.recordStageStart('健康检查')
try {
// 调用部署服务的健康检查方法,执行具体的验证逻辑
// deploymentService.executeHealthCheckStage(pipelineParams)
// 🏗️ 以下是健康检查可能包含的具体操作(示例):
// 1. 🔗 服务端点连通性测试
// - 检查应用的健康检查端点(如:/actuator/health是否返回200状态码
// - 验证关键API接口是否可访问
// 2. 📊 应用状态验证
// - 检查应用日志是否有启动错误
// - 验证数据库连接是否正常建立
// - 确认必要的服务依赖如Redis、MQ等是否连接成功
// 3. 🔍 功能冒烟测试
// - 执行一组最基本的业务操作测试,确保核心功能正常
// - 验证配置是否正确加载(如配置文件、环境变量等)
// 4. 📈 性能基线检查
// - 检查应用启动时间是否在可接受范围内
// - 验证内存占用、线程数等指标是否正常
// 5. 🐳 容器运行状态检查
// - 确认Docker容器处于Running状态
// - 检查容器资源使用情况CPU、内存
// 调用部署服务的健康检查阶段逻辑
// deploymentService.executeHealthCheckStage(pipelineParams)
// 记录健康检查阶段的成功结束
stageService.recordStageEnd('健康检查', 'SUCCESS')
} catch (Exception e) {
// 健康检查失败时的处理
echo "健康检查失败: ${e.message}"
// 记录健康检查阶段的失败状态
stageService.recordStageEnd('健康检查', 'FAILURE')
// 可以选择抛出错误使整个流水线失败或者标记为UNSTABLE
error("健康检查未通过,部署可能存在风险: " + e.getMessage())
}
echo "=== 🏥 完成健康检查 ==="
}
}
}
// 可以在此处添加更多阶段,例如:自动化测试、集成测试、性能测试、安全扫描等
}
/**
* 流水线后处理块 (post section)
* 根据流水线的最终状态执行不同的操作,无论构建成功与否都会执行的处理逻辑。
* 此部分在 pipeline 顶部定义的 agent any 上运行。
*/
post {
/**
* always无论构建结果如何成功、失败、中止、不稳定都会执行
* 主要用于资源清理和状态报告等必须完成的操作
*/
always {
echo "=== 管道执行完成 ==="
echo "完成时间: ${new Date()}" // 打印流水线结束的时间
// 清理工作空间,删除当前流水线运行产生的所有文件,释放磁盘空间
cleanWs()
script {
echo "构建完成,状态: ${currentBuild.currentResult}" // 打印最终构建状态
// 调用阶段服务的方法,收集所有阶段的执行信息(开始时间、持续时间、状态),可能用于通知或报告
stageService.collectAllStagesInfo()
}
}
/**
* success只有当整个流水线的状态为 SUCCESS 时执行
* 主要用于成功通知和结果报告
*/
success {
echo "✅ 部署成功!"
script {
// 调用通知服务的方法发送构建成功的通知如邮件、钉钉、Slack等
notificationService.sendBuildSuccess()
}
}
/**
* failure只有当整个流水线的状态为 FAILURE 时执行
* 主要用于错误报告、通知和可能的清理或回滚操作(虽然此处未展示回滚)
*/
failure {
echo "❌ 部署失败!"
script {
// 调用通知服务的方法,发送构建失败的通知,并传递错误信息
// 这里的 errorMsg 和 extraInfo 是示例,实际可能从捕获的异常中获取
notificationService.sendBuildFailure(
errorMsg: "单元测试失败", // 示例错误消息
extraInfo: [stage: "test", errorDetails: "具体错误信息"] // 示例额外信息
)
}
}
/**
* aborted只有当整个流水线的状态为 ABORTED 时执行(通常由用户手动中止)
* 用于通知构建被中止的情况
*/
aborted {
echo "❌ 构建中止!"
script {
// 调用通知服务的方法,发送构建中止的通知
notificationService.sendBuildAborted(
// 传递一些额外信息,例如中止原因和操作人(如果环境变量可用)
extraInfo: [: '手动中止', : env.USER_ID]
)
}
}
/**
* unstable只有当整个流水线的状态为 UNSTABLE 时执行(通常由测试失败或有警告导致)
* 主要用于警告通知
*/
unstable {
echo "⚠️ 管道执行不稳定"
script {
// 调用通知服务的方法,发送构建不稳定的通知
notificationService.sendBuildUnstable(
extraInfo: ["不稳定原因": "测试未通过或存在警告"] // 示例原因
)
}
}
}
}
}