//引用Library需跟jenkins中系统管理-->系统配置-->Global Pipeline Libraries中配置的Library Name一致有效
@Library('jenkinslib')

//function from share Library
def tools = new org.devops.tools()

// 定义钉钉At List  "手机号"
def dingAtuser = []

pipeline {
    agent any
    environment {
        // GIT_URL填入自己项目的SSH Clone路径(Clone with SSH)
        GIT_URL="git@git.zuoshouyisheng.com:risk_predict/report-website.git"
        // GIT_CREDENTIALSID填入自己项目的可访问认证ID，需在Jenkins上配置好
        GIT_CREDENTIALSID="gitlab-ssh-ops"
        // GIT_TOKEN从Jenkins中获取后填入
        GIT_TOKEN="df3256bf54d0713ddb9cc5d2c4155530"
        // harbor仓库地址，一般无需修改
        HARBOR = "harborcore.zuoshouyisheng.com"
        //所属产品线，按需填写，mpm-pri:用药管家相关
        PROJECT = "open-platform"
        //应用服务名称，按需填写
        APP_NAME = "report-interpret-website"
        //副本数，指定各环境节点数
        DEV_REPLICAS=1
        TEST_REPLICAS=1
        PROD_REPLICAS=2
        //NodePort，指定svc NodePort
        DEV_NODEPORT=21074
        TEST_NODEPORT=31074
        PROD_NODEPORT=31074
        // 钉钉机器人ID
        robot_ID = "Jenkins-open-platform"
        // Jenkins 触发原因
        BUILD_CAUSE = "${currentBuild.getBuildCauses()[0].shortDescription}"
        // 服务空间 开发dev 测试test 生产
        SPACE = ""
        DEV_SPACE = "dev-"
        TEST_SPACE = "test-"
        //空不生效?
        //PROD_SPACE = ""
        // 服务所在顶级域名
        // 测试、开发svc.k8s.zuoshouyisheng.com   生产 svc.zsysackonline01.zuoshouyisheng.com
        ROOT_DOMAIN = ""
        DEV_DOMAIN = "svc.k8s.zuoshouyisheng.com"
        TEST_DOMAIN = "svc.k8s.zuoshouyisheng.com"
        PROD_DOMAIN = "svc.zsysackonline01.zuoshouyisheng.com"
       }
       parameters {

           booleanParam(name: 'Checkout', defaultValue: true, description: '是否拉取代码？')
           booleanParam(name: 'Build', defaultValue: true, description: '是否构建镜像？')
           booleanParam(name: 'Deploy', defaultValue: true, description: '是否部署？和Rollout不可同时选择，否则都不执行！！！')
           booleanParam(name: 'Rollout', defaultValue: false, description: '是否需要回滚？和Deploy不可同时选择，否则都不执行！！！')
           choice(name: 'rolloutEnv', choices: ['dev','test','prod'], description: '在需要执行回滚操作时，请确认选择回滚的环境')

           gitParameter name: 'gitlabSourceBranch',
                        type: 'PT_BRANCH_TAG',
                        defaultValue: 'develop',
                        description: '选择将要构建的分支或tag，分支以"origin/"开头，其余为tag',
                        quickFilterEnabled: true,
                        selectedValue: 'TOP',
                        sortMode: 'DESCENDING_SMART',
                        //branchFilter: 'origin/(.*)',
                        tagFilter: '*'


           // choice(name: 'K8S', choices: ['RKE','ACK'], description: '请选择发布或者回滚？')

       }
       options {
            // 表示保留10次构建历史
           buildDiscarder(logRotator(numToKeepStr: '10'))
           // 不允许同时执行流水线，被用来防止同时访问共享资源等
           disableConcurrentBuilds()
           // 设置流水线运行的超时时间, 在此之后，Jenkins将中止流水线
           timeout(time: 10, unit: 'MINUTES')
           // 输出构建的时间信息
           timestamps()
       }
    triggers{
           //捕获gitlab triggerOnPush和triggerOnMergeRequest，正则匹配分支"(pre|dev).*"
           gitlab( triggerOnPush: true,
                   triggerOnMergeRequest: true,
          branchFilterType: "RegexBasedFilter",
                   //sourceBranchRegex: "(develop).*",
                   targetBranchRegex: "(develop|release).*",
                   secretToken: "${env.GIT_TOKEN}")
       }
       stages {
           //代码检出阶段，符合params条件true即执行
           stage('Checkout') {
               when {
                   expression { return params.Checkout }
               }
               steps {
                   script{
                       if(BUILD_CAUSE.matches("((Started by GitLab).*)"))  {
                          branchName = GIT_BRANCH
                          tools.PrintMes("获取的分支代码Gitlab:,${branchName}", "yellow")
                       }else {
                          branchName= gitlabSourceBranch
                          tools.PrintMes("获取的分支代码MANUAL:,${branchName}", "yellow1")
                       }
                       tools.PrintMes("此次构建部署分支为：${branchName}", "green")
                       tools.PrintMes("获取代码", "green1")

                       checkout([$class: 'GitSCM',
                                 branches: [[name: "${branchName}"]],
                                 doGenerateSubmoduleConfigurations: false,
                                 extensions: [],
                                 gitTool: 'Default',
                                 submoduleCfg: [],
                                 userRemoteConfigs: [[credentialsId: "${env.GIT_CREDENTIALSID}", url: "${env.GIT_URL}"]]
                               ])
                       if(gitlabSourceBranch.matches("((origin|develop).*)"))  {
                           build_tag = sh(returnStdout: true,script: 'git rev-parse --short=8 HEAD').trim()
                           tools.PrintMes("获取的分支代码,${build_tag}", "yellow")
                       }else {
                           build_tag = gitlabSourceBranch
                           tools.PrintMes("获取的tag代码代码,${build_tag}", "yellow1")
                       }

                       if(fileExists('.gitmodules') == true) {
                           tools.PrintMes("获取子模块代码", "blue")
                           sh '''
                               git submodule update --init --recursive
                           '''
                       }else {
                           tools.PrintMes("没有子模块", "blue1")
                       }
                   }
               }
           }

           //构建阶段，符合params条件true即执行
           stage('Build') {
               when {
                   expression { return params.Build }
               }
               steps {
                   script{
                       sh "/data/jenkins/tools/node-v16.16.0-linux-x64/bin/pnpm i"
                       if(branchName.matches("(origin/master|master)")){
                           SPACE = ""
                           ROOT_DOMAIN = PROD_DOMAIN
                           sh """
                           /data/jenkins/tools/node-v16.16.0-linux-x64/bin/pnpm run build --mode master
                           """
                       } else if(branchName.matches("(origin/release|release)")){
                           SPACE = TEST_SPACE
                           ROOT_DOMAIN = TEST_DOMAIN
                           sh """
                           /data/jenkins/tools/node-v16.16.0-linux-x64/bin/pnpm run build --mode release
                           """
                       } else if(branchName.matches("(origin/develop|develop)")){
                           SPACE = DEV_SPACE
                           ROOT_DOMAIN = DEV_DOMAIN
                           sh """
                           /data/jenkins/tools/node-v16.16.0-linux-x64/bin/pnpm run build --mode develop
                           """
                       } else {
                           error ("Here haven't current branch!!!")
                       }

                       // 替换nginx配置变量
                       sh """
                       sed -i 's#<SPACE>#${SPACE}#g' devops/default.conf
                       sed -i 's#<PROJECT>#${PROJECT}#g' devops/default.conf
                       sed -i 's#<ROOT_DOMAIN>#${ROOT_DOMAIN}#g' devops/default.conf
                       """

                       sh "docker build  -t ${HARBOR}/${PROJECT}/${APP_NAME}:${build_tag} -f devops/Dockerfile  . "

                       withCredentials([usernamePassword(credentialsId: 'harbor-admin', usernameVariable: 'harborUser', passwordVariable: 'harborPassword')]){
                           sh """
                           docker login -u ${harborUser} -p  ${harborPassword} http://${HARBOR}
                           docker push ${HARBOR}/${PROJECT}/${APP_NAME}:${build_tag}
                           """
                   }
                   }
               }
           }

           //部署阶段，符合params条件true，且Rollout为false即执行
           stage('Deploy') {
               when {

                   allOf {
                       expression { return params.Build }
                       expression { return params.Deploy }
                       not {expression { return params.Rollout }}
                   }
               }
               steps {
                   script{
                       tools.PrintMes("此次部署的tag为:${build_tag}", "blue")
                       sh """
                       sed -i 's#<APP_NAME>#${APP_NAME}#g' ${WORKSPACE}/devops/k8s.yaml
                       sed -i 's#<HARBOR>#${HARBOR}#g' ${WORKSPACE}/devops/k8s.yaml
                       sed -i 's#<PROJECT>#${PROJECT}#g' ${WORKSPACE}/devops/k8s.yaml
                       sed -i 's#<BUILD_ID>#${BUILD_ID}#g' ${WORKSPACE}/devops/k8s.yaml
                       sed -i 's#<BUILD_ID>#${BUILD_ID}#g' ${WORKSPACE}/devops/k8s.yaml
                       sed -i 's#<BUILD_TAG>#${build_tag}#g' ${WORKSPACE}/devops/k8s.yaml
                       """
                       if(branchName.matches("(origin/master|master)")){
                           sh """
                           sed -i 's#<REPLICAS>#${PROD_REPLICAS}#g' ${WORKSPACE}/devops/k8s.yaml
                           sed -i 's#<NODEPORT>#${PROD_NODEPORT}#g' ${WORKSPACE}/devops/k8s.yaml
                           kubectl config use-context 232496941462807308-cb6d4bb23ca0c480fb3117e3abeabb5fe
                           kubectl apply -f ${WORKSPACE}/devops/k8s.yaml --record -n ${PROJECT}
                           """
                       } else if(branchName.matches("(origin/release|release)")){
                           sh """
                           sed -i 's#<NODEPORT>#${TEST_NODEPORT}#g' ${WORKSPACE}/devops/k8s.yaml
                           sed -i 's#<REPLICAS>#${TEST_REPLICAS}#g' ${WORKSPACE}/devops/k8s.yaml
                           kubectl config use-context local
                           kubectl apply -f ${WORKSPACE}/devops/k8s.yaml --record -n test-${PROJECT}
                           """
                       } else if(branchName.matches("(origin/develop|develop)")){
                           sh """
                           sed -i 's#<NODEPORT>#${DEV_NODEPORT}#g' ${WORKSPACE}/devops/k8s.yaml
                           sed -i 's#<REPLICAS>#${DEV_REPLICAS}#g' ${WORKSPACE}/devops/k8s.yaml
                           kubectl config use-context local
                           kubectl apply -f ${WORKSPACE}/devops/k8s.yaml --record -n dev-${PROJECT}
                           """
                       } else {
                           error ("Here haven't current branch!!!")
                       }
                   }
               }
           }
           //回滚阶段，符合params条件true，且Deploy为false即执行
           stage('Rollout') {
               when {
                   allOf {
                       expression { return params.Rollout }
                       not {expression { return params.Deploy }}
                   }
               }
               steps {
                   script{
                       if (env.rolloutEnv == 'dev'){
                           tools.PrintMes("dev环境执行回滚", "red")
                           sh """
                           kubectl config use-context local
                           kubectl rollout undo deployment -n dev-${PROJECT} ${APP_NAME}
                           """
                       } else if  (env.rolloutEnv == 'test') {
                           tools.PrintMes("test环境执行回滚", "red")
                           sh """
                           kubectl config use-context local
                           kubectl rollout undo deployment -n test-${PROJECT} ${APP_NAME}
                           """
                       } else if  (env.rolloutEnv == 'prod') {
                           tools.PrintMes("prod环境执行回滚", "red")
                           sh """
                           kubectl config use-context 232496941462807308-cb6d4bb23ca0c480fb3117e3abeabb5fe
                           kubectl rollout undo deployment -n  ${PROJECT} ${APP_NAME}
                           """
                       }  else {
                           error ("Here haven't current Env!!!")
                       }

                   }
               }
           }
       }
       post {
           always {
             script{
                 tools.PrintMes("always", "green")
             }
           }
           aborted {
               script{
                   tools.PrintMes("aborted", "yellow")
               }
           }
           success {
               script{
                   tools.PrintMes("success", "red")
               }
           }
           failure {
               script{
                   tools.PrintMes("failure", "blue")
               }
           }
       }
   }
