签入版本
This commit is contained in:
parent
bdb883149e
commit
959b9325ad
149
src/com/nexus/DeploymentService.groovy
Normal file
149
src/com/nexus/DeploymentService.groovy
Normal file
@ -0,0 +1,149 @@
|
||||
package com.nexus
|
||||
|
||||
import com.nexus.stages.BuildService
|
||||
import com.nexus.stages.DeployService
|
||||
|
||||
/**
|
||||
* 部署服务类 - CI/CD流水线核心协调器
|
||||
* 负责执行各个CI/CD阶段的业务逻辑,不直接创建Jenkins stage
|
||||
* 提供模块化的构建、部署、验证功能,作为流水线步骤的抽象层
|
||||
*
|
||||
* 设计原则:
|
||||
* - 单一职责:每个方法只负责一个特定的功能
|
||||
* - 错误隔离:每个阶段的异常不会影响其他阶段
|
||||
* - 可重用性:方法可以在不同的流水线中重用
|
||||
* - 可扩展性:易于添加新的部署阶段或功能
|
||||
* - 可维护性:清晰的代码结构和职责分离
|
||||
*
|
||||
* 主要职责:
|
||||
* 1. 协调各个部署阶段服务的执行
|
||||
* 2. 提供统一的参数传递接口
|
||||
* 3. 处理阶段间的依赖关系
|
||||
* 4. 提供错误处理和回滚机制
|
||||
*
|
||||
* @see Serializable 实现序列化接口,支持Jenkins流水线的暂停和恢复
|
||||
*/
|
||||
class DeploymentService implements Serializable {
|
||||
|
||||
/**
|
||||
* Jenkins pipeline脚本对象
|
||||
* 用于访问Jenkins DSL方法,如sh、echo、error等
|
||||
* 类型: Object (通常是Jenkins pipeline的script对象)
|
||||
*/
|
||||
def script
|
||||
|
||||
/**
|
||||
* 环境配置信息
|
||||
* 存储环境特定的配置参数,如服务器列表、环境变量等
|
||||
* 类型: Map<String, Object> 键值对配置映射
|
||||
*/
|
||||
def envConfig
|
||||
|
||||
// ==========================================================================
|
||||
// 各个阶段的服务实例(依赖注入)
|
||||
// ==========================================================================
|
||||
|
||||
/**
|
||||
* 构建阶段服务实例
|
||||
* 负责Maven项目的编译和打包操作
|
||||
* 类型: BuildService 专门处理构建逻辑的服务类
|
||||
*/
|
||||
def buildService
|
||||
|
||||
/**
|
||||
* 部署阶段服务实例
|
||||
* 负责将应用部署到目标服务器
|
||||
* 类型: DeployService 专门处理部署逻辑的服务类
|
||||
*/
|
||||
def deployService
|
||||
|
||||
/**
|
||||
* 构造函数 - 初始化部署服务
|
||||
* 创建各个阶段的服务实例,建立服务依赖关系
|
||||
*
|
||||
* @param script Jenkins pipeline脚本对象(必须)
|
||||
* - 用途:用于在各个服务中访问Jenkins DSL方法
|
||||
* - 示例:在Pipeline中通过`this`传递当前脚本上下文
|
||||
*
|
||||
* @param envConfig 环境配置信息(可选)
|
||||
* - 类型:Map<String, Object> 键值对配置映射
|
||||
* - 默认值:空Map [:]
|
||||
* - 内容:服务器列表、环境变量、部署策略等配置
|
||||
* - 示例:[
|
||||
* servers: [[serverIP: "192.168.1.1", serverPort: 22]],
|
||||
* envVars: [JAVA_OPTS: "-Xms1g -Xmx1g"],
|
||||
* deploymentStrategy: "rolling"
|
||||
* ]
|
||||
*/
|
||||
DeploymentService(script, envConfig = [:]) {
|
||||
// 初始化基础属性
|
||||
this.script = script
|
||||
this.envConfig = envConfig
|
||||
|
||||
// 初始化各个阶段服务(依赖注入模式)
|
||||
// 通过分离关注点,提高代码的可测试性和可维护性
|
||||
this.buildService = new BuildService(script, envConfig)
|
||||
this.deployService = new DeployService(script, envConfig)
|
||||
|
||||
script.echo "🔧 DeploymentService 初始化完成"
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行构建阶段逻辑
|
||||
* 委托给BuildService处理Maven项目的编译和打包
|
||||
* 这是CI/CD流水线的第一个阶段,负责源代码到产物的转换
|
||||
*
|
||||
* @param params 管道参数Map,包含构建所需的所有配置信息,必须包含:
|
||||
* - MAVEN_SET: String - Maven设置文件ID
|
||||
* - PROFILES: String - Maven构建环境profiles
|
||||
* - jarFilePath: String - JAR文件输出路径
|
||||
* - jarFile: String - 生成的JAR文件名
|
||||
* - skipTests: Boolean - 是否跳过测试(默认true)
|
||||
* - goals: String - Maven执行目标(默认"clean package")
|
||||
* - pomFilePath: String - POM文件路径(默认pom.xml)
|
||||
*
|
||||
* @throws Exception 当Maven构建失败时抛出异常,中断流水线
|
||||
*
|
||||
* @example 使用示例:
|
||||
* def params = [
|
||||
* MAVEN_SET: "nexus-maven-dev",
|
||||
* PROFILES: "dev",
|
||||
* jarFilePath: "target",
|
||||
* jarFile: "app.jar"
|
||||
* ]
|
||||
* deploymentService.executeBuildStage(params)
|
||||
*/
|
||||
def executeBuildStage(params) {
|
||||
// ☕ 开始构建阶段...
|
||||
buildService.executeBuildStage(params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行部署阶段逻辑
|
||||
* 委托给DeployService处理应用部署到目标服务器
|
||||
* 这是CI/CD流水线的第三个阶段,负责将容器部署到环境
|
||||
*
|
||||
* @param params 管道参数Map,包含部署所需的所有配置信息,必须包含:
|
||||
* - servers: List - 服务器列表数组
|
||||
* - deployServer: String - 部署服务器引用
|
||||
* - projectName: String - 项目名称
|
||||
* - PROFILES: String - 环境名称
|
||||
* 可选字段:
|
||||
* - deployScript: String - 部署脚本文件名
|
||||
* - deployPath: String - 部署脚本路径
|
||||
* - envVars: Map - 环境变量配置
|
||||
* - deploymentStrategy: String - 部署策略
|
||||
*
|
||||
* @throws Exception 当部署失败时抛出异常,支持自动回滚
|
||||
*
|
||||
* @note 支持多种部署模式:
|
||||
* - 单服务器部署:deployServer = "servers[0]"
|
||||
* - 多服务器部署:deployServer = "servers[0,1,2]"
|
||||
* - 自动选择:deployServer = "auto"
|
||||
*/
|
||||
def executeDeployStage(params) {
|
||||
// 🚀 开始部署阶段...
|
||||
deployService.executeDeployStage(params)
|
||||
}
|
||||
|
||||
}
|
||||
649
src/com/nexus/ResolverService.groovy
Normal file
649
src/com/nexus/ResolverService.groovy
Normal file
@ -0,0 +1,649 @@
|
||||
package com.nexus
|
||||
|
||||
import com.utils.CommonUtils
|
||||
import com.constants.ConfigConstants
|
||||
|
||||
/**
|
||||
* JDK API 服务类 - 增强Nexus私库上传支持
|
||||
* 负责加载配置、管理分支和服务配置、设置环境参数
|
||||
* 适配新的配置文件格式,支持多环境、多服务配置和Nexus发布配置
|
||||
*
|
||||
* 主要功能:
|
||||
* 1. 加载环境配置和主配置文件
|
||||
* 2. 解析分支和服务配置
|
||||
* 3. 设置Jenkins流水线参数
|
||||
* 4. 提供环境相关的配置获取方法
|
||||
* 5. 支持Nexus私库上传配置解析
|
||||
*
|
||||
* @version 2.1.0
|
||||
* @since 2025-09-09
|
||||
*/
|
||||
class ResolverService implements Serializable {
|
||||
|
||||
// Jenkins流水线脚本对象,用于执行Jenkins相关操作
|
||||
def script
|
||||
|
||||
// 主配置文件内容(解析后的YAML数据)
|
||||
def config
|
||||
|
||||
// 组织名称
|
||||
def orgName
|
||||
|
||||
// 环境配置文件内容
|
||||
def envConfig
|
||||
|
||||
// 主配置文件路径
|
||||
def jobConfigFile
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* 初始化服务类实例
|
||||
*
|
||||
* @param script Jenkins流水线脚本对象,提供echo、error等方法
|
||||
* @param orgName 组织名称,用于标识项目归属
|
||||
*/
|
||||
ResolverService(script, orgName) {
|
||||
this.script = script
|
||||
this.orgName = orgName
|
||||
this.config = [:]
|
||||
this.envConfig = [:]
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载所有配置文件
|
||||
* 按顺序加载环境配置和主配置文件
|
||||
*
|
||||
* @throws Exception 如果配置文件加载失败
|
||||
*/
|
||||
void loadConfigurations() {
|
||||
script.echo "🚀 开始加载配置文件..."
|
||||
|
||||
// 首先加载环境配置文件(.env.yml)
|
||||
loadEnvConfig()
|
||||
|
||||
// 然后加载主配置文件(根据环境配置中的路径)
|
||||
loadJobConfig()
|
||||
|
||||
script.echo "✅ 所有配置文件加载完成"
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载环境配置文件的方法
|
||||
* 从.jenkins/.env.yml读取环境配置,包含主配置文件路径等基本信息
|
||||
*
|
||||
* @return 返回当前对象实例,支持链式调用
|
||||
* @throws Exception 如果文件存在但解析失败
|
||||
*/
|
||||
def loadEnvConfig() {
|
||||
try {
|
||||
// 环境配置文件相对路径
|
||||
def envFilePath = '.jenkins/.env.yml'
|
||||
script.echo "📁 环境配置文件路径: ${envFilePath}"
|
||||
|
||||
if (script.fileExists(envFilePath)) {
|
||||
// 读取并解析YAML格式的环境配置文件
|
||||
envConfig = script.readYaml(file: envFilePath)
|
||||
|
||||
// 从环境配置中获取主配置文件路径
|
||||
jobConfigFile = ".pipeline-files/config-file/" + envConfig.jobConfigFile
|
||||
script.echo "✅ 成功加载环境配置文件"
|
||||
|
||||
// 打印所有环境配置项(调试用)
|
||||
if (!envConfig.isEmpty()) {
|
||||
script.echo "📋 环境配置内容:"
|
||||
envConfig.each { key, value ->
|
||||
script.echo " ${key}: ${value}"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
script.echo "⚠️ 警告: 未找到环境配置文件 .env.yml,使用默认配置"
|
||||
}
|
||||
} catch (Exception e) {
|
||||
script.echo "⚠️ 警告: .env.yml 文件无效,使用默认配置: ${e.message}"
|
||||
// 不抛出异常,允许继续执行
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载主配置文件的方法
|
||||
* 读取新的配置文件格式,包含common、branchConfig、serviceConfig等部分
|
||||
*
|
||||
* @return 返回当前对象实例,支持链式调用
|
||||
* @throws Exception 如果文件不存在或解析失败
|
||||
*/
|
||||
def loadJobConfig() {
|
||||
try {
|
||||
// 检查主配置文件是否存在
|
||||
if (!script.fileExists(jobConfigFile)) {
|
||||
script.error("❌ 错误: 配置文件不存在: ${jobConfigFile},请检查文件路径或创建配置文件")
|
||||
}
|
||||
|
||||
// 读取并解析YAML格式的主配置文件
|
||||
this.config = script.readYaml(file: jobConfigFile)
|
||||
script.echo "✅ 成功加载主配置文件: ${jobConfigFile}"
|
||||
|
||||
// 打印配置详情(调试用)
|
||||
printConfigSummary()
|
||||
|
||||
} catch (Exception e) {
|
||||
script.error("❌ 错误: 加载配置文件失败: ${jobConfigFile}. 错误详情: ${e.message}")
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印主配置文件的详细内容
|
||||
* 格式化输出所有配置信息,便于调试和验证
|
||||
*/
|
||||
def printConfigSummary() {
|
||||
script.echo "=" * 70
|
||||
script.echo "📊 主配置文件详细内容"
|
||||
script.echo "=" * 70
|
||||
|
||||
if (!this.config) {
|
||||
script.echo "⚠️ 配置文件内容为空"
|
||||
return
|
||||
}
|
||||
|
||||
// 打印通用配置信息
|
||||
if (this.config.common) {
|
||||
script.echo "🌐 通用配置:"
|
||||
script.echo "-" * 50
|
||||
|
||||
// Nexus配置
|
||||
if (this.config.common.nexus) {
|
||||
script.echo "🔗 Nexus仓库配置:"
|
||||
this.config.common.nexus.each { nexusName, nexusConfig ->
|
||||
script.echo " ${nexusName}: ${nexusConfig.url}"
|
||||
script.echo " 类型: ${nexusConfig.type}, 策略: ${nexusConfig.policy}"
|
||||
}
|
||||
}
|
||||
|
||||
// 构建策略配置
|
||||
if (this.config.common.buildStrategy) {
|
||||
script.echo "⚡ 构建策略:"
|
||||
script.echo " 重试次数: ${this.config.common.buildStrategy.retryCount}"
|
||||
script.echo " 超时时间: ${this.config.common.buildStrategy.timeoutMinutes}分钟"
|
||||
script.echo " 启用缓存: ${this.config.common.buildStrategy.enableCaching}"
|
||||
}
|
||||
|
||||
// 发布策略配置
|
||||
if (this.config.common.publishStrategy) {
|
||||
script.echo "🚀 发布策略:"
|
||||
script.echo " 版本策略: ${this.config.common.publishStrategy.versionPolicy}"
|
||||
script.echo " 自动发布: ${this.config.common.publishStrategy.autoPublish}"
|
||||
script.echo " 签名构件: ${this.config.common.publishStrategy.signArtifacts}"
|
||||
}
|
||||
script.echo ""
|
||||
}
|
||||
|
||||
// 打印环境配置信息
|
||||
if (this.config.common?.profiles) {
|
||||
script.echo "🏭 环境配置 (共 ${this.config.common.profiles.size()} 个环境):"
|
||||
script.echo "-" * 50
|
||||
|
||||
this.config.common.profiles.each { envName, envConfig ->
|
||||
script.echo " ${envName.toUpperCase()} 环境:"
|
||||
script.echo " Nexus配置: ${envConfig.nexus ?: 'default'}"
|
||||
script.echo " 版本后缀: ${envConfig.versionSuffix ?: '无'}"
|
||||
script.echo " 自动部署: ${envConfig.autoDeploy}"
|
||||
script.echo " 仓库策略: ${envConfig.repositoryPolicy ?: 'releases'}"
|
||||
script.echo ""
|
||||
}
|
||||
}
|
||||
|
||||
// 打印分支构建配置信息
|
||||
if (this.config.branchConfig) {
|
||||
script.echo "🌿 分支构建配置 (共 ${this.config.branchConfig.size()} 个分支):"
|
||||
script.echo "-" * 50
|
||||
|
||||
this.config.branchConfig.each { branchName, branchConfig ->
|
||||
script.echo " ${branchName} 分支:"
|
||||
script.echo " Jenkins代理: ${branchConfig.jenkinsAgent ?: '未设置'}"
|
||||
script.echo " Maven配置集: ${branchConfig.maven?.mavenSet ?: '未设置'}"
|
||||
script.echo " 跳过测试: ${branchConfig.maven?.skipTests ?: 'false'}"
|
||||
script.echo " Maven目标: ${branchConfig.maven?.goals ?: '未设置'}"
|
||||
script.echo " 部署操作: ${branchConfig.maven?.deploy ?: 'false'}"
|
||||
}
|
||||
}
|
||||
|
||||
// 打印服务配置信息
|
||||
if (this.config.serviceConfig) {
|
||||
script.echo "🔧 服务配置 (共 ${this.config.serviceConfig.size()} 个服务):"
|
||||
script.echo "-" * 50
|
||||
|
||||
this.config.serviceConfig.each { serviceName, serviceConfig ->
|
||||
script.echo " ${serviceName} 服务:"
|
||||
script.echo " 项目名称: ${serviceConfig.projectName ?: '未设置'}"
|
||||
script.echo " 项目描述: ${serviceConfig.description ?: '未设置'}"
|
||||
script.echo " 编程语言: ${serviceConfig.programLang ?: '未设置'}"
|
||||
script.echo " 语言版本: ${serviceConfig.programLangVersion ?: '未设置'}"
|
||||
script.echo " POM路径: ${serviceConfig.pomFilePath ?: '未设置'}"
|
||||
script.echo " 服务路径: ${serviceConfig.servicePath ?: '未设置'}"
|
||||
}
|
||||
}
|
||||
|
||||
script.echo "=" * 70
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前分支的配置
|
||||
* 根据当前Jenkins作业的分支名称查找对应的分支配置
|
||||
*
|
||||
* @return 分支配置对象(Map类型)
|
||||
* @throws Exception 如果分支配置不存在
|
||||
*/
|
||||
def getBranchConfig() {
|
||||
// 获取当前Jenkins作业的分支名称
|
||||
def branchName = script.env.BRANCH_NAME
|
||||
|
||||
if (!branchName) {
|
||||
script.error("❌ 错误: 无法获取分支名称,env.BRANCH_NAME 为空。请检查流水线配置")
|
||||
}
|
||||
|
||||
script.echo "🌿 正在查找分支配置: ${branchName}"
|
||||
|
||||
// 检查分支配置是否存在
|
||||
if (!config.branchConfig || config.branchConfig.isEmpty()) {
|
||||
script.error("❌ 错误: 分支配置列表为空或未定义。请检查配置文件结构")
|
||||
}
|
||||
|
||||
// 根据分支名称获取配置
|
||||
def branchConfig = config.branchConfig[branchName]
|
||||
|
||||
if (branchConfig) {
|
||||
script.echo "✅ 成功匹配分支配置:"
|
||||
script.echo " - Jenkins代理: ${branchConfig.jenkinsAgent ?: '未设置'}"
|
||||
script.echo " - Maven配置集: ${branchConfig.maven?.mavenSet ?: '未设置'}"
|
||||
script.echo " - Maven目标: ${branchConfig.maven?.goals ?: '未设置'}"
|
||||
script.echo " - 跳过测试: ${branchConfig.maven?.skipTests ?: 'false'}"
|
||||
script.echo " - 部署操作: ${branchConfig.maven?.deploy ?: 'false'}"
|
||||
} else {
|
||||
// 构建友好的错误信息,列出所有可用分支
|
||||
def availableBranches = config.branchConfig.keySet().join(', ')
|
||||
script.error("❌ 错误: 找不到分支 '${branchName}' 的配置。可用分支: ${availableBranches}")
|
||||
}
|
||||
|
||||
return branchConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定服务的配置信息
|
||||
* 根据服务名称从serviceConfig中查找对应的服务配置
|
||||
*
|
||||
* @param serviceName 服务名称,需要与配置文件中serviceConfig的键匹配
|
||||
* @return 服务配置对象(Map类型)
|
||||
* @throws Exception 如果服务配置不存在
|
||||
*/
|
||||
def getServiceConfig(serviceName) {
|
||||
if (!serviceName) {
|
||||
script.error("❌ 错误: 服务名称参数不能为空")
|
||||
}
|
||||
|
||||
script.echo "🔧 正在查找服务配置: ${serviceName}"
|
||||
|
||||
// 检查服务配置是否存在
|
||||
if (!config.serviceConfig || config.serviceConfig.isEmpty()) {
|
||||
script.error("❌ 错误: 服务配置列表为空或未定义,请检查配置文件结构")
|
||||
}
|
||||
|
||||
// 根据服务名称获取配置
|
||||
def serviceConfig = config.serviceConfig[serviceName]
|
||||
|
||||
if (serviceConfig) {
|
||||
script.echo "✅ 成功找到服务配置: ${serviceName}"
|
||||
script.echo " - 项目名称: ${serviceConfig.projectName ?: '未设置'}"
|
||||
script.echo " - 项目描述: ${serviceConfig.description ?: '未设置'}"
|
||||
script.echo " - 编程语言: ${serviceConfig.programLang ?: '未设置'}"
|
||||
script.echo " - 语言版本: ${serviceConfig.programLangVersion ?: '未设置'}"
|
||||
script.echo " - POM路径: ${serviceConfig.pomFilePath ?: '未设置'}"
|
||||
script.echo " - 服务路径: ${serviceConfig.servicePath ?: '未设置'}"
|
||||
} else {
|
||||
// 构建友好的错误信息,列出所有可用服务
|
||||
def availableServices = config.serviceConfig.keySet().join(', ')
|
||||
script.error("❌ 错误: 找不到服务 '${serviceName}' 的配置。可用服务: ${availableServices}")
|
||||
}
|
||||
|
||||
return serviceConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置管道参数
|
||||
* 整合分支配置、服务配置和环境配置,生成完整的流水线参数
|
||||
* 增强对Nexus发布配置的支持
|
||||
*
|
||||
* @return 参数映射表,包含所有必要的部署参数
|
||||
*/
|
||||
def setupParameters() {
|
||||
script.echo "⚙️ 开始设置管道参数..."
|
||||
|
||||
// 获取当前分支配置
|
||||
def branchConfig = getBranchConfig()
|
||||
|
||||
// 从Jenkins作业名称中提取服务名称
|
||||
// 格式通常为: "组织名/服务名" 或 "服务名"
|
||||
def serviceName = script.env.JOB_NAME?.tokenize('/')?.get(0)
|
||||
script.echo "📦 服务名称: ${serviceName}"
|
||||
|
||||
// 获取服务配置
|
||||
def serviceConfig = getServiceConfig(serviceName)
|
||||
|
||||
// 根据分支类型获取环境配置
|
||||
def profiles = getBranchProfiles(branchConfig)
|
||||
script.echo "🌍 环境配置: ${profiles}"
|
||||
|
||||
// 构建完整的参数映射表
|
||||
def params = [
|
||||
// 构建相关参数
|
||||
jenkinsAgent : branchConfig.jenkinsAgent,
|
||||
MAVEN_SET : branchConfig.maven?.mavenSet,
|
||||
skipTests : branchConfig.maven?.skipTests,
|
||||
goals : branchConfig.maven?.goals,
|
||||
mavenOptions : branchConfig.maven?.options,
|
||||
|
||||
// 服务相关参数
|
||||
projectName : serviceConfig.projectName ?: serviceConfig.containerName,
|
||||
description : serviceConfig.description,
|
||||
pomFilePath : serviceConfig.pomFilePath,
|
||||
servicePath : serviceConfig.servicePath,
|
||||
|
||||
// 环境相关参数
|
||||
PROFILES : profiles.default_profile,
|
||||
availableProfiles : profiles.available_profiles,
|
||||
|
||||
// Git配置
|
||||
gitUrl : config.common?.git?.url,
|
||||
gitCredentialsId : config.common?.git?.credentialsId,
|
||||
gitBranch : script.env.BRANCH_NAME,
|
||||
|
||||
// 钉钉配置
|
||||
dingTalkCredentialsId: config.common?.dingtalk?.credentialsId,
|
||||
|
||||
// 其他参数
|
||||
envConfig : this.envConfig,
|
||||
orgName : this.orgName,
|
||||
branchConfig : branchConfig,
|
||||
serviceConfig : serviceConfig
|
||||
]
|
||||
|
||||
// 获取分支环境变量配置
|
||||
getEnvironmentConfig(params)
|
||||
|
||||
script.echo "基础参数:${params}"
|
||||
|
||||
// 设置Jenkins参数(仅对标准流水线)
|
||||
setupJenkinsParameters(profiles.available_profiles as List<String>)
|
||||
|
||||
script.echo "✅ 管道参数设置完成"
|
||||
|
||||
// 返回参数
|
||||
return params
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定环境的全部配置参数
|
||||
* 从通用配置中提取指定环境的所有参数,包括Nexus配置、构建策略等
|
||||
*
|
||||
* @param params 参数映射表(会被修改),用于存储提取的配置信息
|
||||
* @return 包含指定环境全部参数的Map
|
||||
*/
|
||||
def getEnvironmentConfig(params) {
|
||||
try {
|
||||
// 从参数中获取环境名称,如果没有设置则使用默认值"dev"
|
||||
def envName = params.PROFILES ?: "dev"
|
||||
def envKey = envName.toLowerCase()
|
||||
|
||||
script.echo "🔍 开始获取 ${envKey} 环境的全部配置参数..."
|
||||
|
||||
// ==========================================================================
|
||||
// 添加Nexus配置
|
||||
// ==========================================================================
|
||||
if (config.common?.nexus) {
|
||||
params.nexusConfigs = config.common.nexus
|
||||
script.echo "🔗 Nexus配置已加载,共 ${config.common.nexus.size()} 个仓库"
|
||||
|
||||
// 设置当前环境使用的Nexus配置
|
||||
def envConfig = config.common?.profiles?."${envKey}"
|
||||
def nexusConfigName = envConfig?.nexus ?: "default"
|
||||
params.currentNexusConfig = config.common.nexus[nexusConfigName]
|
||||
|
||||
script.echo "📦 当前环境使用Nexus配置: ${nexusConfigName}"
|
||||
script.echo " - URL: ${params.currentNexusConfig?.url}"
|
||||
script.echo " - 凭证ID: ${params.currentNexusConfig?.credentialsId}"
|
||||
script.echo " - 策略: ${params.currentNexusConfig?.policy}"
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// 添加通知配置
|
||||
// ==========================================================================
|
||||
if (config.common?.notification) {
|
||||
params.notification = config.common.notification
|
||||
script.echo "📧 通知配置已加载"
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// 添加构建策略配置
|
||||
// ==========================================================================
|
||||
if (config.common?.buildStrategy) {
|
||||
params.buildStrategy = config.common.buildStrategy
|
||||
script.echo "⚡ 构建策略:"
|
||||
script.echo " - 重试次数: ${params.buildStrategy.retryCount}"
|
||||
script.echo " - 超时时间: ${params.buildStrategy.timeoutMinutes}分钟"
|
||||
script.echo " - 启用缓存: ${params.buildStrategy.enableCaching}"
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// 添加发布策略配置
|
||||
// ==========================================================================
|
||||
if (config.common?.publishStrategy) {
|
||||
params.publishStrategy = config.common.publishStrategy
|
||||
script.echo "🚀 发布策略:"
|
||||
script.echo " - 版本策略: ${params.publishStrategy.versionPolicy}"
|
||||
script.echo " - 自动发布: ${params.publishStrategy.autoPublish}"
|
||||
script.echo " - 签名构件: ${params.publishStrategy.signArtifacts}"
|
||||
}
|
||||
|
||||
script.echo "环境变量:${config.common?.profiles}"
|
||||
|
||||
// 安全地获取环境配置
|
||||
def envConfig = config.common?.profiles?."${envKey}"
|
||||
script.echo "环境变量:${envConfig}"
|
||||
if (!envConfig) {
|
||||
def availableProfiles = config?.common?.profiles?.keySet() ?: []
|
||||
throw new Exception("未找到 ${envKey} 环境的配置,可用环境: ${availableProfiles.join(', ')}")
|
||||
}
|
||||
|
||||
script.echo "✅ 找到 ${envKey} 环境配置,开始提取参数..."
|
||||
|
||||
// ==========================================================================
|
||||
// 提取环境特定配置
|
||||
// ==========================================================================
|
||||
if (envConfig?.versionSuffix) {
|
||||
params.versionSuffix = envConfig.versionSuffix
|
||||
script.echo "🏷️ 版本后缀: ${envConfig.versionSuffix}"
|
||||
}
|
||||
|
||||
if (envConfig?.autoDeploy != null) {
|
||||
params.autoDeploy = envConfig.autoDeploy
|
||||
script.echo "🚀 自动部署: ${envConfig.autoDeploy}"
|
||||
}
|
||||
|
||||
if (envConfig?.repositoryPolicy) {
|
||||
params.repositoryPolicy = envConfig.repositoryPolicy
|
||||
script.echo "📦 仓库策略: ${envConfig.repositoryPolicy}"
|
||||
}
|
||||
|
||||
script.echo "✅ ${envKey} 环境全部参数获取完成"
|
||||
|
||||
return params
|
||||
} catch (Exception e) {
|
||||
script.echo "❌ 获取环境配置失败: ${e.message}"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Nexus配置信息
|
||||
* 专门用于获取Nexus仓库配置,支持按环境选择不同的Nexus配置
|
||||
*
|
||||
* @param envName 环境名称
|
||||
* @param nexusConfigName Nexus配置名称(可选,默认使用环境配置中的设置)
|
||||
* @return Nexus配置对象
|
||||
*/
|
||||
def getNexusConfig(String envName = null, String nexusConfigName = null) {
|
||||
try {
|
||||
def envKey = (envName ?: params.PROFILES ?: "dev").toLowerCase()
|
||||
def configName = nexusConfigName ?: config.common?.profiles?."${envKey}"?.nexus ?: "default"
|
||||
|
||||
def nexusConfig = config.common?.nexus?."${configName}"
|
||||
if (!nexusConfig) {
|
||||
script.echo "⚠️ 警告: 未找到Nexus配置 '${configName}',使用默认配置"
|
||||
nexusConfig = config.common?.nexus?.default ?: [:]
|
||||
}
|
||||
|
||||
script.echo "🔗 Nexus配置 [${configName}] for ${envKey} 环境:"
|
||||
script.echo " - URL: ${nexusConfig.url}"
|
||||
script.echo " - Snapshots URL: ${nexusConfig.snapshotsUrl}"
|
||||
script.echo " - 凭证ID: ${nexusConfig.credentialsId}"
|
||||
|
||||
return nexusConfig
|
||||
} catch (Exception e) {
|
||||
script.echo "❌ 获取Nexus配置失败: ${e.message}"
|
||||
return [:]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构建策略配置
|
||||
* @return 构建策略配置对象
|
||||
*/
|
||||
def getBuildStrategy() {
|
||||
return config.common?.buildStrategy ?: [:]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发布策略配置
|
||||
* @return 发布策略配置对象
|
||||
*/
|
||||
def getPublishStrategy() {
|
||||
return config.common?.publishStrategy ?: [:]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知配置
|
||||
* @return 通知配置对象
|
||||
*/
|
||||
def getNotificationConfig() {
|
||||
return config.common?.notification ?: [:]
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Jenkins 作业参数
|
||||
* 为标准流水线作业创建环境选择参数和服务器选择参数
|
||||
* 根据可用环境配置动态生成下拉选择框,支持环境和服务器的两级选择
|
||||
*
|
||||
* @param availableProfiles 可用的环境配置列表
|
||||
* - 类型: List<String> 环境名称列表(如:['dev', 'test', 'prod'])
|
||||
* - 来源: 通常从配置文件中解析得到的环境配置键值
|
||||
* - 要求: 列表不能为空,且必须与配置文件中的环境名称匹配
|
||||
*
|
||||
* @note 在多分支流水线中会自动跳过参数设置(因为多分支通常根据分支自动确定环境)
|
||||
* @note 在标准流水线中会创建用户可交互的选择参数
|
||||
*
|
||||
* @example 生成的参数:
|
||||
* - PROFILES: 环境选择下拉框(dev/test/prod)
|
||||
* - SERVERS: 服务器选择下拉框(根据选择的环境动态显示对应服务器)
|
||||
*/
|
||||
private void setupJenkinsParameters(List<String> availableProfiles) {
|
||||
// 检查可用环境列表是否为空
|
||||
if (!availableProfiles || availableProfiles.isEmpty()) {
|
||||
script.echo "⚠️ 可用环境配置列表为空,跳过参数设置"
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前分支名称,用于判断流水线类型
|
||||
def branchName = script.env.BRANCH_NAME ?: ''
|
||||
|
||||
// 判断是否为多分支流水线(分支名通常包含斜杠,如: feature/xxx)
|
||||
boolean isMultibranchPipeline = branchName.contains('/')
|
||||
|
||||
if (isMultibranchPipeline) {
|
||||
script.echo "🔧 检测到多分支流水线,跳过参数设置(分支: ${branchName})"
|
||||
script.echo "💡 多分支流水线通常根据分支名称自动确定目标环境"
|
||||
return
|
||||
}
|
||||
|
||||
script.echo "🔧 标准流水线作业,设置部署环境参数"
|
||||
script.echo "📋 可用环境选项: ${availableProfiles.join(', ')}"
|
||||
|
||||
try {
|
||||
// ==========================================================================
|
||||
// 创建环境选择参数
|
||||
// ==========================================================================
|
||||
def profileParameter = script.choice(
|
||||
choices: availableProfiles.join('\n'), // 下拉选项,每行一个选择项
|
||||
description: '请选择要部署的目标环境', // 参数描述,显示在Jenkins界面上
|
||||
name: 'PROFILES' // 参数名称,后续通过params.PROFILES访问
|
||||
)
|
||||
|
||||
// ==========================================================================
|
||||
// 设置Jenkins作业参数
|
||||
// ==========================================================================
|
||||
script.properties([
|
||||
script.parameters([
|
||||
profileParameter, // 环境选择参数
|
||||
])
|
||||
])
|
||||
|
||||
script.echo "✅ 成功设置部署参数:"
|
||||
script.echo " - PROFILES: 环境选择(${availableProfiles.size()} 个选项)"
|
||||
|
||||
} catch (Exception e) {
|
||||
script.echo "⚠️ 设置 Jenkins 参数失败: ${e.message}"
|
||||
script.echo "💡 这可能是因为没有权限修改作业配置,或者参数格式不正确"
|
||||
// 不抛出异常,避免影响后续流程,参数设置失败通常不会阻断部署
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分支配置获取对应的环境配置文件和默认配置文件
|
||||
* @param branchConfig 分支配置信息,包含分支类型等
|
||||
* @return Map 包含可用配置列表和默认配置
|
||||
*/
|
||||
private def getBranchProfiles(branchConfig) {
|
||||
// 获取当前分支名称
|
||||
def branchName = script.env.BRANCH_NAME ?: ''
|
||||
|
||||
// 1. 优先从常量配置中获取该分支类型对应的可用配置
|
||||
def availableProfiles = ConfigConstants.BRANCH_PROFILES[branchName]
|
||||
|
||||
// 2. 如果常量配置中没有找到,根据分支类型选择不同的默认配置源
|
||||
if (!availableProfiles) {
|
||||
availableProfiles = (branchName == 'master') ?
|
||||
envConfig.masterProfiles : // master分支使用特殊配置
|
||||
envConfig.Profiles // 其他分支使用通用配置
|
||||
}
|
||||
|
||||
// 确保availableProfiles不为null,如果是null则转为空列表
|
||||
availableProfiles = availableProfiles ?: []
|
||||
|
||||
// 3. 获取默认配置,优先从常量配置中获取
|
||||
def defaultProfile = ConfigConstants.DEFAULT_PROFILES[branchName]
|
||||
|
||||
// 4. 如果常量配置中没有默认配置,则从可用配置中选择
|
||||
if (!defaultProfile) {
|
||||
defaultProfile = availableProfiles.find { it } ? // 查找第一个非空配置
|
||||
availableProfiles[0] : // 如果都为空则取第一个
|
||||
null // 如果没有可用配置则返回null
|
||||
}
|
||||
|
||||
return [
|
||||
available_profiles: availableProfiles,
|
||||
default_profile : defaultProfile
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
396
src/com/nexus/stages/BuildService copy.groovy
Normal file
396
src/com/nexus/stages/BuildService copy.groovy
Normal file
@ -0,0 +1,396 @@
|
||||
package com.nexus.stages
|
||||
|
||||
/**
|
||||
* 构建阶段服务 - 负责Maven项目的编译和打包,支持Nexus私库发布
|
||||
*
|
||||
* 主要职责:
|
||||
* - 执行Maven项目的清理、编译、打包、部署操作
|
||||
* - 验证构建环境和配置的有效性
|
||||
* - 处理构建过程中的异常和错误
|
||||
* - 提供构建结果的状态反馈
|
||||
* - 支持Nexus私库发布和依赖管理
|
||||
*
|
||||
* 设计原则:
|
||||
* - 单一职责:专注于Maven构建相关的逻辑
|
||||
* - 可重用性:可以在不同的流水线项目中重用
|
||||
* - 错误隔离:构建失败不会影响其他服务实例
|
||||
* - 配置驱动:通过参数Map接收所有配置信息
|
||||
*
|
||||
* @see Serializable 实现序列化接口,支持Jenkins流水线的暂停和恢复
|
||||
*/
|
||||
class BuildService implements Serializable {
|
||||
|
||||
/**
|
||||
* Jenkins pipeline脚本对象
|
||||
* 用于访问Jenkins DSL方法,如sh、echo、error等
|
||||
* 类型: Object (通常是Jenkins pipeline的script对象)
|
||||
*/
|
||||
def script
|
||||
|
||||
/**
|
||||
* 环境配置信息
|
||||
* 存储构建环境特定的配置参数
|
||||
* 类型: Map<String, Object> 键值对配置映射
|
||||
*/
|
||||
def envConfig
|
||||
|
||||
/**
|
||||
* 构造函数 - 初始化构建服务
|
||||
*
|
||||
* @param script Jenkins pipeline脚本对象(必须)
|
||||
* - 用途:用于在服务中访问Jenkins DSL方法
|
||||
* - 示例:在Pipeline中通过`this`传递当前脚本上下文
|
||||
*
|
||||
* @param envConfig 环境配置信息(可选)
|
||||
* - 类型:Map<String, Object> 键值对配置映射
|
||||
* - 默认值:空Map [:]
|
||||
* - 内容:构建环境相关的配置参数
|
||||
*/
|
||||
BuildService(script, envConfig = [:]) {
|
||||
this.script = script
|
||||
this.envConfig = envConfig
|
||||
|
||||
script.echo "🔧 BuildService 初始化完成"
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行构建阶段逻辑 - 增强版,支持Nexus私库发布
|
||||
* 负责Maven项目的完整构建生命周期,包括清理、编译、测试、打包、部署
|
||||
*
|
||||
* 主要步骤:
|
||||
* 1. 输出构建开始信息和配置详情
|
||||
* 2. 验证环境配置的有效性
|
||||
* 3. 执行Maven构建命令(包含依赖清理和Nexus部署)
|
||||
* 4. 处理构建结果和异常
|
||||
* 5. 生成构建报告
|
||||
*
|
||||
* @param params 管道参数Map,包含构建所需的所有配置信息,必须包含:
|
||||
* - MAVEN_SET: String - Maven设置文件ID(Jenkins Config File ID)
|
||||
* - PROFILES: String - Maven构建环境profiles(如:dev, test, prod)
|
||||
* 可选字段:
|
||||
* - jarFilePath: String - JAR文件输出路径(默认:target)
|
||||
* - jarFile: String - 生成的JAR文件名
|
||||
* - skipTests: Boolean - 是否跳过测试(默认:true)
|
||||
* - goals: String - Maven执行目标
|
||||
* - pomFilePath: String - POM文件路径(默认:pom.xml)
|
||||
* - orgName: String - 组织名称(用于JDK服务验证)
|
||||
* - availableProfiles: List - 可用的环境profile列表
|
||||
* - branchConfig: Map - 分支配置信息
|
||||
* - currentNexusConfig: Map - 当前Nexus配置
|
||||
* - repositoryPolicy: String - 仓库策略
|
||||
* - publishStrategy: Map - 发布策略配置
|
||||
*
|
||||
* @throws Exception 当Maven构建失败时抛出异常,中断流水线
|
||||
* 异常信息包含详细的错误原因和建议解决方案
|
||||
*
|
||||
* @example 使用示例:
|
||||
* def buildParams = [
|
||||
* MAVEN_SET: "nexus-maven-dev",
|
||||
* PROFILES: "dev",
|
||||
* jarFilePath: "target",
|
||||
* jarFile: "xiaomayi-common.jar",
|
||||
* skipTests: true,
|
||||
* orgName: "xiaomayi",
|
||||
* availableProfiles: ["dev", "test", "prod"],
|
||||
* branchConfig: [maven: [deploy: true]],
|
||||
* currentNexusConfig: [url: "http://nexus/repository/maven-snapshots/"],
|
||||
* repositoryPolicy: "snapshots"
|
||||
* ]
|
||||
* buildService.executeBuildStage(buildParams)
|
||||
*/
|
||||
def executeBuildStage(params) {
|
||||
try {
|
||||
// 输出构建开始信息和配置详情
|
||||
script.echo "🏗️ 开始构建阶段..."
|
||||
|
||||
printBuildConfiguration(params)
|
||||
|
||||
// 验证环境profile的有效性(确保配置的一致性)
|
||||
validateProfile(params)
|
||||
|
||||
// 执行Maven构建命令
|
||||
executeMavenBuild(params)
|
||||
|
||||
// 构建成功完成,生成报告
|
||||
generateBuildReport(params)
|
||||
|
||||
} catch (Exception e) {
|
||||
// 构建失败处理
|
||||
handleBuildFailure(e, params)
|
||||
// 重新抛出异常,确保流水线标记为失败状态
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印构建配置详情
|
||||
* 显示所有构建相关的配置信息,便于调试和验证
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def printBuildConfiguration(params) {
|
||||
script.echo "📋 构建配置详情:"
|
||||
script.echo " 🔧 Maven配置: ${params.MAVEN_SET}"
|
||||
script.echo " 🌍 构建Profile: ${params.PROFILES}"
|
||||
script.echo " 📦 输出路径: ${params.jarFilePath ?: 'target'}"
|
||||
script.echo " 🏷️ JAR文件: ${params.jarFile ?: '未指定'}"
|
||||
script.echo " ⚡ 跳过测试: ${params.skipTests ?: true}"
|
||||
script.echo " 📄 POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
|
||||
// 显示Nexus相关配置
|
||||
if (params.currentNexusConfig) {
|
||||
script.echo " 🔗 Nexus仓库: ${params.currentNexusConfig.url}"
|
||||
script.echo " 🎯 仓库策略: ${params.repositoryPolicy ?: 'releases'}"
|
||||
}
|
||||
|
||||
// 显示发布策略
|
||||
if (params.publishStrategy) {
|
||||
script.echo " 🚀 自动发布: ${params.publishStrategy.autoPublish ?: 'false'}"
|
||||
script.echo " 🔏 GPG签名: ${params.publishStrategy.signArtifacts ?: 'false'}"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Maven构建命令
|
||||
* 使用Config File Provider动态加载Maven配置,执行完整的构建生命周期
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def executeMavenBuild(params) {
|
||||
script.echo "🔨 执行Maven构建命令..."
|
||||
|
||||
// 使用Config File Provider加载Maven settings.xml
|
||||
script.configFileProvider([script.configFile(fileId: params.MAVEN_SET, variable: 'MAVEN_SETTINGS_XML')]) {
|
||||
|
||||
// 构建Maven命令参数
|
||||
def mavenGoals = buildMavenGoals(params)
|
||||
def mavenOptions = buildMavenOptions(params)
|
||||
|
||||
script.sh """
|
||||
# ================================================
|
||||
# 小蚂蚁核心库Maven构建脚本
|
||||
# 环境: ${params.PROFILES}
|
||||
# 时间: \$(date)
|
||||
# ================================================
|
||||
|
||||
echo "🚀 开始执行Maven构建..."
|
||||
|
||||
# 显示Maven版本信息
|
||||
/usr/local/maven/bin/mvn --version
|
||||
|
||||
# 显示当前工作目录和POM文件
|
||||
echo "📁 工作目录: \$(pwd)"
|
||||
echo "📄 POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
echo "🔧 Settings文件: \${MAVEN_SETTINGS_XML}"
|
||||
|
||||
# 执行Maven构建命令
|
||||
echo "🔨 执行命令: /usr/local/maven/bin/mvn --settings \${MAVEN_SETTINGS_XML} ${mavenGoals} ${mavenOptions}"
|
||||
|
||||
/usr/local/maven/bin/mvn \\
|
||||
--settings \${MAVEN_SETTINGS_XML} \\
|
||||
-f ${params.pomFilePath ?: 'pom.xml'} \\
|
||||
${mavenGoals} ${mavenOptions}
|
||||
|
||||
# 检查构建结果
|
||||
BUILD_RESULT=\$?
|
||||
if [ \$BUILD_RESULT -eq 0 ]; then
|
||||
echo "✅ Maven构建成功完成!"
|
||||
else
|
||||
echo "❌ Maven构建失败,退出码: \$BUILD_RESULT"
|
||||
exit \$BUILD_RESULT
|
||||
fi
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Maven执行目标
|
||||
* 根据参数配置生成合适的Maven goals
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return Maven goals字符串
|
||||
*/
|
||||
private def buildMavenGoals(params) {
|
||||
def goals = []
|
||||
|
||||
// 添加依赖清理(针对小蚂蚁依赖)
|
||||
goals.add("dependency:purge-local-repository -Dinclude=com.xiaomayi")
|
||||
|
||||
// 添加标准构建生命周期
|
||||
goals.add("clean")
|
||||
|
||||
// 根据分支配置决定是否部署
|
||||
if (params.branchConfig?.maven?.deploy) {
|
||||
goals.add("deploy")
|
||||
script.echo " 🚀 启用部署到Nexus仓库"
|
||||
} else {
|
||||
goals.add("install")
|
||||
script.echo " 💾 仅安装到本地仓库"
|
||||
}
|
||||
|
||||
goals.add("package")
|
||||
|
||||
return goals.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Maven选项参数
|
||||
* 根据配置生成Maven命令行选项
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return Maven选项字符串
|
||||
*/
|
||||
private def buildMavenOptions(params) {
|
||||
def options = []
|
||||
|
||||
// 强制更新依赖
|
||||
options.add("-U")
|
||||
|
||||
// 跳过测试配置
|
||||
if (params.skipTests ?: true) {
|
||||
options.add("-Dmaven.test.skip=true")
|
||||
script.echo " ⚡ 跳过单元测试"
|
||||
} else {
|
||||
script.echo " ✅ 执行单元测试"
|
||||
}
|
||||
|
||||
// 添加Maven profile(如果指定)
|
||||
if (params.PROFILES) {
|
||||
options.add("-P${params.PROFILES}")
|
||||
}
|
||||
|
||||
// 添加分支配置中的额外选项
|
||||
if (params.branchConfig?.maven?.options) {
|
||||
options.add(params.branchConfig.maven.options)
|
||||
}
|
||||
|
||||
return options.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成构建报告
|
||||
* 构建成功后生成详细的构建结果报告
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def generateBuildReport(params) {
|
||||
script.echo "📊 构建阶段完成报告:"
|
||||
script.echo " - ✅ 依赖清理完成(com.xiaomayi)"
|
||||
script.echo " - ✅ 代码编译完成"
|
||||
script.echo " - ${params.skipTests ? '⚡ 单元测试跳过' : '✅ 单元测试通过'}"
|
||||
script.echo " - ✅ 打包完成"
|
||||
|
||||
// 显示部署状态
|
||||
def deployStatus = params.branchConfig?.maven?.deploy ? "已部署到Nexus" : "未部署"
|
||||
script.echo " - 📦 部署状态: ${deployStatus}"
|
||||
|
||||
if (params.branchConfig?.maven?.deploy) {
|
||||
script.echo " 🎯 目标仓库: ${params.currentNexusConfig?.url ?: '默认仓库'}"
|
||||
script.echo " 📋 仓库策略: ${params.repositoryPolicy ?: 'releases'}"
|
||||
}
|
||||
|
||||
// 显示GPG签名状态
|
||||
if (params.publishStrategy?.signArtifacts) {
|
||||
script.echo " - 🔏 GPG签名: 已启用(密钥: ${params.publishStrategy.gpgKeyId ?: '默认密钥'})"
|
||||
}
|
||||
|
||||
// 显示生成的构件信息
|
||||
script.echo "🎉 构建产物已生成到: ${params.jarFilePath ?: 'target'} 目录"
|
||||
|
||||
// 尝试列出生成的JAR文件
|
||||
try {
|
||||
def jarFiles = script.findFiles(glob: "${params.jarFilePath ?: 'target'}/*.jar")
|
||||
if (jarFiles) {
|
||||
script.echo "📦 生成的构件:"
|
||||
jarFiles.each { file ->
|
||||
script.echo " - ${file.name} (${file.length()} bytes)"
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
script.echo " ℹ️ 无法列出构件文件: ${e.message}"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理构建失败情况
|
||||
* 提供详细的错误信息和调试建议
|
||||
*
|
||||
* @param e 异常对象
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def handleBuildFailure(Exception e, params) {
|
||||
script.echo "❌ 构建阶段失败: ${e.message}"
|
||||
script.echo "💡 建议检查:"
|
||||
script.echo " - Maven settings.xml 配置是否正确"
|
||||
script.echo " - Nexus仓库连接是否正常(地址: ${params.currentNexusConfig?.url ?: '未配置'})"
|
||||
script.echo " - 网络连接是否正常(依赖下载)"
|
||||
script.echo " - 代码编译是否有语法错误"
|
||||
script.echo " - 单元测试是否通过"
|
||||
script.echo " - 版本号冲突或依赖问题"
|
||||
|
||||
// 显示当前环境信息用于调试
|
||||
script.echo "🔍 调试信息:"
|
||||
script.echo " - 环境: ${params.PROFILES}"
|
||||
script.echo " - Maven配置: ${params.MAVEN_SET}"
|
||||
script.echo " - POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证环境profile有效性
|
||||
* 检查选择的部署环境是否在可用环境列表中,确保部署配置的正确性
|
||||
*
|
||||
* 主要功能:
|
||||
* - 验证必要参数的存在性和有效性
|
||||
* - 检查所选环境是否在可用环境列表中
|
||||
* - 提供详细的错误信息和调试建议
|
||||
*
|
||||
* @param params 参数Map,必须包含以下字段:
|
||||
* - PROFILES: String - 要验证的环境profile名称
|
||||
* - availableProfiles: List<String> - 可用的环境profile列表
|
||||
* - orgName: String - 组织名称(用于日志和错误消息)
|
||||
*
|
||||
* @throws IllegalArgumentException 当缺少必要参数或参数无效时抛出
|
||||
* @throws Exception 当环境验证失败时抛出,包含详细的错误信息
|
||||
*/
|
||||
private def validateProfile(params) {
|
||||
script.echo "🔍 开始验证环境profile有效性..."
|
||||
|
||||
// 参数完整性检查
|
||||
if (!params.PROFILES) {
|
||||
def errorMsg = "缺少必要的PROFILES参数,请指定要部署的环境"
|
||||
script.echo "❌ ${errorMsg}"
|
||||
throw new IllegalArgumentException(errorMsg)
|
||||
}
|
||||
|
||||
if (!params.availableProfiles || params.availableProfiles.isEmpty()) {
|
||||
def errorMsg = "缺少可用的环境profile列表,请检查配置文件中环境配置"
|
||||
script.echo "❌ ${errorMsg}"
|
||||
throw new IllegalArgumentException(errorMsg)
|
||||
}
|
||||
|
||||
if (!params.orgName) {
|
||||
script.echo "⚠️ 缺少组织名称参数orgName,使用默认标识"
|
||||
}
|
||||
|
||||
// 环境有效性验证
|
||||
try {
|
||||
def selectedProfile = params.PROFILES.trim()
|
||||
def availableProfiles = params.availableProfiles.collect { it.toString().trim() }
|
||||
|
||||
script.echo "📋 验证详情:"
|
||||
script.echo " 🎯 选择的环境: ${selectedProfile}"
|
||||
script.echo " 📊 可用环境: ${availableProfiles.join(', ')}"
|
||||
|
||||
if (!availableProfiles.contains(selectedProfile)) {
|
||||
def errorMsg = "无效的部署环境: '${selectedProfile}'。可用环境: ${availableProfiles.join(', ')}"
|
||||
script.error("环境验证失败: ${errorMsg}")
|
||||
}
|
||||
|
||||
script.echo "✅ 环境profile验证通过: ${selectedProfile}"
|
||||
} catch (Exception e) {
|
||||
script.echo "❌ 环境profile验证过程中发生错误: ${e.message}"
|
||||
script.echo "📋 可用环境列表: ${params.availableProfiles.join(', ')}"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
375
src/com/nexus/stages/BuildService.groovy
Normal file
375
src/com/nexus/stages/BuildService.groovy
Normal file
@ -0,0 +1,375 @@
|
||||
package com.nexus.stages
|
||||
|
||||
/**
|
||||
* 构建服务 - 负责Maven项目的编译、测试、打包和本地安装
|
||||
* 专注于构建生命周期,不包含部署逻辑
|
||||
*
|
||||
* 主要职责:
|
||||
* - 执行Maven项目的清理、编译、测试、打包
|
||||
* - 将构件安装到本地Maven仓库
|
||||
* - 验证构建环境和配置的有效性
|
||||
* - 处理构建过程中的异常和错误
|
||||
* - 提供构建结果的状态反馈
|
||||
*
|
||||
* 设计原则:
|
||||
* - 单一职责:专注于代码构建和本地安装
|
||||
* - 可重用性:可以在不同的流水线项目中重用
|
||||
* - 错误隔离:构建失败不会影响部署服务
|
||||
* - 配置驱动:通过参数Map接收所有配置信息
|
||||
*
|
||||
* @see Serializable 实现序列化接口,支持Jenkins流水线的暂停和恢复
|
||||
*/
|
||||
class BuildService implements Serializable {
|
||||
|
||||
/**
|
||||
* Jenkins pipeline脚本对象
|
||||
*/
|
||||
def script
|
||||
|
||||
/**
|
||||
* 环境配置信息
|
||||
*/
|
||||
def envConfig
|
||||
|
||||
/**
|
||||
* 构造函数 - 初始化构建服务
|
||||
*
|
||||
* @param script Jenkins pipeline脚本对象
|
||||
* @param envConfig 环境配置信息(可选)
|
||||
*/
|
||||
BuildService(script, envConfig = [:]) {
|
||||
this.script = script
|
||||
this.envConfig = envConfig
|
||||
|
||||
script.echo "🔧 BuildService 初始化完成(纯构建版本)"
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行构建阶段逻辑
|
||||
* 负责Maven项目的编译、测试、打包和本地安装
|
||||
*
|
||||
* 主要步骤:
|
||||
* 1. 输出构建开始信息和配置详情
|
||||
* 2. 验证环境配置的有效性
|
||||
* 3. 执行Maven install步骤
|
||||
* 4. 处理构建结果和异常
|
||||
* 5. 生成构建报告
|
||||
*
|
||||
* @param params 管道参数Map,包含构建所需的所有配置信息
|
||||
* @return 构建结果信息,包含构建状态和产物信息
|
||||
* @throws Exception 当Maven构建失败时抛出异常,中断流水线
|
||||
*/
|
||||
def executeBuildStage(params) {
|
||||
def buildResult = [:]
|
||||
|
||||
try {
|
||||
// 输出构建开始信息和配置详情
|
||||
script.echo "🏗️ 开始构建阶段..."
|
||||
printBuildConfiguration(params)
|
||||
|
||||
// 验证环境profile的有效性
|
||||
validateProfile(params)
|
||||
|
||||
// 执行Maven install(构建和本地安装)
|
||||
buildResult = executeMavenInstall(params)
|
||||
|
||||
// 构建成功完成,生成报告
|
||||
generateBuildReport(params, buildResult)
|
||||
|
||||
return buildResult
|
||||
|
||||
} catch (Exception e) {
|
||||
// 构建失败处理
|
||||
handleBuildFailure(e, params)
|
||||
// 重新抛出异常,确保流水线标记为失败状态
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Maven install步骤
|
||||
* 负责代码编译、测试、打包和本地安装
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return 构建结果信息
|
||||
*/
|
||||
private def executeMavenInstall(params) {
|
||||
script.echo "📦 开始执行Maven install步骤..."
|
||||
|
||||
def buildResult = [
|
||||
success: false,
|
||||
artifacts: [],
|
||||
installTime: new Date().format('yyyy-MM-dd HH:mm:ss'),
|
||||
profile: params.PROFILES
|
||||
]
|
||||
|
||||
// 使用Config File Provider加载Maven settings.xml
|
||||
script.configFileProvider([script.configFile(fileId: params.MAVEN_SET, variable: 'MAVEN_SETTINGS_XML')]) {
|
||||
|
||||
def installGoals = buildInstallGoals(params)
|
||||
def installOptions = buildInstallOptions(params)
|
||||
|
||||
def installOutput = script.sh(
|
||||
script: """
|
||||
# ================================================
|
||||
# Maven Install 步骤 - 编译和本地安装
|
||||
# 环境: ${params.PROFILES}
|
||||
# 时间: \$(date)
|
||||
# ================================================
|
||||
|
||||
echo "🚀 开始Maven install操作..."
|
||||
|
||||
# 显示构建信息
|
||||
echo "📁 工作目录: \$(pwd)"
|
||||
echo "📄 POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
echo "🔧 Settings文件: \${MAVEN_SETTINGS_XML}"
|
||||
echo "🎯 操作目标: 本地安装 (install)"
|
||||
|
||||
# 执行install命令
|
||||
echo "🔨 执行命令: /usr/local/maven/bin/mvn --settings \${MAVEN_SETTINGS_XML} ${installGoals} ${installOptions}"
|
||||
|
||||
/usr/local/maven/bin/mvn \\
|
||||
--settings \${MAVEN_SETTINGS_XML} \\
|
||||
-f ${params.pomFilePath ?: 'pom.xml'} \\
|
||||
${installGoals} ${installOptions}
|
||||
""",
|
||||
returnStatus: true
|
||||
)
|
||||
|
||||
// 处理构建结果
|
||||
buildResult.success = (installOutput == 0)
|
||||
buildResult.exitCode = installOutput
|
||||
|
||||
if (buildResult.success) {
|
||||
script.echo "✅ Maven install 成功完成!"
|
||||
|
||||
// 收集生成的构件信息
|
||||
buildResult.artifacts = collectArtifacts(params)
|
||||
buildResult.localRepositoryPath = getLocalRepositoryPath()
|
||||
|
||||
} else {
|
||||
script.echo "❌ Maven install 失败,退出码: ${installOutput}"
|
||||
throw new Exception("Maven构建失败,退出码: ${installOutput}")
|
||||
}
|
||||
}
|
||||
|
||||
return buildResult
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建install步骤的Maven目标
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return Maven goals字符串
|
||||
*/
|
||||
private def buildInstallGoals(params) {
|
||||
def goals = []
|
||||
|
||||
// 添加依赖清理(针对小蚂蚁依赖)
|
||||
goals.add("dependency:purge-local-repository -Dinclude=com.xiaomayi")
|
||||
|
||||
// 添加标准构建生命周期
|
||||
goals.add("clean")
|
||||
goals.add("install") // 本地安装,包含package阶段
|
||||
|
||||
script.echo " 🔧 Install步骤Goals: ${goals.join(' ')}"
|
||||
return goals.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建install步骤的Maven选项
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return Maven选项字符串
|
||||
*/
|
||||
private def buildInstallOptions(params) {
|
||||
def options = []
|
||||
|
||||
// 强制更新依赖
|
||||
options.add("-U")
|
||||
|
||||
// 跳过测试配置
|
||||
if (params.skipTests ?: true) {
|
||||
options.add("-Dmaven.test.skip=true")
|
||||
}
|
||||
|
||||
// 添加Maven profile(如果指定)
|
||||
if (params.PROFILES) {
|
||||
options.add("-P${params.PROFILES}")
|
||||
}
|
||||
|
||||
// 添加分支配置中的额外选项
|
||||
if (params.branchConfig?.maven?.options) {
|
||||
options.add(params.branchConfig.maven.options)
|
||||
}
|
||||
|
||||
script.echo " ⚙️ Install步骤Options: ${options.join(' ')}"
|
||||
return options.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集生成的构件信息
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @return 构件信息列表
|
||||
*/
|
||||
private def collectArtifacts(params) {
|
||||
def artifacts = []
|
||||
|
||||
try {
|
||||
def jarFiles = script.findFiles(glob: "${params.jarFilePath ?: 'target'}/*.jar")
|
||||
jarFiles.each { file ->
|
||||
artifacts.add([
|
||||
name: file.name,
|
||||
path: file.path,
|
||||
size: file.length(),
|
||||
type: file.name.endsWith('-sources.jar') ? 'sources' :
|
||||
file.name.endsWith('-javadoc.jar') ? 'javadoc' : 'main'
|
||||
])
|
||||
}
|
||||
} catch (Exception e) {
|
||||
script.echo "⚠️ 无法收集构件信息: ${e.message}"
|
||||
}
|
||||
|
||||
return artifacts
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地仓库路径(模拟)
|
||||
*
|
||||
* @return 本地仓库路径
|
||||
*/
|
||||
private def getLocalRepositoryPath() {
|
||||
return "~/.m2/repository/com/xiaomayi/"
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印构建配置详情
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def printBuildConfiguration(params) {
|
||||
script.echo "📋 构建配置详情:"
|
||||
script.echo " 🔧 Maven配置: ${params.MAVEN_SET}"
|
||||
script.echo " 🌍 构建Profile: ${params.PROFILES}"
|
||||
script.echo " 📦 输出路径: ${params.jarFilePath ?: 'target'}"
|
||||
script.echo " 🏷️ JAR文件: ${params.jarFile ?: '未指定'}"
|
||||
script.echo " ⚡ 跳过测试: ${params.skipTests ?: true}"
|
||||
script.echo " 📄 POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
script.echo " 🔄 构建模式: 纯构建 (install only)"
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成构建报告
|
||||
*
|
||||
* @param params 构建参数Map
|
||||
* @param buildResult 构建结果
|
||||
*/
|
||||
private def generateBuildReport(params, buildResult) {
|
||||
script.echo "📊 构建阶段完成报告:"
|
||||
script.echo " - ✅ 依赖清理完成(com.xiaomayi)"
|
||||
script.echo " - ✅ 代码编译完成"
|
||||
script.echo " - ${params.skipTests ? '⚡ 单元测试跳过' : '✅ 单元测试通过'}"
|
||||
script.echo " - ✅ 打包完成"
|
||||
script.echo " - ✅ 本地安装完成"
|
||||
|
||||
// 显示生成的构件信息
|
||||
script.echo "🎉 构建产物信息:"
|
||||
script.echo " - 本地路径: ${params.jarFilePath ?: 'target'} 目录"
|
||||
script.echo " - 本地仓库: ${buildResult.localRepositoryPath}"
|
||||
|
||||
if (buildResult.artifacts) {
|
||||
script.echo "📦 生成的构件:"
|
||||
buildResult.artifacts.each { artifact ->
|
||||
script.echo " - ${artifact.name} (${artifact.size} bytes) [${artifact.type}]"
|
||||
}
|
||||
}
|
||||
|
||||
script.echo "⏱️ 构建时间: ${buildResult.installTime}"
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理构建失败情况
|
||||
*
|
||||
* @param e 异常对象
|
||||
* @param params 构建参数Map
|
||||
*/
|
||||
private def handleBuildFailure(Exception e, params) {
|
||||
script.echo "❌ 构建阶段失败: ${e.message}"
|
||||
script.echo "💡 建议检查:"
|
||||
script.echo " - Maven settings.xml 配置是否正确"
|
||||
script.echo " - 网络连接是否正常(依赖下载)"
|
||||
script.echo " - 代码编译是否有语法错误"
|
||||
script.echo " - 单元测试是否通过"
|
||||
script.echo " - 版本号冲突或依赖问题"
|
||||
|
||||
// 显示当前环境信息用于调试
|
||||
script.echo "🔍 调试信息:"
|
||||
script.echo " - 环境: ${params.PROFILES}"
|
||||
script.echo " - Maven配置: ${params.MAVEN_SET}"
|
||||
script.echo " - POM文件: ${params.pomFilePath ?: 'pom.xml'}"
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证环境profile有效性
|
||||
*
|
||||
* @param params 参数Map
|
||||
*/
|
||||
private def validateProfile(params) {
|
||||
script.echo "🔍 开始验证环境profile有效性..."
|
||||
|
||||
// 参数完整性检查
|
||||
if (!params.PROFILES) {
|
||||
def errorMsg = "缺少必要的PROFILES参数,请指定要部署的环境"
|
||||
script.echo "❌ ${errorMsg}"
|
||||
throw new IllegalArgumentException(errorMsg)
|
||||
}
|
||||
|
||||
if (!params.availableProfiles || params.availableProfiles.isEmpty()) {
|
||||
def errorMsg = "缺少可用的环境profile列表,请检查配置文件中环境配置"
|
||||
script.echo "❌ ${errorMsg}"
|
||||
throw new IllegalArgumentException(errorMsg)
|
||||
}
|
||||
|
||||
// 环境有效性验证
|
||||
try {
|
||||
def selectedProfile = params.PROFILES.trim()
|
||||
def availableProfiles = params.availableProfiles.collect { it.toString().trim() }
|
||||
|
||||
script.echo "📋 验证详情:"
|
||||
script.echo " 🎯 选择的环境: ${selectedProfile}"
|
||||
script.echo " 📊 可用环境: ${availableProfiles.join(', ')}"
|
||||
|
||||
if (!availableProfiles.contains(selectedProfile)) {
|
||||
def errorMsg = "无效的部署环境: '${selectedProfile}'。可用环境: ${availableProfiles.join(', ')}"
|
||||
script.error("环境验证失败: ${errorMsg}")
|
||||
}
|
||||
|
||||
script.echo "✅ 环境profile验证通过: ${selectedProfile}"
|
||||
} catch (Exception e) {
|
||||
script.echo "❌ 环境profile验证过程中发生错误: ${e.message}"
|
||||
script.echo "📋 可用环境列表: ${params.availableProfiles.join(', ')}"
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查构建是否成功(公共方法)
|
||||
*
|
||||
* @param buildResult 构建结果
|
||||
* @return boolean 是否成功
|
||||
*/
|
||||
def isBuildSuccessful(buildResult) {
|
||||
return buildResult?.success ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构建产物列表(公共方法)
|
||||
*
|
||||
* @param buildResult 构建结果
|
||||
* @return 构件列表
|
||||
*/
|
||||
def getBuildArtifacts(buildResult) {
|
||||
return buildResult?.artifacts ?: []
|
||||
}
|
||||
}
|
||||
431
src/com/nexus/stages/DeployService.groovy
Normal file
431
src/com/nexus/stages/DeployService.groovy
Normal file
@ -0,0 +1,431 @@
|
||||
package com.nexus.stages
|
||||
|
||||
/**
|
||||
* 部署服务 - 负责将Maven构件部署到Nexus私库
|
||||
* 专注于部署生命周期,依赖于构建服务的输出
|
||||
*
|
||||
* 主要职责:
|
||||
* - 执行Maven deploy步骤,将构件部署到远程仓库
|
||||
* - 验证部署环境和配置的有效性
|
||||
* - 处理GPG签名等安全相关操作
|
||||
* - 提供部署结果的状态反馈
|
||||
* - 支持快照版本和正式版本的发布策略
|
||||
*
|
||||
* 设计原则:
|
||||
* - 单一职责:专注于构件部署和发布
|
||||
* - 依赖注入:依赖于BuildService的输出结果
|
||||
* - 条件执行:根据配置决定是否执行部署
|
||||
* - 错误隔离:部署失败不影响构建结果
|
||||
*
|
||||
* @see Serializable 实现序列化接口,支持Jenkins流水线的暂停和恢复
|
||||
*/
|
||||
class DeployService implements Serializable {
|
||||
|
||||
/**
|
||||
* Jenkins pipeline脚本对象
|
||||
*/
|
||||
def script
|
||||
|
||||
/**
|
||||
* 环境配置信息
|
||||
*/
|
||||
def envConfig
|
||||
|
||||
/**
|
||||
* 构造函数 - 初始化部署服务
|
||||
*
|
||||
* @param script Jenkins pipeline脚本对象
|
||||
* @param envConfig 环境配置信息(可选)
|
||||
*/
|
||||
DeployService(script, envConfig = [:]) {
|
||||
this.script = script
|
||||
this.envConfig = envConfig
|
||||
|
||||
script.echo "🚀 DeployService 初始化完成"
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行部署阶段逻辑
|
||||
* 负责将构建产物部署到Nexus仓库
|
||||
*
|
||||
* 主要步骤:
|
||||
* 1. 验证部署条件和配置
|
||||
* 2. 执行Maven deploy步骤
|
||||
* 3. 处理部署结果和异常
|
||||
* 4. 生成部署报告
|
||||
*
|
||||
* @param params 管道参数Map,包含部署所需的所有配置信息
|
||||
* @param buildResult 构建阶段的结果(可选)
|
||||
* @return 部署结果信息
|
||||
* @throws Exception 当部署失败时抛出异常
|
||||
*/
|
||||
def executeDeployStage(params, buildResult = null) {
|
||||
def deployResult = [:]
|
||||
|
||||
try {
|
||||
// 验证是否应该执行部署
|
||||
if (!shouldExecuteDeploy(params)) {
|
||||
script.echo "⏭️ 跳过部署阶段(部署功能未启用)"
|
||||
return [success: true, skipped: true, reason: "部署功能未启用"]
|
||||
}
|
||||
|
||||
// 输出部署开始信息
|
||||
script.echo "🚀 开始部署阶段..."
|
||||
printDeployConfiguration(params)
|
||||
|
||||
// 验证部署环境
|
||||
validateDeployEnvironment(params)
|
||||
|
||||
// 执行Maven deploy步骤
|
||||
deployResult = executeMavenDeploy(params)
|
||||
|
||||
// 部署成功完成,生成报告
|
||||
generateDeployReport(params, deployResult, buildResult)
|
||||
|
||||
return deployResult
|
||||
|
||||
} catch (Exception e) {
|
||||
// 部署失败处理
|
||||
handleDeployFailure(e, params)
|
||||
// 重新抛出异常,确保流水线标记为失败状态
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Maven deploy步骤
|
||||
* 负责将构件部署到远程Nexus仓库
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return 部署结果信息
|
||||
*/
|
||||
private def executeMavenDeploy(params) {
|
||||
script.echo "📤 开始执行Maven deploy步骤..."
|
||||
|
||||
def deployResult = [
|
||||
success: false,
|
||||
deployedArtifacts: [],
|
||||
deployTime: new Date().format('yyyy-MM-dd HH:mm:ss'),
|
||||
repositoryUrl: params.currentNexusConfig?.url,
|
||||
repositoryPolicy: params.repositoryPolicy
|
||||
]
|
||||
|
||||
// 使用Config File Provider加载Maven settings.xml
|
||||
script.configFileProvider([script.configFile(fileId: params.MAVEN_SET, variable: 'MAVEN_SETTINGS_XML')]) {
|
||||
|
||||
def deployGoals = buildDeployGoals(params)
|
||||
def deployOptions = buildDeployOptions(params)
|
||||
|
||||
def deployOutput = script.sh(
|
||||
script: """
|
||||
# ================================================
|
||||
# Maven Deploy 步骤 - 部署到Nexus仓库
|
||||
# 环境: ${params.PROFILES}
|
||||
# 时间: \$(date)
|
||||
# ================================================
|
||||
|
||||
echo "🚀 开始部署到Nexus仓库..."
|
||||
|
||||
# 显示部署信息
|
||||
echo "🎯 目标仓库: ${params.currentNexusConfig?.url ?: '默认仓库'}"
|
||||
echo "📋 仓库策略: ${params.repositoryPolicy ?: 'releases'}"
|
||||
echo "🔧 Settings文件: \${MAVEN_SETTINGS_XML}"
|
||||
echo "🏷️ 版本后缀: ${params.versionSuffix ?: '无'}"
|
||||
|
||||
# 执行deploy命令
|
||||
echo "🔨 执行命令: /usr/local/maven/bin/mvn --settings \${MAVEN_SETTINGS_XML} ${deployGoals} ${deployOptions}"
|
||||
|
||||
/usr/local/maven/bin/mvn \\
|
||||
--settings \${MAVEN_SETTINGS_XML} \\
|
||||
-f ${params.pomFilePath ?: 'pom.xml'} \\
|
||||
${deployGoals} ${deployOptions}
|
||||
""",
|
||||
returnStatus: true
|
||||
)
|
||||
|
||||
// 处理部署结果
|
||||
deployResult.success = (deployOutput == 0)
|
||||
deployResult.exitCode = deployOutput
|
||||
|
||||
if (deployResult.success) {
|
||||
script.echo "✅ Maven deploy 成功完成!"
|
||||
deployResult.deployedArtifacts = estimateDeployedArtifacts(params)
|
||||
} else {
|
||||
script.echo "❌ Maven deploy 失败,退出码: ${deployOutput}"
|
||||
throw new Exception("Maven部署失败,退出码: ${deployOutput}")
|
||||
}
|
||||
}
|
||||
|
||||
return deployResult
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建deploy步骤的Maven目标
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return Maven goals字符串
|
||||
*/
|
||||
private def buildDeployGoals(params) {
|
||||
def goals = ["deploy"]
|
||||
|
||||
script.echo " 🚀 Deploy步骤Goals: ${goals.join(' ')}"
|
||||
return goals.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建deploy步骤的Maven选项
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return Maven选项字符串
|
||||
*/
|
||||
private def buildDeployOptions(params) {
|
||||
def options = buildCommonMavenOptions(params)
|
||||
|
||||
// deploy特有的选项
|
||||
if (params.publishStrategy?.signArtifacts) {
|
||||
options.add("-Dgpg.sign=true")
|
||||
if (params.publishStrategy.gpgKeyId) {
|
||||
options.add("-Dgpg.keyname=${params.publishStrategy.gpgKeyId}")
|
||||
}
|
||||
script.echo " 🔏 启用GPG签名"
|
||||
}
|
||||
|
||||
script.echo " ⚙️ Deploy步骤Options: ${options.join(' ')}"
|
||||
return options.join(" ")
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建通用的Maven选项
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return Maven选项列表
|
||||
*/
|
||||
private def buildCommonMavenOptions(params) {
|
||||
def options = []
|
||||
|
||||
// 强制更新依赖
|
||||
options.add("-U")
|
||||
|
||||
// 跳过测试配置
|
||||
if (params.skipTests ?: true) {
|
||||
options.add("-Dmaven.test.skip=true")
|
||||
}
|
||||
|
||||
// 添加Maven profile(如果指定)
|
||||
if (params.PROFILES) {
|
||||
options.add("-P${params.PROFILES}")
|
||||
}
|
||||
|
||||
// 添加分支配置中的额外选项
|
||||
if (params.branchConfig?.maven?.options) {
|
||||
options.add(params.branchConfig.maven.options)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否应该执行deploy步骤
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return boolean 是否执行deploy
|
||||
*/
|
||||
private def shouldExecuteDeploy(params) {
|
||||
// 检查分支配置中的deploy设置
|
||||
def branchDeployEnabled = params.branchConfig?.maven?.deploy ?: false
|
||||
|
||||
// 检查环境配置中的autoDeploy设置
|
||||
def envAutoDeploy = params.autoDeploy ?: true
|
||||
|
||||
// 检查发布策略中的autoPublish设置
|
||||
def publishAutoPublish = params.publishStrategy?.autoPublish ?: true
|
||||
|
||||
// 最终决策:所有条件都满足时才执行部署
|
||||
def finalDecision = branchDeployEnabled && envAutoDeploy && publishAutoPublish
|
||||
|
||||
script.echo "📋 部署决策分析:"
|
||||
script.echo " - 分支部署配置: ${branchDeployEnabled}"
|
||||
script.echo " - 环境自动部署: ${envAutoDeploy}"
|
||||
script.echo " - 发布策略自动发布: ${publishAutoPublish}"
|
||||
script.echo " - 最终决策: ${finalDecision ? '执行部署' : '跳过部署'}"
|
||||
|
||||
return finalDecision
|
||||
}
|
||||
|
||||
/**
|
||||
* 估计部署的构件信息
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @return 部署的构件列表
|
||||
*/
|
||||
private def estimateDeployedArtifacts(params) {
|
||||
def artifacts = []
|
||||
|
||||
// 根据常见的Maven项目结构估计部署的构件
|
||||
def baseArtifacts = [
|
||||
[name: "${params.artifactName ?: 'project'}.jar", type: "main"],
|
||||
[name: "${params.artifactName ?: 'project'}-sources.jar", type: "sources"],
|
||||
[name: "${params.artifactName ?: 'project'}-javadoc.jar", type: "javadoc"],
|
||||
[name: "${params.artifactName ?: 'project'}.pom", type: "pom"]
|
||||
]
|
||||
|
||||
baseArtifacts.each { artifact ->
|
||||
artifacts.add([
|
||||
name: artifact.name,
|
||||
type: artifact.type,
|
||||
repository: params.currentNexusConfig?.url,
|
||||
policy: params.repositoryPolicy
|
||||
])
|
||||
}
|
||||
|
||||
return artifacts
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证部署环境
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
*/
|
||||
private def validateDeployEnvironment(params) {
|
||||
script.echo "🔍 验证部署环境配置..."
|
||||
|
||||
// 检查Nexus配置
|
||||
if (!params.currentNexusConfig) {
|
||||
throw new IllegalArgumentException("缺少Nexus仓库配置")
|
||||
}
|
||||
|
||||
if (!params.currentNexusConfig.url) {
|
||||
throw new IllegalArgumentException("Nexus仓库URL未配置")
|
||||
}
|
||||
|
||||
if (!params.currentNexusConfig.credentialsId) {
|
||||
script.echo "⚠️ Nexus仓库凭证未配置,可能使用匿名访问"
|
||||
}
|
||||
|
||||
// 检查仓库策略
|
||||
if (!params.repositoryPolicy) {
|
||||
script.echo "⚠️ 仓库策略未指定,使用默认策略"
|
||||
}
|
||||
|
||||
script.echo "✅ 部署环境验证通过"
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印部署配置详情
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
*/
|
||||
private def printDeployConfiguration(params) {
|
||||
script.echo "📋 部署配置详情:"
|
||||
script.echo " 🔧 Maven配置: ${params.MAVEN_SET}"
|
||||
script.echo " 🌍 部署Profile: ${params.PROFILES}"
|
||||
script.echo " 🔗 Nexus仓库: ${params.currentNexusConfig?.url}"
|
||||
script.echo " 🎯 仓库策略: ${params.repositoryPolicy ?: 'releases'}"
|
||||
script.echo " 🔑 凭证ID: ${params.currentNexusConfig?.credentialsId ?: '未设置'}"
|
||||
|
||||
// 显示发布策略
|
||||
if (params.publishStrategy) {
|
||||
script.echo " 🚀 自动发布: ${params.publishStrategy.autoPublish ?: 'false'}"
|
||||
script.echo " 🔏 GPG签名: ${params.publishStrategy.signArtifacts ?: 'false'}"
|
||||
if (params.publishStrategy.signArtifacts) {
|
||||
script.echo " 🔑 GPG密钥: ${params.publishStrategy.gpgKeyId ?: '默认密钥'}"
|
||||
}
|
||||
script.echo " 📋 版本策略: ${params.publishStrategy.versionPolicy ?: 'semantic'}"
|
||||
}
|
||||
|
||||
script.echo " 🏷️ 版本后缀: ${params.versionSuffix ?: '无'}"
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成部署报告
|
||||
*
|
||||
* @param params 部署参数Map
|
||||
* @param deployResult 部署结果
|
||||
* @param buildResult 构建结果(可选)
|
||||
*/
|
||||
private def generateDeployReport(params, deployResult, buildResult) {
|
||||
script.echo "📊 部署阶段完成报告:"
|
||||
script.echo " - ✅ 构件验证完成"
|
||||
script.echo " - ✅ 仓库连接建立"
|
||||
script.echo " - ✅ 构件上传完成"
|
||||
|
||||
if (params.publishStrategy?.signArtifacts) {
|
||||
script.echo " - 🔏 GPG签名验证完成"
|
||||
}
|
||||
|
||||
script.echo "🎯 部署目标信息:"
|
||||
script.echo " - 🌐 仓库地址: ${deployResult.repositoryUrl}"
|
||||
script.echo " - 📋 仓库策略: ${deployResult.repositoryPolicy}"
|
||||
script.echo " - 🏷️ 版本类型: ${params.versionSuffix ? '快照版本' : '正式版本'}"
|
||||
|
||||
if (deployResult.deployedArtifacts) {
|
||||
script.echo "📦 部署的构件:"
|
||||
deployResult.deployedArtifacts.each { artifact ->
|
||||
script.echo " - ${artifact.name} [${artifact.type}]"
|
||||
}
|
||||
}
|
||||
|
||||
script.echo "⏱️ 部署时间: ${deployResult.deployTime}"
|
||||
|
||||
// 显示与构建结果的关联
|
||||
if (buildResult) {
|
||||
script.echo "🔗 构建-部署关联:"
|
||||
script.echo " - 构建时间: ${buildResult.installTime}"
|
||||
script.echo " - 部署时间: ${deployResult.deployTime}"
|
||||
script.echo " - 总耗时: 计算中..."
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理部署失败情况
|
||||
*
|
||||
* @param e 异常对象
|
||||
* @param params 部署参数Map
|
||||
*/
|
||||
private def handleDeployFailure(Exception e, params) {
|
||||
script.echo "❌ 部署阶段失败: ${e.message}"
|
||||
script.echo "💡 建议检查:"
|
||||
script.echo " - Nexus仓库地址是否正确"
|
||||
script.echo " - 仓库访问权限是否足够"
|
||||
script.echo " - 网络连接是否正常"
|
||||
script.echo " - 版本号是否冲突(重复部署)"
|
||||
script.echo " - GPG签名配置是否正确"
|
||||
|
||||
// 显示当前部署环境信息用于调试
|
||||
script.echo "🔍 调试信息:"
|
||||
script.echo " - 环境: ${params.PROFILES}"
|
||||
script.echo " - Nexus仓库: ${params.currentNexusConfig?.url}"
|
||||
script.echo " - 仓库策略: ${params.repositoryPolicy}"
|
||||
script.echo " - 部署配置: ${params.branchConfig?.maven?.deploy ? '启用' : '禁用'}"
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查部署是否成功(公共方法)
|
||||
*
|
||||
* @param deployResult 部署结果
|
||||
* @return boolean 是否成功
|
||||
*/
|
||||
def isDeploySuccessful(deployResult) {
|
||||
return deployResult?.success ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查部署是否被跳过(公共方法)
|
||||
*
|
||||
* @param deployResult 部署结果
|
||||
* @return boolean 是否被跳过
|
||||
*/
|
||||
def isDeploySkipped(deployResult) {
|
||||
return deployResult?.skipped ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部署的构件信息(公共方法)
|
||||
*
|
||||
* @param deployResult 部署结果
|
||||
* @return 部署的构件列表
|
||||
*/
|
||||
def getDeployedArtifacts(deployResult) {
|
||||
return deployResult?.deployedArtifacts ?: []
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,266 @@
|
||||
// 导入在 Pipeline 中需要使用的共享库类
|
||||
// 这些类通常在 Jenkins 的共享库 (Shared Libraries) 中定义,提供了可重用的功能
|
||||
import com.nexus.ResolverService
|
||||
import com.nexus.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)
|
||||
|
||||
// 记录 '初始化配置' 阶段的成功结束
|
||||
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 "=== 🔨 开始代码构建 ==="
|
||||
// 记录 '构建镜像' 阶段的开始时间
|
||||
stageService.recordStageStart('构建镜像')
|
||||
// 调用部署服务的方法,执行具体的构建逻辑
|
||||
// 该方法内部可能包含:mvn clean compile/test/package、docker build/push 等步骤
|
||||
deploymentService.executeBuildStage(pipelineParams)
|
||||
// 记录 '构建镜像' 阶段的成功结束
|
||||
stageService.recordStageEnd('构建镜像', 'SUCCESS')
|
||||
echo "=== 🔨 完成代码构建 ==="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 第三阶段:应用部署
|
||||
// * 将Docker镜像部署到目标服务器(如测试、预生产、生产环境)。
|
||||
// * 此阶段同样在指定的 Jenkins 代理节点 (jenkinsAgent) 上运行。
|
||||
// */
|
||||
// stage('Deploy') {
|
||||
// // 指定在此阶段使用的 Jenkins 代理节点标签
|
||||
// agent {
|
||||
// label jenkinsAgent
|
||||
// }
|
||||
// steps {
|
||||
// script {
|
||||
// echo "=== 🚀 开始应用部署 ==="
|
||||
// // 记录 '应用部署' 阶段的开始时间
|
||||
// stageService.recordStageStart('应用部署')
|
||||
// // 调用部署服务的方法,执行具体的部署逻辑
|
||||
// // 该方法内部可能包含:通过 SSH 连接到目标服务器、执行部署脚本、更新容器(docker compose/k8s)等
|
||||
// deploymentService.executeDeployStage(pipelineParams)
|
||||
// // 记录 '应用部署' 阶段的成功结束
|
||||
// stageService.recordStageEnd('应用部署', 'SUCCESS')
|
||||
// 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: ["不稳定原因": "测试未通过或存在警告"] // 示例原因
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user