[code]//主要用于记录工作流中操作,如从git仓库拉取代码、编译其他项目的job任务、编译docker镜像、推送镜像到仓库、操作json数组、从接口中读取数据等操作。pipeline{ agent { label "${NODE_LABELS}" //jenkins服务器节点,不同操作系统使用 } environment { //该步骤的变量下面操作无法进行修改 PROJECT_API_URL = "..." //获取项目列表api接口地址 UPDATE_DOCKER_API_URL = "..." //更新镜像api接口地址 DOWNLOAD_URL_BASE = "..." //下载程序代码url地址 OPS_GIT_URL = "..." //下载dockerfile的git地址 DOCKER_IMAGE_BASE_URL = '...' //docker镜像仓库地址 DOCKER_CREDENTIALS_ID = '...' //docker授权ID,需在jenkins凭证中进行添加 NEXUS_URL = "..." //制品库地址 NEXUS_CREDENTIALS_ID = '...' //制品库授权ID,需在jenkins凭证中进行添加 } stages{ stage('清空当前工作目录') { steps { script { // 移除当前工作的目录中的所有文件和子目录 sh 'rm -rf ./*' // 输出一个确认信息 echo "当前工作目录已清空" } } } stage('初始化变量') { steps { script { // 声明全局变量,此处变量后续可修改 def frontendProjects = [] def backendProjects = [] env.DOCKERFILE_NAME = 'Dockerfile' env.BUILD_PROJECTS = '[]' env.buildCount = 0 env.buildStaticCount = 0 //使用非凭证方式下载代码,可修改为使用凭证方式 def GIT_CONFIG_USER_NAME = 'git_user' def GIT_CONFIG_USER_PASSWORD = 'git_password' env.STATIC_CONTIG_GIT_URL = "http://$GIT_CONFIG_USER_NAME GIT_CONFIG_USER_PASSWORD@服务器ip:端口号/config.git" } } } stage('登录Docker镜像仓库') { steps { script { //使用凭证ID登录docker withCredentials([usernamePassword(credentialsId: env.DOCKER_CREDENTIALS_ID, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { sh """ docker login $DOCKER_IMAGE_BASE_URL -u "$env.DOCKER_USERNAME" -p "$env.DOCKER_PASSWORD" """ } } } } stage('获取项目列表'){ steps { script { // 从接口获取项目json项目列表,结构为{"project_name":"aa","build_tag":"test_aa_...."} def response = httpRequest url: "${env.PROJECT_API_URL}?id=${upgradeListId}", validResponseCodes: '200:499' // 转换为json数组 def jsonData = readJSON text: response.content // 提取项目列表 frontendProjects = jsonData.data.frontends ?: [] backendProjects = jsonData.data.backends ?: [] } } } stage('从git仓库中获取Dockerfile'){ steps { git url: "${env.OPS_GIT_URL}", branch: "master" } } stage('编译关联的其他job任务') { when { expression { backendProjects.any { it['project_name'] == 'extra_project' } } } steps { script { #从项目列表读取关联job的tag def extraBuildTag = findTagValueFromVariable(backendProjects,'extra_project') // 编译extra_project项目 build job: 'extra_project', parameters: [ string(name: 'Tag', value: extraBuildTag), string(name: 'NODE_LABELS', value: NODE_LABELS) ] } } } stage('处理后端程序包'){ when { expression { backendProjects != null && !backendProjects.isEmpty() && buildBackend == 'true' } } steps { script { backendProjects.each{ project -> script { handleBackendProject(project) env.buildCount = env.buildCount.toInteger() + 1 } } } } } stage('下载前端程序包'){ when { expression { frontendProjects != null && !frontendProjects.isEmpty() && buildFrontend == 'true' } } steps { script { frontendProjects.each{ project -> script { handleFrontendProject(project) env.buildStaticCount = env.buildStaticCount.toInteger() + 1 } } //判断项目是否少于15个,否则返回错误 if( env.buildStaticCount.toInteger() buildProjectArray = buildProjectArray + project } def buiildProjectString = buildProjectArray.join(' ') def buildImageOfflineName = "test-app-${upgradeListId}.jar" sh """ docker save -o $buildImageOfflineName ${buiildProjectString} """ //归档镜像,可在点击项目进行下载 archiveArtifacts artifacts: buildImageOfflineName, fingerprint: true //上传到nexus withCredentials([usernamePassword(credentialsId: env.NEXUS_CREDENTIALS_ID, usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASSWORD')]) { sh """ curl -X POST "${env.NEXUS_URL}/service/rest/v1/components?repository=buildpackage" \ -H "accept: application/json" \ -H "Content-Type: multipart/form-data" \ -F "raw.directory=/build_packages/dockerImages/" \ -F "raw.asset1=@${buildImageOfflineName};type=application/java-archive" \ -F "raw.asset1.filename=${buildImageOfflineName}" \ -u ${NEXUS_USER} {NEXUS_PASSWORD} """ } print("--------------打包离线镜像完成--------------") def downloadImageLink = "${env.NEXUS_URL}/repository/buildpackage/build_packages/dockerImages/${buildImageOfflineName}" echo "--------------下载离线镜像URL: ${downloadImageLink} ----------" } } } stage('删除本地镜像'){ when { expression { env.BUILD_PROJECTS != null && !env.BUILD_PROJECTS.isEmpty() } } steps { script { def buildProjects = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS) buildProjects.each{ project -> print("--------------开始删除本地镜像: ${project}--------------") sh """ docker rmi "${project}" """ } print("--------------删除本地镜像完成--------------") } } } stage('更新记录'){ when { expression { env.BUILD_PROJECTS != null && !env.BUILD_PROJECTS.isEmpty() && updateListDockerImage == 'true' } } steps { script { def dokcerImageUrls = java.net.URLEncoder.encode(env.BUILD_PROJECTS, "UTF-8") // 调用接口更新镜像 def response = httpRequest url: "${env.UPDATE_DOCKER_API_URL}?id=${upgradeListId}&image_urls=${dokcerImageUrls}", validResponseCodes: '200:499' def jsonData = readJSON text: response.content } } } } post { always { outputBuildProjects() } }}// 追加元素到全局列表def appendToList(String element) { def list = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS) list.add(element) env.BUILD_PROJECTS = new groovy.json.JsonBuilder(list).toString()}//输出编译项目列表def outputBuildProjects() { stage('输出编译的镜像列表'){ def buildProjectString = "" def buildProjects = new groovy.json.JsonSlurper().parseText(env.BUILD_PROJECTS) buildProjects.each{ project -> buildProjectString = buildProjectString + "\r\n" + project } print("docker image push list【${buildProjects.size()}个】:") print("${buildProjectString}") }}// 处理前端项目def handleFrontendProject(project) { def projectName = project.project_name print("--------------开始复制前端项目: ${projectName}--------------") dir(projectName) { // 下载构建包 def downloadUrl = "..." try { sh """ //下载项目 mkdir -p ${WORKSPACE}/static && wget -q -O ${WORKSPACE}/static/${projectName}.zip ${downloadUrl} """ } catch (Exception e) { // 捕获异常并在控制台输出错误信息 error "下载项目${projectName}失败: ${e.message}" } }}// 处理后端项目def handleBackendProject(project) { def projectName = project.project_name print("--------------开始后端处理项目: ${projectName}--------------") dir(projectName) { // 下载构建包 def downloadUrl = "..." def dockerBuildDir = "..." // 跳过 if (skipCount.toInteger() > 0 && env.buildCount.toInteger() |