pipeline { agent any parameters { string(name: 'PROJECT_VERSION', defaultValue: '3.8.0', description: '构建版本') string(name: 'PROJECT_KEY', defaultValue: 'ruoyi', description: '项目唯一标识') string(name: 'NEXUS_JAVA_URL', defaultValue: 'ruoyi-maven', description: '后端制品仓库') string(name: 'NEXUS_DIST_URL', defaultValue: 'ruoyi-dist', description: '前端制品仓库') string(name: 'DOCKER_JAVA_IMAGE_NAME', defaultValue: 'library/ruoyi-backend', description: 'Docker后端镜像名称') string(name: 'DOCKER_DIST_IMAGE_NAME', defaultValue: 'library/ruoyi-fronted', description: 'Docker前端镜像名称') string(name: 'DOCKER_REGISTRY_URL', defaultValue: '10.36.176.174', description: 'Docker 镜像仓库地址') } environment { NEXUS_CREDENTIALS_ID = 'jenkins_nexus' GROUP_ID = 'com.ruoyi' ARTIFACT_ID = 'ruoyi' SONARQUBE_ENV = 'sonarqube' } stages { stage('后端打包') { steps { withDockerContainer(image: 'maven:3.8.8-sapmachine-11') { sh """ mvn package """ } } } stage('前端打包') { steps { withDockerContainer(image: 'node:18.20.3-alpine3.20') { sh """ cd ruoyi-ui npm install --cache .npm --registry http://registry.npmmirror.com npm run build:prod """ } } } stage('代码扫描') { steps { withCredentials([string(credentialsId: 'sonarqube-token-id', variable: 'SONAR_TOKEN')]) { withSonarQubeEnv("${env.SONARQUBE_ENV}") { // 使用配置的 SonarQube 安装名称 withDockerContainer(image: 'sonarsource/sonar-scanner-cli') { sh """ sonar-scanner \ -Dsonar.userHome=./cache \ -Dsonar.projectKey=${params.PROJECT_KEY} \ -Dsonar.projectName=${params.PROJECT_KEY} \ -Dsonar.projectVersion=${params.PROJECT_VERSION} \ -Dsonar.sources=. \ -Dsonar.host.url=http://10.36.176.174:19000 \ -Dsonar.login=${SONAR_TOKEN} \ -Dsonar.java.binaries=. """ } } } } } stage('质量检查') { steps { script { // 增加超时设置,防止无限等待 timeout(time: 30, unit: 'MINUTES') { def qg = waitForQualityGate() // 打印质量门的详细信息以便调试 echo "Quality Gate status: ${qg.status}" echo "Quality Gate details: ${qg}" if (qg.status != 'OK') { error "代码扫描异常,质量门未通过: ${qg.status}" } } } } } stage('后端推送制品库') { steps { withCredentials([usernamePassword(credentialsId: "${env.NEXUS_CREDENTIALS_ID}", usernameVariable: 'NEXUS_USERNAME', passwordVariable: 'NEXUS_PASSWORD')]) { withDockerContainer(args: '-v /root/.m2:/root/.m2', image: 'maven:3.8.8-sapmachine-11') { sh """ mvn deploy:deploy-file \ -DgroupId=${env.GROUP_ID} \ -DartifactId=${env.ARTIFACT_ID} \ -Dversion=${params.PROJECT_VERSION} \ -Dpackaging=jar \ -Dfile=ruoyi-admin/target/ruoyi-admin.jar \ -DrepositoryId=nexus \ -Durl=http://${NEXUS_USERNAME}:${NEXUS_PASSWORD}@10.36.176.174:8081/repository/${params.NEXUS_JAVA_URL}/ """ } } } } stage('前端推送制品库') { steps { // 使用curl命令将构建的HTML文件上传到Nexus script { // 上传zip文件到Nexus withCredentials([usernamePassword(credentialsId: env.NEXUS_CREDENTIALS_ID, passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { sh """ cd ruoyi-ui zip -r build.zip dist curl -v -u $NEXUS_USERNAME:$NEXUS_PASSWORD --upload-file build.zip http://10.36.176.174:8081/repository/${params.NEXUS_DIST_URL}/build-${params.PROJECT_VERSION}.zip """ } } } } stage('后端镜像构建和推送') { steps { script { withCredentials([usernamePassword(credentialsId: 'jenkins-docker', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { def imageName = "${params.DOCKER_REGISTRY_URL}/${params.DOCKER_JAVA_IMAGE_NAME}:${params.PROJECT_VERSION}" sh """ docker build -t ${imageName} -f Dockerfile-java . echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin ${params.DOCKER_REGISTRY_URL} docker push ${imageName} docker logout ${params.DOCKER_REGISTRY_URL} """ } } } } stage('前端镜像构建和推送') { steps { script { withCredentials([usernamePassword(credentialsId: 'jenkins-docker', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { def imageName = "${params.DOCKER_REGISTRY_URL}/${params.DOCKER_DIST_IMAGE_NAME}:${params.PROJECT_VERSION}" sh """ docker build -t ${imageName} -f Dockerfile-nginx . echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin ${params.DOCKER_REGISTRY_URL} docker push ${imageName} docker logout ${params.DOCKER_REGISTRY_URL} """ } } } } } post { // always { // cleanWs() // } success { emailext( subject: '项目 【$PROJECT_NAME】 第【$BUILD_NUMBER】次构建 - SUCCESS!', body: ''' ${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志

本邮件由系统自动发出,请勿回复!


各位同事,大家好,以下为${PROJECT_NAME}项目构建信息
构建结果 - ${BUILD_STATUS}

构建信息

最近提交


    ${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="
  • %d [%a] %m
  • "}
详细提交: ${PROJECT_URL}changes
''', to: '1161733918@qq.com', attachLog: true ) } failure { emailext( subject: '项目 【$PROJECT_NAME】 第【$BUILD_NUMBER】次构建 - FAILURE!', body: ''' ${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志

本邮件由系统自动发出,请勿回复!


各位同事,以下为${PROJECT_NAME}项目构建信息
构建结果 - ${BUILD_STATUS}

构建信息

最近提交


    ${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="
  • %d [%a] %m
  • "}
详细提交: ${PROJECT_URL}changes
''', to: '1161733918@qq.com', attachLog: true ) } } }