From b4b6389b8887fea264e5ed1faf661e69b6a0823c Mon Sep 17 00:00:00 2001 From: wangdongjun Date: Tue, 6 Jan 2026 16:00:48 +0800 Subject: [PATCH] 1 --- deploy-tools/Dockerfile | 10 ++ deploy-tools/Jenkinsfile | 154 +++++++++++++++++++++++++ deploy-tools/Jenkinsfile.back | 138 ++++++++++++++++++++++ deploy-tools/email-notice-false.html | 77 +++++++++++++ deploy-tools/email-notice-success.html | 77 +++++++++++++ 5 files changed, 456 insertions(+) create mode 100644 deploy-tools/Dockerfile create mode 100644 deploy-tools/Jenkinsfile create mode 100644 deploy-tools/Jenkinsfile.back create mode 100644 deploy-tools/email-notice-false.html create mode 100644 deploy-tools/email-notice-success.html diff --git a/deploy-tools/Dockerfile b/deploy-tools/Dockerfile new file mode 100644 index 0000000..e93e8a7 --- /dev/null +++ b/deploy-tools/Dockerfile @@ -0,0 +1,10 @@ +FROM docker-new.cyweb.top/common/nginx:1.21.6 +VOLUME /tmp + +ARG profile + +ENV LANG en_US.UTF-8 +ADD ./nginx/${profile}.conf /etc/nginx/conf.d/default.conf +ADD ./dist/ /usr/share/nginx/html/ +EXPOSE 80 +EXPOSE 443 diff --git a/deploy-tools/Jenkinsfile b/deploy-tools/Jenkinsfile new file mode 100644 index 0000000..9ae5223 --- /dev/null +++ b/deploy-tools/Jenkinsfile @@ -0,0 +1,154 @@ +node("height_A") { + +// name name path + + def projectKey = "scj-v3-front-2026-1-6" //必须是每个项目唯一的key + + def branch = "${env.BRANCH_NAME}" //当前分支变量 + def toEmail = '493840844@qq.com,374362909@qq.com,278725160@qq.com,1012033624@qq.com' //需要接收邮件提醒的 + def tag = sh(script: "echo `date +%s`", returnStdout: true).trim() //镜像tag + def registryHost = 'docker-new.cyweb.top' //har仓库 + def harBorNamespace = 'project' //镜像存储目录 + def artifactId = '' + def version = '' + def needSonarQube = false //是否开启代码质量检测 + def isSuccess = true + def needNotice = true + def needIgnore = false + def realpathTemp = ""; + def dockerImage = ""; + def credentialsId = ""; + def remoteHost = ""; + def hostPort; + def namespace = ""; + def profile = ""; + + try{ + stage("初始化分支相关信息"){ + switch(branch){ + case 'developer' : + hostPort = 22 + credentialsId = "scj-v3" + remoteHost = "192.168.42.127" + namespace = "scj-v3" + profile = "developer" + break; + case 'master': + hostPort = 22 + credentialsId = "city-zhxy-deploy" + remoteHost = "192.168.41.228" + namespace = "scj-v3" + profile = "deploy" + break; + default: + error('未配置分支!放弃执行') + break; + } + } + + + + + + stage("获取最新代码"){ + withFolderProperties{ + sh 'printenv' + echo "当前分支${branch}" + git branch: "${branch}", credentialsId: 'git-ssh-auth', url: "${env.gitSource}" + } + + } + + + stage("打包编译"){ + nodejs(cacheLocationStrategy: workspace(), configId: 'bdb7fb3a-3aab-44ab-9d19-b55b4ae896ff', nodeJSInstallationName: '18.20') + { + sh 'npm config fix' + sh 'npm cache clean --force' + sh 'npm install --force' +// sh 'npm config fix' + sh 'npm run build' + } + + } + + + stage("docker 操作"){ + if(!needIgnore) + { + withFolderProperties{ + tool name: 'docker: 1.12.6', type: 'dockerTool' + withCredentials([usernamePassword(credentialsId: 'dockerharbor_new', passwordVariable: 'password', usernameVariable: 'username')]) { + echo "登录docker harbor" + sh "docker login ${registryHost} -u ${username} -p ${password} " + dockerImage = "${registryHost}/${harBorNamespace}/${projectKey}/${branch}/${projectKey}-${branch}:${tag} " + echo "镜像名称:"+dockerImage + sh "docker build --build-arg profile=${profile} -t ${dockerImage} -f ${env.WORKSPACE}/deploy-tools/Dockerfile . " + echo "提交镜像" + sh "docker push ${dockerImage} " + //删除本地镜像 防止磁盘漫 + sh "docker rmi ${dockerImage} " + + } + } + }else{ + echo "略过" + } + + } + + stage("更新服务"){ + if(!needIgnore) + { + withFolderProperties{ + echo "开始更新服务" + def remote = [:] + remote.name = "k8s-master-dev" + remote.host = "${remoteHost}" + remote.allowAnyHosts = true + + withCredentials([sshUserPrivateKey(credentialsId: 'root-with-key-ubu-70', keyFileVariable: 'identity', passphraseVariable: '', usernameVariable: 'username')]) { + remote.user = "${username}" + remote.port = hostPort + remote.identityFile = identity + sshCommand remote: remote, command: "source ~/.bash_profile;kubectl set image deployment/front front=${dockerImage} --namespace=${namespace}" + } + } + }else{ + echo "略过" + } + + + } + + + }catch(Exception e){ + isSuccess = false + currentBuild.result = 'FAILURE' + + throw e; //必须跑出异常 否则构建失败结果无法被jenkins捕获 + + }finally{ + + stage("发送邮件通知"){ + if(needNotice) + { +// if(isSuccess) +// { +// emailext body: '${FILE,path="deploy-tools/email-notice-success.html"}', subject: '构建通知:${projectName} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS} 请勿回复', to: "$toEmail" +// +// }else{ +// emailext body: '${FILE,path="deploy-tools/email-notice-false.html"}', subject: '构建通知:${projectName} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS} 请勿回复', to: "$toEmail" +// +// } + } + + } + + + } + + + + +} diff --git a/deploy-tools/Jenkinsfile.back b/deploy-tools/Jenkinsfile.back new file mode 100644 index 0000000..f95ad5a --- /dev/null +++ b/deploy-tools/Jenkinsfile.back @@ -0,0 +1,138 @@ + +node("slave") { + + def project = 'city-zhxy-front' //镜像名称 + def gitSource = 'ssh://git@code.cyweb.top:30033/scj/zhxy-city/backend-front.git' //代码地址 + def toEmail = '493840844@qq.com,374362909@qq.com' //需要接收邮件提醒的 + // def namespace = "fund" //k8snamespaces + + /******* 自定义变量,在jenkins必须对应设置 start *********/ + def namespace = "${namespace}" //k8snamespaces + def branch = "${branch}" //当前分支变量 + def profile = "${profile}" //dev + def remoteHost = "${remoteHost}" //部署服务器的ip + def remoteHostAuth = "${remoteHostAuth}" //部署服务器的凭证 + /******* 自定义变量,在jenkins必须对应设置 end *********/ + + def tag = "jenkins-2021-${env.BUILD_NUMBER}" //镜像tag + + def registryHost = 'docker.registry.cyweb.net:5000' //har仓库 + def harBorNamespace = 'project' //镜像存储目录 + + def artifactId = '' + def version = '' + def needSonarQube = false //是否开启代码质量检测 + def isSuccess = true + + + try{ + stage("获取最新代码"){ + sh 'printenv' + echo "当前分支${branch}" + git branch: "${branch}", credentialsId: 'git-ssh-auth', url: "${gitSource}" + } + + + stage("打包编译"){ + nodejs(cacheLocationStrategy: workspace(), configId: '066d1e6d-2a35-4832-96c1-78970fb7d78b', nodeJSInstallationName: 'node-10.15.1') { + sh 'npm install' + sh 'npm rebuild node-sass' + sh 'npm run build' + } + } + + + if(needSonarQube){ + stage("代码审查"){ + def scannerHome = tool 'sonar-scanner' + withSonarQubeEnv('SonarQuber-Server') { + sh "${scannerHome}/bin/sonar-scanner " + + "-Dsonar.projectKey=${project}-${branch} " + + "-Dsonar.projectName=基金-开发分支 " + + "-Dsonar.sourceEncoding=UTF-8 " + + "-Dsonar.projectVersion=1.0 " + + "-Dsonar.java.binaries=./target/classes " + + "-Dsonar.sources=. "+ + "-Dsonar.exclusions=**/test/**,**/target/**,**/main/resources/**,**/deploy-tools/** "+ + "-Dsonar.java.source=1.8 "+ + "-Dsonar.java.target=1.8" + + // sh "${scannerHome}/bin/sonar-scanner -Dproject.settings=./deploy-tools/sonar-project.properties" + } + sleep(10) + timeout(time: 10, unit: 'MINUTES') { + def qg = waitForQualityGate() + if (qg.status != 'OK') { + echo "代码质量检测不通过" + error "Pipeline aborted due to quality gate failure: ${qg.status}" + }else{ + echo "通过了代码质量检测" + } + } + } + } + + + stage("docker 操作"){ + tool name: 'docker: 1.12.6', type: 'dockerTool' + withCredentials([usernamePassword(credentialsId: '193f70e2-0fc6-43dc-a1c6-c026d0fa3523', passwordVariable: 'password', usernameVariable: 'username')]) { + echo "登录docker harbor" + sh "docker login ${registryHost} -u ${username} -p ${password} " + // sh ' echo ${password} | docker login ${registryHost} -u Wang628625!@# --password-stdin ' + echo "构建镜像" + sh "docker build --build-arg profile=${profile} -t ${registryHost}/${harBorNamespace}/${project}/${project}-${profile}:${tag} -f deploy-tools/Dockerfile . " + echo "提交镜像" + sh "docker push ${registryHost}/${harBorNamespace}/${project}/${project}-${profile}:${tag} " + } + } + + + stage("更新服务"){ + echo "开始更新服务" + def remote = [:] + remote.name = "k8s-master-dev" + remote.host = "${remoteHost}" + remote.allowAnyHosts = true + + + withCredentials([usernamePassword(credentialsId: "${remoteHostAuth}", passwordVariable: 'passowrd', usernameVariable: 'username')]) { + remote.user = "${username}" + remote.password = "${passowrd}" + sshCommand remote: remote, command: 'source ~/.bash_profile' + sshCommand remote: remote, command: "kubectl set image deployment/front front=${registryHost}/${harBorNamespace}/${project}/${project}-${profile}:${tag} --namespace=${namespace}" + + } + } + + + }catch(Exception e){ + isSuccess = false + currentBuild.result = 'FAILURE' + + throw e; //必须跑出异常 否则构建失败结果无法被jenkins捕获 + + }finally{ + + stage("发送邮件通知"){ + if(isSuccess) + { + emailext body: '${FILE,path="deploy-tools/email-notice-success.html"}', subject: '构建通知:{$PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS} 请勿回复', to: "$toEmail" + + }else{ + emailext body: '${FILE,path="deploy-tools/email-notice-false.html"}', subject: '构建通知:{$PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS} 请勿回复', to: "$toEmail" + + } + // echo "clear workspace......" + // deleteDir() + } + + + } + + + + + + + +} diff --git a/deploy-tools/email-notice-false.html b/deploy-tools/email-notice-false.html new file mode 100644 index 0000000..a699f66 --- /dev/null +++ b/deploy-tools/email-notice-false.html @@ -0,0 +1,77 @@ + + + + +${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
(本邮件是程序自动下发的,请勿回复!)

+ 构建结果 - ${BUILD_STATUS} +


+ 构建信息 +
+ +
Changes Since Last + Successful Build: +
+ ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:
%c
",showPaths=true,changesFormat="
[%a]
%m
",pathFormat="    %p"} +
Failed Test Results +
$FAILED_TESTS
+
构建日志 (最后 100行): +
Test Logs (if test has ran): + ${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip +
+
+
+
+ + \ No newline at end of file diff --git a/deploy-tools/email-notice-success.html b/deploy-tools/email-notice-success.html new file mode 100644 index 0000000..36bb1f2 --- /dev/null +++ b/deploy-tools/email-notice-success.html @@ -0,0 +1,77 @@ + + + + +${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
(本邮件是程序自动下发的,请勿回复!)

+ 构建结果 - ${BUILD_STATUS} +


+ 构建信息 +
+ +
Changes Since Last + Successful Build: +
+ ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:
%c
",showPaths=true,changesFormat="
[%a]
%m
",pathFormat="    %p"} +
Failed Test Results +
$FAILED_TESTS
+
构建日志 (最后 100行): +
Test Logs (if test has ran): + ${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip +
+
+
+
+ + \ No newline at end of file