1811872455@163.com hai 2 semanas
pai
achega
8403cd641d
Modificáronse 1 ficheiros con 355 adicións e 0 borrados
  1. 355 0
      Jenkinsfile

+ 355 - 0
Jenkinsfile

@@ -0,0 +1,355 @@
+properties([
+        parameters([
+                [$class: 'ChoiceParameter',
+                 choiceType: 'PT_SINGLE_SELECT',
+                 description: '选择要部署 API or UI',
+                 name: 'modulePrefix',
+                 randomName: 'choice-parameter-5631314439613978',
+                 script: [
+                         $class: 'GroovyScript',
+                         fallbackScript: [
+                                 classpath: [],
+                                 sandbox: true,
+                                 script:
+                                         'return[\'Could not get Env\']'
+                         ],
+                         script: [
+                                 classpath: [],
+                                 sandbox: true,
+                                 script:
+                                         'return["java","ui"]'
+                         ]
+                 ]
+                ],
+                [$class: 'CascadeChoiceParameter',
+                 choiceType: 'PT_SINGLE_SELECT',
+                 description: '选择要部署的项目',
+                 name: 'module',
+                 randomName: 'choice-parameter-5631314456178619',
+                 referencedParameters: 'modulePrefix',
+                 script: [
+                         $class: 'GroovyScript',
+                         fallbackScript: [
+                                 classpath: [],
+                                 sandbox: true,
+                                 script:
+                                         'return[\'Could not get Environment from Env Param\']'
+                         ],
+                         script: [
+                                 classpath: [],
+                                 sandbox: true,
+                                 script:
+                                         ''' if (modulePrefix.equals("java")){
+                                return["storlead-centre-api"]
+                            }
+                            else if(modulePrefix.equals("ui")){
+                                return["sp-user-center"]
+                            }
+                        '''
+                         ]
+                 ]
+                ]
+
+
+        ])
+])
+
+pipeline {
+    options {
+        timestamps()
+    }
+    environment {
+        GROUPID = readMavenPom().getGroupId()//com.storlead
+        ARTIFACTID = readMavenPom().getArtifactId()//sp-project
+        VERSION = readMavenPom().getVersion()//1.0
+    }
+    // 参数
+    parameters {
+        choice(
+                name: 'profile',
+                choices: ['test', 'prod','uat'],
+                description: '选择要部署的配置文件'
+        )
+    }
+    agent any
+    stages {
+        stage('处理参数') {
+            steps {
+                script {
+                    echo "处理参数"
+                    script {
+                        //服务器配置
+                        MODULE_PREFIX = "${params.modulePrefix}"
+                        SERVER_SSH_PORT = 53023
+                        SERVER_HOST = "node1.storlead.com"
+                        SWARM_INIT_REPLICAS_NUM = 1
+
+                        //服务配置
+                        API_PORT = 9200
+                        API_REMOTE_DEBUG_PORT = 9201
+                        API_NAMESPACE_RESTFUL = "${params.module}"
+
+                        //DOCKER配置
+                        DOCKER_REGISTRY = "reg-aliyun"
+                        DOCKER_HOST = "registry.cn-shenzhen.aliyuncs.com"
+                        //Docker私服登陆url https://registry-vpc.cn-shenzhen.aliyuncs.com
+                        DOCKER_LOGIN_REGISTRY = "https://${DOCKER_HOST}"
+
+                        BUILD_PREFIX = "storlead-huawei"
+                        //镜像完整名称 registry-vpc.cn-shenzhen.aliyuncs.com/storlead/sp-project-management-prod:1.0
+                        DOCKER_IMG_NAME = "${DOCKER_HOST}/${BUILD_PREFIX}/${ARTIFACTID}-${params.module}-${params.profile}:${VERSION}"
+                        //镜像名 storlead/sp-project-management-prod:1.0
+                        IMG_NAME = "${BUILD_PREFIX}/${ARTIFACTID}-${params.module}-${params.profile}:${VERSION}"
+
+                        PUSH_DOCK_IMG = true
+                        SERVER_HOST_NAME =  "test1"
+                        echo "为指定 module 设定对应 服务器及端口"
+                        echo "处理 ${params.module} 项目"
+                        if (params.modulePrefix == "java") {
+                            echo "---- storelad-centre-api"
+                            script {
+                                if (params.profile == "test") {
+                                    SWARM_INIT_REPLICAS_NUM = 1
+                                    SERVER_HOST = "test1.storlead.com"
+                                    API_PORT = 10020
+                                    API_REMOTE_DEBUG_PORT = 10021
+                                    SERVER_HOST_NAME =  "test1"
+                                } else if (params.profile == "prod") {
+                                    SERVER_HOST = "110.41.82.21"
+                                    API_PORT = 10020
+                                    API_REMOTE_DEBUG_PORT = 10020
+                                    SERVER_HOST_NAME =  "node1"
+                                }
+                            }
+                        }  else if (params.modulePrefix == "ui") {
+                            script {
+                                if (params.profile == "test") {
+                                    SERVER_HOST = "test1.storlead.com"
+                                } else if (params.profile == "prod") {
+                                    SERVER_HOST = "110.41.82.21"
+                                }
+                            }
+                        }
+
+                        echo "处理MODULE_NAMESPACE_RESTFUL"
+                        //把 module 名 从 sp-xxx 变成 xxx 也就是 项目 的 namespace
+                        if (API_NAMESPACE_RESTFUL == "sp-sales-api") {
+                            API_NAMESPACE_RESTFUL = "sales"
+                        }
+                        echo "处理镜像推送"
+                    }
+                }
+            }
+        }
+
+        stage('Node 编译') {
+
+            when {
+                environment name: 'modulePrefix', value: 'ui'
+            }
+            agent {
+                docker {
+//                      image "registry-vpc.cn-shenzhen.aliyuncs.com/storlead/node:19-alpine"
+                    image "node:20-alpine"
+                    args '-v /app:/app/:z -v /etc/localtime:/etc/localtime:ro -u root'
+                    reuseNode true
+                }
+            }
+            steps {
+                withCredentials([
+                        usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
+                        usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password')
+                ]) {
+                    script {
+                        echo "发布 UI 代码"
+
+                        def remote = [:]
+                        remote.allowAnyHosts = true
+                        remote.name = "${SERVER_HOST}"
+                        remote.host = "${SERVER_HOST}"
+                        remote.port = 53023
+                        remote.user = username
+                        remote.password = password
+
+                        if (params.profile == "prod") {
+                            remote.port = 22
+                            remote.user = "root"
+                            remote.user = usernameHW
+                            remote.password = passwordHW
+                        }
+                        if(params.module == 'sp-user-mobile-center') {
+                           sh """cd ${params.modulePrefix}/${params.module} && npm install  && npm run build:${params.profile}"""
+                        } else {
+                           sh """cd ${params.modulePrefix}/${params.module} && npm install  && npm run ${params.profile}"""
+                        }
+
+//                          sh """cd ${params.modulePrefix}/${params.module}  && npm run ${params.profile}"""
+
+                        sshCommand remote: remote, command: "mkdir -p /app/sp/ui/app-centre/${params.profile}/${params.module}"
+
+                        sshCommand remote: remote, command: "rm -rf /app/sp/ui/app-centre/${params.profile}/${params.module}/dist/*"
+
+
+                        echo "/app/sp/ui/sales/${params.profile}/${params.module}/*"
+
+                        sshPut remote: remote, from: "${params.modulePrefix}/${params.module}/dist/", into: "/app/sp/ui/app-centre/${params.profile}/${params.module}/"
+
+                        echo "${params.modulePrefix}/${params.module}/dist/,/app/sp/ui/app-centre/${params.profile}/${params.module}/"
+
+                        sshCommand remote: remote, command: "cp -rf /app/sp/ui/app-centre/${params.profile}/${params.module}/dist/* /app/sp/ui/app-centre/${params.profile}/${params.module}/"
+                    }
+                }
+            }
+        }
+
+        stage('Maven 编译') {
+            when {
+                environment name: 'modulePrefix', value: 'java'
+            }
+            agent {
+                docker {
+                    image 'maven:3-amazoncorretto-11'
+                    //让docker 使用 host 宿主机的 m2仓库 使用root用户来运行 以让指定的~/.m2/config/setting.xml 阿里加速下载maven 依赖生效
+                    args '-v /app:/app:z -v $HOME/.m2:/root/.m2:z -u root'
+                    reuseNode true
+                }
+            }
+            steps {
+                echo "编译 API 代码"
+                sh "mvn clean package -U -am -pl ${modulePrefix}/${params.module} -P${params.profile} -Dmaven.test.skip=true"
+            }
+        }
+
+        // 项目打包到镜像并推送到镜像仓库
+        stage('构建Docker镜像') {
+            when {
+                environment name: 'modulePrefix', value: 'java'
+            }
+            steps {
+                echo "构建Dcoker镜像-------------------"
+                script {
+                    docker.withRegistry(DOCKER_LOGIN_REGISTRY, DOCKER_REGISTRY) {
+
+                        BASE_IMAGE = 'registry.cn-shenzhen.aliyuncs.com/storlead/openjdk:11'
+                        sh "docker pull ${BASE_IMAGE}"
+
+                        sh """
+                          echo '
+                          FROM ${BASE_IMAGE}
+
+                          COPY ${modulePrefix}/${params.module}/target/${params.module}.jar app.jar
+                          EXPOSE ${API_PORT}
+                          EXPOSE ${API_REMOTE_DEBUG_PORT}
+                          HEALTHCHECK --interval=1m --timeout=10s CMD curl -f http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator
+                          ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-Djava.awt.headless=true","-Dspring.profiles.active=${params.profile}", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${API_REMOTE_DEBUG_PORT}","-jar","/app.jar"]' > Dockerfile
+                          docker build -t ${DOCKER_IMG_NAME} .
+                         """
+                        sh "docker push ${DOCKER_IMG_NAME}"
+                    }
+                }
+            }
+        }
+
+        stage('启动服务') {
+            when {
+                environment name: 'modulePrefix', value: 'java'
+            }
+            steps {
+                withCredentials([
+                        usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
+                        usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password'),
+                        usernamePassword(credentialsId: 'reg-aliyun', usernameVariable: 'aliUsername', passwordVariable: 'aliPassword')
+                ]) {
+                    script {
+
+                        echo "启动服务"
+                        echo "${aliPassword}"
+                        echo "docker login -u ${aliUsername} -p ${aliPassword} ${DOCKER_LOGIN_REGISTRY}"
+
+                        def remote = [:]
+                        remote.name = "${SERVER_HOST}"
+                        remote.host = "${SERVER_HOST}"
+                        remote.port = 53023
+                        remote.user = username
+                        remote.password = password
+                        remote.allowAnyHosts = true
+
+                        //因为使用 docker swarm 发布 只能在 manage node 执行部署
+                        if (params.profile == "prod") {
+                            remote.port = 22
+                            remote.user = "root"
+                            remote.user = usernameHW
+                            remote.password = passwordHW
+                        }
+                        if (PUSH_DOCK_IMG) {
+                            //docker 认证
+                            sshCommand remote: remote, command: "docker login -u ${aliUsername} -p ${aliPassword} ${DOCKER_LOGIN_REGISTRY}"
+                            //如果选择推送才使用远程的版本 如果不选择推送到远程则直接运行本机刚打包的镜像版本即可
+                            sshCommand remote: remote, command: "docker pull ${DOCKER_IMG_NAME}"
+                        }
+                        sh """
+                          echo '
+  version: "3.7"
+  services:
+    ${ARTIFACTID}-${params.module}-${params.profile}:
+      image: ${DOCKER_IMG_NAME}
+      deploy:
+        replicas: ${SWARM_INIT_REPLICAS_NUM}
+        placement:
+          constraints:  
+            - 'node.hostname == ${SERVER_HOST_NAME}'
+        update_config:
+          parallelism: 1
+          delay: 1m
+        restart_policy:
+          condition: on-failure
+          # 最多连续重试3次如果仍然失败则放弃重试
+          max_attempts: 3
+      healthcheck:
+        test: ["CMD", "curl", "-f", "http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator"]
+        interval: 1m
+        timeout: 5s
+        retries: 3
+        start_period: 30s
+      environment:
+        - "TZ=Asia/Shanghai"
+        - "SPRING_PROFILES_ACTIVE=${params.profile}"
+      volumes:
+        - /app:/app
+        - /mnt/vdb/storlead:/mnt/vdb/storlead
+      ports:
+        - "${API_PORT}:${API_PORT}"
+        - "${API_REMOTE_DEBUG_PORT}:${API_REMOTE_DEBUG_PORT}"
+      networks:
+        - vonedao_net
+      extra_hosts:
+        - "www.storlead.com:172.18.194.161"
+        - "node1:110.41.82.21"
+        - "node2:110.41.174.46"
+        - "node3:121.37.226.174"
+        - "test1.storlead.com:172.18.194.168"
+        - "test2.storlead.com:172.18.194.163"
+  networks:
+    vonedao_net:
+       external: true
+                          ' > ${ARTIFACTID}-${params.module}-${params.profile}-stack.yml
+                         """
+                        //                        if (params.profile =="dev") {
+                        //                            sh "docker stack deploy -c ${ARTIFACTID}-${params.profile}-stack.yml ${ARTIFACTID}-${params.profile}"
+
+                        //                            sh "docker ps -f name=${ARTIFACTID} -q | xargs --no-run-if-empty docker container stop"
+                        //                            sh "docker container ls -a -fname=${ARTIFACTID} -q | xargs -r docker container rm"
+                        //                            sh "docker run -d --restart=always -p ${API_PORT}:${API_PORT} -p ${API_REMOTE_DEBUG_PORT}:${API_REMOTE_DEBUG_PORT} -v /app:/app --name ${ARTIFACTID} ${DOCKER_IMG_NAME}"
+                        //                        } else {
+                        // 全部都以swarm 模式启动
+                        sshPut remote: remote, from: "${ARTIFACTID}-${params.module}-${params.profile}-stack.yml", into: "/docker/sp/${ARTIFACTID}-${params.module}-${params.profile}-stack.yml"
+                        sshCommand remote: remote, command: "docker stack deploy --resolve-image=always --with-registry-auth -c /docker/sp/${ARTIFACTID}-${params.module}-${params.profile}-stack.yml ${params.module}-${params.profile}"
+                        //                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+}