1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| pipeline { parameters { choice choices: ['app1', 'app2'], description: '选择发布程序', name: 'APP_NAME' } options { buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '5')) } environment { PROJECT = '项目名' BRANCH_NAME = '环境名(分支名)' HARBOR_NAMESPACE = 'docker仓库凭据名称' GIT_ID = 'git凭据名称' GIT_URL = "https://git.xxx.com/${APP_NAME}.git(git的url)" REGISTRY = '镜像仓库地址' KUBECONFIG_ID = 'kubeconfig id' KUBERNETES_APP_REPLICAS = 'deployment副本数' KUBERNETES_DEPLOYMENT_ID = 'global-kubernetes-deployment' DOCKER_DOCKERFILE_ID = 'global-dockerfile-file' SW_OAP = 'skywalking OPA地址' }
agent { kubernetes { inheritFrom 'mypod' } } stages { stage('拉取代码') { steps { git(credentialsId: "${GIT_ID}", url: "$GIT_URL", branch: "${BRANCH_NAME}", changelog: true, poll: false) } post { failure { echo "❌ 代码拉取失败" sendNotification("拉取代码", "❌失败") } } } stage('编译打包') { steps { sh 'mvn clean package install -Dmaven.test.skip=true -DarchetypeCatalog=local' } post { failure { echo "❌ 打包失败" sendNotification("maven打包", "❌失败") } } } stage('镜像制作') { steps { container('docker') { // 创建 Dockerfile 文件,但只能在方法块内使用 configFileProvider([configFile(fileId: "${DOCKER_DOCKERFILE_ID}", targetLocation: "dockerfile")]){ script { // 设置 Docker 镜像名称 def dockerImageName = "${REGISTRY}/${PROJECT}/${APP_NAME}:1.${BUILD_NUMBER}" // 替换dockerfile文件中的变量 def dockerfile = readFile encoding: "UTF-8", file: "dockerfile" def dockerfile = dockerfile.replaceAll("#APP_NAME","${APP_NAME}") .replaceAll("#PROJECT","${PROJECT}") .replaceAll("#SW_OAP","${SW_OAP}") // 生成新的 dockerfile 部署文件 writeFile encoding: 'UTF-8', file: './Dockerfile', text: "${dockerfile}" // sh "cat ./Dockerfile" // 提供 Docker 环境,使用 Docker 工具来进行 Docker 镜像构建与推送 docker.withRegistry("http://${REGISTRY}", "${HARBOR_NAMESPACE}") { def customImage = docker.build("${dockerImageName}") customImage.push() } } } } } post { failure { echo "❌ 镜像制作" sendNotification("镜像制作", "❌失败") } } } stage('更新版本') { steps { // 使用 Kubectl Cli 插件的方法,提供 Kubeconfig withKubeConfig([credentialsId: "${KUBECONFIG_ID}"]) { // 读取 Kubernetes 部署文件 configFileProvider([configFile(fileId: "${KUBERNETES_DEPLOYMENT_ID}", targetLocation: "deployment.yaml")]){ script { // 替换deployment文件中的变量 def deploy = readFile encoding: "UTF-8", file: "deployment.yaml" def deployfile = deploy.replaceAll("#APP_NAME","${APP_NAME}") .replaceAll("#APP_REPLICAS","${KUBERNETES_APP_REPLICAS}") .replaceAll("#APP_IMAGE_NAME","${dockerImageName}") // 生成新的 Kubernetes 部署文件 writeFile encoding: 'UTF-8', file: './deploy.yaml', text: "${deployfile}" // sh "cat deploy.yaml" // 执行 Kuberctl 命令进行部署操作 sh "kubectl apply -n ${PROJECT} -f deploy.yaml" } } } } post { failure { echo "❌ 更新版本失败" sendNotification("更新版本", "❌失败") } } } } post { success { lark ( robot: "${ROBOT_ID}", type: "CARD", title: "📢 ${PROJECT} ${APP_NAME} 构建成功通知 ", text: [ "📋 **任务名称**:[${JOB_NAME}](${JOB_URL})", "🔢 **任务编号**:[${BUILD_DISPLAY_NAME}](${BUILD_URL})", "🌟 **构建状态**: <font color='green'>成功</font>", "🕐 **构建用时**: ${currentBuild.duration / 1000} 秒", "📜 **更新内容**: $changeString", "<at id=all></at>" ], buttons: [ [ title: "更改记录", url: "${BUILD_URL}changes" ], [ title: "控制台", type: "danger", url: "${BUILD_URL}console" ] ] ) } } }
def sendNotification(String stageName, String status) { lark( robot: "${ROBOT_ID}", type: "CARD", title: "❌ ${PROJECT} ${APP_NAME} ${stageName}失败通知", text: [ "📌 **阶段**: ${stageName}", "🔢 **状态**: <font color='red'>${status}</font>", "<at id=all></at>" ] ) }
@NonCPS def getChangeString() { MAX_MSG_LEN = 100 def changeString = ""
echo "Gathering SCM changes" def changeLogSets = currentBuild.changeSets for (int i = 0; i < changeLogSets.size(); i++) { def entries = changeLogSets[i].items for (int j = 0; j < entries.length; j++) { def entry = entries[j] truncated_msg = entry.msg.take(MAX_MSG_LEN) changeString += " - ${truncated_msg} [${entry.author}]\n" } } if (!changeString) { changeString = " - No new changes" } return changeString }
|