koca_nexus: nexus镜像制作流水线

1、流水线架构介绍

1、首先KDOP流水线会从Git中获取要更新的npm和maven包清单,清单存放地址:http://xxx/KOCA/koca-devops/blob/ci/koca-development-deploy/deploy-list.yaml

文件内容如下:
# ****KOCA开发能力交付内容****
# 填写内容需从公司Nexus上获取
# 程序根据所填内容将去公司Nexus获取对应依赖
deploy:
  # maven依赖交付
  maven:
    # 单包交付
    single:
      - group: szkingdom.yf.component.workflow
        name: null
    # 所有版本交付
    multi:
      - group: szkingdom.yf.component.workflow
        name: null
      - group: szkingdom.yf.component.report
        name: null
      - group: com.oracle
        name: ojdbc7
      - group: szkingdom.yf.koca.dac  
        name: null
      - group: szkingdom.yf.koca.dac.comp   
        name: null
      - group: szkingdom.yf.koca.adapter.parent    
        name: null
      - group: szkingdom.yf.koca.studio    
        name: null
      - group: szkingdom.yf.koca.registry   
        name: null
      - group: szkingdom.yf.koca.plugins    
        name: null
      - group: szkingdom.yf.koca.parent   
        name: null
      - group: szkingdom.yf.koca.gate   
        name: null
      - group: szkingdom.yf.koca.dtc  
        name: null
      - group: szkingdom.yf.koca.dashboard  
        name: null
      - group: szkingdom.yf.koca.dashboard.amo  
        name: null
      - group: szkingdom.yf.koca.core  
        name: null
      - group: szkingdom.yf.koca.config  
        name: null
      - group: szkingdom.yf.koca.base  
        name: null
      - group: szkingdom.yf.koca.admin   
        name: null
      - group: szkingdom.yf.koca.cloud  
        name: null 
      - group: com.szkingdom.koca.admin  
        name: null
      - group: com.szkingdom.koca.amo  
        name: null
      - group: com.szkingdom.koca.base  
        name: null
      - group: com.szkingdom.koca.boot  
        name: null
      - group: com.szkingdom.koca.cloud  
        name: null
      - group: com.szkingdom.koca.dtc   
        name: null
      - group: com.szkingdom.koca.parent  
        name: null
      - group: com.szkingdom.koca.plugins  
        name: null
      - group: com.szkingdom.koca.studio  
        name: null
      - group: com.szkingdom.koca.lcp
        name: null
      - group: kanosaki
        name: epimetheus
      - group: com.github.ralfstuckert.pdfbox-layout
        name: pdfbox2-layout
  # npm仓库依赖交付
  npm:
    # 单包交付
    single:
      - group: null        
        name: '@szkingdom.koca/micro' 
      - group: null
        name: '@szkingdom.koca/icons-vue' 
      - group: null
        name: '@szkingdom.koca/charts' 
      - group: null
        name: '@szkingdom.koca/lowcode-engine'  
    # 所有版本交付
    multi:
      - group: null
        name: szkingdom.yf.koca-cli
      - group: null
        name: szkingdom.yf.koca-template
      - group: null
        name: szkingdom.yf.koca-ui
      - group: null
        name: szkingdom.yf.koca-ui-v3
      - group: null
        name: szkingdom.yf.koca-modules-configuration
      - group: null   
        name: szkingdom.yf.amo-template
      - group: null   
        name: szkingdom.yf.dashboard-template
      - group: null   
        name: szkingdom.yf.micro-template         
      - group: null
        name: szkingdom.yf.admin-backlog   
      - group: null
        name: szkingdom.yf.admin-basic   
      - group: null
        name: szkingdom.yf.admin-business   
      - group: null
        name: szkingdom.yf.admin-biz-log    
      - group: null
        name: szkingdom.yf.admin-common-confirm   
      - group: null
        name: szkingdom.yf.admin-dtc-manager   
      - group: null
        name: szkingdom.yf.admin-file-manage   
      - group: null
        name: szkingdom.yf.admin-jobschedule  
      - group: null
        name: szkingdom.yf.admin-report    
      - group: null
        name: szkingdom.yf.admin-view-module    
      - group: null
        name: szkingdom.yf.admin-workflow   
      - group: null
        name: szkingdom.yf.config-server   
      - group: null
        name: szkingdom.yf.registry-manager   
      - group: null
        name: szkingdom.yf.studio-api-mgt     
      - group: null
        name: szkingdom.yf.admin-app-access   
      - group: null
        name: szkingdom.yf.admin-oem     
      - group: null
        name: szkingdom.yf.studio-basic      
      - group: null
        name: szkingdom.yf.studio-webdesigner   
      - group: null
        name: szkingdom.yf.amo-basic    
      - group: null
        name: szkingdom.yf.amo-logging    
      - group: null
        name: szkingdom.yf.amo-monitor    
      - group: null
        name: szkingdom.yf.amo-operation  
      - group: null
        name: szkingdom.yf.amo-tracing   
      - group: null
        name: szkingdom.yf.amo-alert    
      - group: null
        name: szkingdom.yf.amo-topology   
      - group: null
        name: szkingdom.yf.amo-runtime   
      - group: null
        name: szkingdom.yf.amo-cmp   
      - group: null
        name: szkingdom.yf.studio-standard   
      - group: null
        name: szkingdom.yf.studio-dac   
      - group: null
        name: szkingdom.yf.studio-datasource   
      - group: null
        name: szkingdom.yf.studio-lcrm
      - group: null
        name: szkingdom.yf.admin-message  
      - group: null
        name: szkingdom.yf.admin-document
      - group: null
        name: szkingdom.yf.admin-video-chat
      - group: null
        name: szkingdom.yf.admin-hare
      - group: null
        name:  szkingdom.yf.admin-kgms
      - group: null
        name:  szkingdom.yf.amo-cmdb     
      - group: null
        name:  szkingdom.yf.amo-conf
      - group: null
        name:  szkingdom.yf.amo-prettybi
      - group: null
        name: '@szkingdom.koca/lcp-runtime-model-driven'
      - group: null
        name: '@szkingdom.koca/template'
      - group: null
        name: '@szkingdom.koca/admin-basic'
      - group: null
        name: '@szkingdom.koca/cli'
      - group: null
        name: '@szkingdom.koca/admin-oem'   
      - group: null
        name: '@szkingdom.koca/admin-file-manage'   
      - group: null
        name: '@szkingdom.koca/admin-role-interceptor'    
      - group: null
        name: '@szkingdom.koca/admin-message' 
      - group: null
        name: '@szkingdom.koca/admin-report'
      - group: null
        name: '@szkingdom.koca/admin-workflow'
      - group: null
        name: '@szkingdom.koca/admin-jobschedule'   
      - group: null
        name: '@szkingdom.koca/admin-biz-log'
      - group: null
        name: '@szkingdom.koca/template-base'
      - group: null
        name: '@szkingdom.koca/config-center'
      - group: null
        name: '@szkingdom.koca/amo-monitor'
      - group: null
        name: '@szkingdom.koca/amo-logging'
      - group: null
        name: '@szkingdom.koca/amo-tracing'                
      - group: null
        name: '@szkingdom.koca/amo-alert'
      - group: null
        name: '@szkingdom.koca/amo-topology'
      - group: null
        name: '@szkingdom.koca/amo-operation'
      - group: null
        name: '@szkingdom.koca/amo-runtime'
      - group: null
        name: '@szkingdom.koca/amo-cmp'
      - group: null
        name: '@szkingdom.koca/amo-cmdb'
      - group: null
        name: '@szkingdom.koca/amo-conf'
      - group: null
        name: '@szkingdom.koca/amo-prettybi'
      - group: null
        name: '@szkingdom.koca/config-server'
      - group: null
        name: '@szkingdom.koca/registry-manager'
      - group: null
        name: '@szkingdom.koca/lcp-workflow'
      - group: null
        name: '@szkingdom.koca/lcp-runtime-model'
      - group: null
        name: '@szkingdom.koca/lcp-runtime-api'
      - group: null
        name: '@szkingdom.koca/lcp-runtime-page'
      - group: null
        name: '@szkingdom.koca/lcp-runtime-component'
      - group: null
        name: '@szkingdom.koca/eco-client-sdk'
      - group: null
        name: '@szkingdom.koca/configuration'
      - group: null
        name: '@szkingdom.koca/ui'
      - group: null
        name: '@szkingdom.koca/micro' 
      - group: null
        name: '@szkingdom.koca/icons-vue' 
      - group: null
        name: '@szkingdom.koca/charts' 
      - group: null
        name: '@szkingdom.koca/lowcode-engine'       
        


2、获取到清单地址后可以选择依赖是同步到云端仓库还是NEXUS临时仓库?
云端仓库:是直接对用户的,用户可以直接连接
NEXUS临时仓库:在金证内网,会把NEXUS临时仓库制作成docker镜像,推送到云端FTP,供用户下载安装使用

2、流水线总体执行流程介绍

1、首先是从gitlab中获取需要同步的依赖清单,依赖清单文件分为如下几个字段,因为依赖推送比较花时间,所以要支持包的全量推送及指定包推送。参考deploy-list.yaml文件
deploy.maven.single: 用来向仓库推送指定的几个包
deploy.maven.multi: 全量的maven包
deploy.npm.single: 同上
deploy.npm.multi:同上

2、选择是否同步到目标仓库,这里的目标仓库是指金证内网的临时仓库
3、是否把目标仓库制作成nexus镜像
4、是否把镜像上传到云端FTP
5、是否从源仓库把依赖同步到云端仓库

3、流水线参数介绍


全量:表所推送所有的maven及Npm包(deploy.maven.multi和deploy.npm. multi)
参考deploy-list.yaml文件
全量maven: deploy.maven.multi
全量npm:deploy.npm. multi
单包maven: deploy.maven.single
单包npm: deploy.npm.single

import hudson.model.*;
import groovy.json.JsonSlurperClassic

// 功能清单对象
class DeployList {
    // maven交付
    def mavenList
    // npm交付
    def npmList
}

def deployList
// 加载清单文件
def loadDeployList(String filePath, String synchronize_type) {
    def delpoyList = new DeployList()
    def data = readYaml file: "$filePath"

    if(synchronize_type == "全量") {
        delpoyList.mavenList = data.deploy.maven.multi
        delpoyList.npmList = data.deploy.npm.multi
    } else if (synchronize_type == "全量npm") {
        delpoyList.npmList = data.deploy.npm.multi
    } else if (synchronize_type == "全量maven") {
        delpoyList.mavenList = data.deploy.maven.multi
    } else if (synchronize_type == "单包npm") {
        delpoyList.npmList = data.deploy.npm.single
    } else if (synchronize_type == "单包maven") {
        delpoyList.mavenList = data.deploy.maven.single
    }

    return delpoyList
}

/**
 * git克隆
 * remoteAddr:仓库地址 如:http://xxx/KOCA/koca-devops.git
 * branch:git分支 如:refs/heads/develop
 * credentialsId:git用户凭证
 * dirName:git克隆在dirName目录下
 */ 
def gitClone(String remoteAddr, String branch, String credentialsId,String dirName) {
    dir(dirName){
        checkout([$class: 'GitSCM',
            branches: [[name: (branch)]], doGenerateSubmoduleConfigurations: false, 
            extensions: [], submoduleCfg: [], 
            userRemoteConfigs: [[credentialsId: (credentialsId), url: (remoteAddr)]]])
    }
}

/**
 * 连接npm仓库
 * npmUrl: npm仓库url 如:http://ip4:8081/repository/koca-npm/
 * userName: 用户名
 * passWord: 密码  
 */ 
def loginNexus(String npmUrl, String userName, String passWord){
sh """
#!/bin/bash
npm config set registry ${npmUrl}
expect <<EOF
    set timeout 10
    spawn npm login ${npmUrl}
    expect {
        "Username: " { 
            send "${userName}\r"; 
            exp_continue 
        }
        "Password: " { 
            send "${passWord}\r"; 
            exp_continue 
        }
        "Email: (this IS public) " {
            send "koca@szkingdom.com\r"; 
            exp_continue 
        }
    }
EOF
"""
}

//deploy到目标仓库
def deployPom(String jarName, String targetNexus, String mavenSettings) {
    if (jarName == 'null' || !jarName) {
        return
    }

    def strs = jarName.split('/')
    def strLen = strs.size()

    def groupID = ''
    for (int i = 0; i < strLen - 4; i++) {
        groupID += strs[i] + '.'
    }
    groupID += strs[(strLen - 4)]
    def artifactID = strs[(strLen - 3)]
    def version = strs[(strLen - 2)]
    def filename = strs[(strLen - 1)]

    def packagePom = sh(returnStatus: true, script: " grep '<packaging>pom</packaging>' $filename ")

    if (packagePom != 0 ) {
        def jarFile = filename.replaceAll('.pom', '.jar')
        sh """
            mvn deploy:deploy-file -s=$mavenSettings  -DpomFile=$filename -Dfile=$jarFile -Durl=$targetNexus -DrepositoryId=releases
            rm -f $filename $jarFile
        """
        return
    }

    sh """
        mvn deploy:deploy-file -s=$mavenSettings  -DgroupId=$groupID -DartifactId=$artifactID -Dversion=$version \
            -Dpackaging=pom -Dfile=$filename -Durl=$targetNexus -DrepositoryId=releases
        rm -f $filename
    """
}

//deploy source.jar到目标仓库
def deployJar(String jarName, String targetNexus, String mavenSettings) {
    if (jarName == 'null' || !jarName) {
        return
    }

    def strs = jarName.split('/')
    def strLen = strs.size()

    def groupID = ''
    for (int i = 0; i < strLen - 4; i++) {
        groupID += strs[i] + '.'
    }
    groupID += strs[(strLen - 4)]
    def artifactID = strs[(strLen - 3)]
    def version = strs[(strLen - 2)]
    def filename = strs[(strLen - 1)]
    sh """
        mvn deploy:deploy-file -s=$mavenSettings  -DgroupId=$groupID -DartifactId=$artifactID -Dversion=$version \
            -Dpackaging=jar -Dclassifier=sources -Dfile=$filename -Durl=$targetNexus -DrepositoryId=releases
        rm -f $filename
    """
}

/**
 * 获取仓库依赖包
 * 比如szkingdom.yf.koca-template包,需要多次调用此接口,每次调用会返回一个token,当token为null的说明包全部获取完了
 * sourceUrl:仓库地址 如:'http://ip5:8081'
 * token:每次调用返回的token
 * group: maven的gorup
 * name: 依赖包名 如:szkingdom.yf.koca-template
 * userName:仓库用户名
 * passWord:仓库密码
 */ 
def getPackageData(String sourceUrl, String token, String group,String name, String userName, String passWord) {
    def tokenSearch = 'continuationToken=' + token + '&'
    def groupSearch = 'group=' + group + '&'
    def nameSearch = 'name=' + name + '&'
    def requestUrl = ''
    def queryData = ''

    // v3: 注意特殊字符转义问题@=%40 /=2F%
    // curl -u 'userName:passWord' -X GET 'http://ip5:8081/service/rest/v1/search/assets?name="%40"szkingdom.koca"%2F"admin-basic' -H 'accept: application/json'

    if (token == null) {
        tokenSearch = ''
    }

    if (group == 'null' || !group) {
        groupSearch = ''
    }

    if (name == 'null' || !name) {
        nameSearch = ''
    }

    nameSearch = nameSearch.replace('@', '"%40"').replace('/', '"%2F"')

    requestUrl = sourceUrl + '/service/rest/v1/search/assets?' + tokenSearch + groupSearch + nameSearch

    queryData = sh(returnStdout: true, script: """ curl -u $userName:$passWord -X GET '$requestUrl' -H "accept: application/json" """)

    return queryData
}

/**
 * 获取仓库依赖包列表
 * sourceUrl:仓库地址 如:'http://ip5:8081'
 * group:maven的group
 * name: 依赖包名 如:szkingdom.yf.koca-template
 * userName:仓库用户名
 * passWord:仓库密码
 */ 
def getPackageDataList(String sourceUrl,String group,String name, String userName, String passWord) {
    def queryData = getPackageData(sourceUrl, null,group, name, userName, passWord)
    if ( -1 == queryData.indexOf('items') ) {
        return null
    }

    def json = new JsonSlurperClassic().parseText(queryData)
    def result = json.items
    def token = json.continuationToken

    while ( token != null) {
        queryData = getPackageData(sourceUrl, token, group, name, userName, passWord)
        try {
            json = new JsonSlurperClassic().parseText(queryData)
        } catch (Exception ex) {
            println("getValidUrlNew异常:$sourceUrl,$group,$name,$userName,$passWord");
        } finally {
            result.addAll(json.items)
            token = json.continuationToken
        }

    }

    return result
}

/**
 * 对比源仓库与目标仓库包名与CheckSum
 * srcDownloadUrl:源仓库包下载连接
 * resultsnew:目标仓库包列表
 */
def isHave(String srcDownloadUrl, def resultsnew) {
    // 获取源仓库包名:如szkingdom.yf.koca-template-1.0.0.tgz
    def srcPackageName = srcDownloadUrl.subSequence(srcDownloadUrl.lastIndexOf('/') + 1, srcDownloadUrl.length())
    println('源仓库:' + srcPackageName)

    def find = false
    for (asset in resultsnew) {
        // 获取目标仓库DownloadUrl:如"downloadUrl" : "http://ip5:8081/repository/npm-hosted/szkingdom.yf.koca-template/-/szkingdom.yf.koca-template-3.3.1.tgz"
        def targetDownloadUrl = asset.downloadUrl
        // 获取目标仓库包名:如szkingdom.yf.koca-template-1.0.0.tgz
        def targetDownloadUrlName = targetDownloadUrl.subSequence(targetDownloadUrl.lastIndexOf('/') + 1, targetDownloadUrl.length())

        // 对比包是否已经存在,比较包名与checksum
        if (srcPackageName == targetDownloadUrlName) {
            println(targetDownloadUrlName + '已经存在,不用更新')
            find = true
            break
        } 
    }

    return find
}

/**
 * 发布Npm依赖到仓库
 * path 如:"path" : "szkingdom.yf.koca-template/-/szkingdom.yf.koca-template-3.3.1.tgz",
 * npmSourceUrl: 源npm仓库地址
 * npmTargetUrl: 目标npm仓库地址
 */
def publishTgz(String path, String npmSourceUrl, String npmTargetUrl) {
    if (path == 'null' || !path) {
        return
    }

    def strs = path.split('/')
    def strLen = strs.size()
    def filename = strs[(strLen - 1)]
    def targetName = filename[0..-5]

    try {
        sh """
            #!/bin/bash
            mkdir -p $targetName
            tar -zxf $filename -C $targetName
            if [ ! -f "$targetName/package/package.json" ];then
                echo "$targetName/package/package.json文件不存在"
            else
                sed -i 's#$npmSourceUrl#$npmTargetUrl#g' $targetName/package/package.json
                cd $targetName/package
                npm publish
                cd -
            fi
        """
    } catch (Exception ex) {
        println("publishT $targetName faild");
    } finally {
        sh """
            rm -rf $targetName
        """
    } 
}

/**
 * wget --user=user '--password=pass' http://ip5:8081/repository/npm-hosted/@szkingdom.koca/lcp-runtime-model-driven/-/lcp-runtime-model-driven-0.14.0.tgz
 * url: npm包downloadUrl
 * userName: 仓库的用户名
 * passWord: 仓库的密码
 */
def wgetNexus(String url, String userName, String passWord) {
    sh "wget --user=$userName --password=$passWord $url"
}

/**
 * 同步npm  
   每个package格式:
   {
    "downloadUrl" : "http://ip5:8081/repository/npm-hosted/szkingdom.yf.koca-template/-/szkingdom.yf.koca-template-3.3.1.tgz",
    "path" : "szkingdom.yf.koca-template/-/szkingdom.yf.koca-template-3.3.1.tgz",
    "id" : "bnBtLWhvc3RlZDplOTk5OTRmZDIxYTcyM2MwMDFmZTJiODYzMjc0MWUxOA",
    "repository" : "npm-hosted",
    "format" : "npm",
    "checksum" : {
      "sha1" : "a98336f5064aecc916116afc218fa4c7fad83a79"
    }
  }
 */
def npmSynchronize(
    String nexusSource,             // 源仓库地址:http://ip:port
    String npmSourceUrl,            // 源仓库npm地址:http://ip:port/repository/npm-hosted
    String sourceUserName,          // 源仓库用户名
    String sourcePassword,          // 源仓库密码
    String nexusTarget,             // 目标仓库地址:http://ip:port  
    String npmTargetUrl,            // 目标仓库Npm地址
    String targetUserName,          // 目标仓库用户名  
    String targetPassword,          // 目标仓库密码
    def deployList) {               // 同步的包列表
    for(npm in deployList.npmList) {
        println("npm name:$npm.name")
        // 获取源仓库指定包的npm包的集合,集合中包含了所有的版本
        def results = getPackageDataList(nexusSource, npm.group ,npm.name,sourceUserName,sourcePassword)
        // 获取目标仓库指定包的npm包的集合,集合中包含了所有的版本
        def resultsnew = getPackageDataList(nexusTarget, npm.group ,npm.name,targetUserName,targetPassword)
        for (asset in results) {
            def downloadUrl = asset.downloadUrl
            def path = asset.path
            def format = asset.format
            
            // 对其它格式文件进行过滤
            if (format != 'npm' || downloadUrl.indexOf('unknown') != -1 || downloadUrl.contains('snapshot') || downloadUrl.contains('beta')|| downloadUrl.contains('alpha')) {
                continue
            }

            if (downloadUrl ==~ /^.*-\d*\.tgz$/) {
                continue
            }

            if (downloadUrl.endsWith('.tgz') ) {
                // 在这里进行对比,看是否需要更新
                if(isHave(downloadUrl, resultsnew)) {
                    continue
                }
                // 从源仓库下载需要更新的包
                wgetNexus(downloadUrl,sourceUserName,sourcePassword)
                // 同步包到目标仓库
                publishTgz(path, npmSourceUrl, npmTargetUrl)
            }
        }
    }
}

// 同步maven
def mavenSynchronize(
    String nexusSource,             // 源仓库地址:http://ip:port
    String sourceUserName,          // 源仓库用户名
    String sourcePassword,          // 源仓库密码
    String nexusTarget,             // 目标仓库地址:http://ip:port 
    String mavenTargetUrl,           // 目标maven地址 
    String targetUserName,          // 目标仓库用户名  
    String targetPassword,          // 目标仓库密码
    String mavenSettings,           // maven settings文件路径
    def deployList,                 // 同步的包列表
    def synchronizeSourcejar        // 是否同步sourceJar
) {
    for(maven in deployList.mavenList) {
         def results = getPackageDataList(nexusSource, maven.group ,maven.name,sourceUserName,sourcePassword)
        // 获取目标仓库指定包的npm包的集合,集合中包含了所有的版本
        def resultsnew = getPackageDataList(nexusTarget, maven.group ,maven.name,targetUserName,targetPassword)
        for (asset in results){
            def downloadUrl = asset.downloadUrl
            def path = asset.path
            def format = asset.format
            if (downloadUrl.indexOf('SNAPSHOT') != -1  || downloadUrl.indexOf('unknown') != -1 || downloadUrl.contains("amo-app")) {
                continue
            }

            if (format != 'maven2') {
                continue
            } 

            if ((downloadUrl.endsWith('.jar') && !downloadUrl.endsWith('javadoc.jar')) || downloadUrl.endsWith('.pom')){
                // 在这里进行对比,看是否需要更新
                if(isHave(downloadUrl, resultsnew)) {
                    continue
                }
                wgetNexus(downloadUrl,sourceUserName,sourcePassword)
                if (downloadUrl. endsWith('pom')) {
                    deployPom(path, mavenTargetUrl, mavenSettings)
                }else if (downloadUrl.endsWith('sources.jar') && synchronizeSourcejar == true) {
                    deployJar(path, mavenTargetUrl, mavenSettings)
                }
            }
        }
    }
}

pipeline{

    // 添加节点
    agent{

        node{
            label 'Nodeip4'
        }
    }

    parameters{
        string (defaultValue: '4.1.0', description: '1.1发布版本号', name: 'koca_version')
        booleanParam (defaultValue: true, description: '1.2制品同步到目标仓库', name: 'nexus_synchronize')
        booleanParam (defaultValue: true, description: '1.3目标仓库制作nexus镜像', name: 'make_package')
        booleanParam (defaultValue: true, description: '1.4nexus镜像推送到ftp', name: 'push_ftp')
        booleanParam (defaultValue: true, description: '2同步云端Maven', name: 'synchronize_cloudy')
        choice(description: '选择同步类型',name: 'synchronize_type',choices: ['全量','全量npm','全量maven','单包npm','单包maven'])
        booleanParam (defaultValue: false, description: '是否同步source.jar', name: 'synchronize_sourcejar')
    }

    environment{
        NEXUS_VERSION = 'sonatype/nexus3:3.26.0'
        // 源仓库地址
        nexusSource = 'http://ip5:8081';
        // 源仓库npm地址
        npmSourceUrl = 'http://ip5:8081/repository/npm-hosted/'
        // 源仓库用户名
        sourceUserName = 'user'
        // 源仓库密码
        sourcePassword = 'password'
    }

    stages{

        stage('获取同步清单'){

            environment{
                defaultEnv = 'ci'
            }

            steps{

                script{

                    // 克隆koca-deveops ci分支到本地
                    gitClone('http://xxx/KOCA/koca-devops.git',"refs/heads/${defaultEnv}",'git-user','koca-devops')
                    // 读取deploy-list.yaml中要升级的清单列表
                    dir("koca-devops/koca-development-deploy"){
                        deployList = loadDeployList("deploy-list.yaml",params.synchronize_type)
                    }
                }
            }
        }

        stage('制品同步到目标仓库'){

            environment{
                // 目标仓库maven配置
                mavenSettings = '/home/koca-nexus-base/maven-settings.xml';
                // 目标仓库地址
                nexusTarget = 'http://ip4:8081';
                // 目标仓库maven hosted
                mavenTargetUrl = 'http://ip4:8081/repository/koca-maven/';
                // 目标仓库npm hosted
                npmTargetUrl = 'http://ip4:8081/repository/koca-npm/';
                // 目标仓库用户名
                targetUserName = 'user'
                // 目标仓库密码
                targetPassword = 'password'
            }

            when{

                expression{
                    return params.nexus_synchronize
                }
            }

            steps{

                script{

                    dir('koca-dependences'){
                        // 登录目标仓库
                        loginNexus(npmTargetUrl,targetUserName,targetPassword)
                        npmSynchronize(nexusSource,npmSourceUrl,sourceUserName,sourcePassword,nexusTarget,npmTargetUrl,targetUserName,targetPassword,deployList)
                        // 同步maven
                        mavenSynchronize(nexusSource,sourceUserName,sourcePassword,nexusTarget,mavenTargetUrl,targetUserName,targetPassword,mavenSettings,deployList,"${synchronize_sourcejar}")
                    }
                }
            }
        }

        stage('目标仓库制作nexus镜像'){

            when{

                expression{
                    return params.make_package
                }
            }

            steps{

                script{
                    sh """
                    cd /home/nexus
                    docker build . -f DeployDockerfile -t koca-nexus3:$koca_version                   
                    rm -rf ./jenkins/KOCA_NEXUS_PACKAGE/koca_nexus/registry/*.tar.gz
                    docker save koca-nexus3:$koca_version -o ./jenkins/KOCA_NEXUS_PACKAGE/koca_nexus/registry/koca-nexus3-${koca_version}.tar.gz
                    rm -rf ./jenkins/KOCA_NEXUS_V*
                    mkdir -p ./jenkins/KOCA_NEXUS_V${koca_version}
                    cd ./jenkins/KOCA_NEXUS_PACKAGE
                    tar -czf - koca_nexus | split -b 400m -d - /home/jenkins/KOCA_NEXUS_V${koca_version}/koca_nexus_${koca_version}.tar.gz
                    """
                }
            }
        }

        stage('nexus镜像推送到ftp'){

            when{

                expression{
                    return params.push_ftp
                }
            }

            steps{

                script{
                    sh """
                    /usr/bin/sshpass -p password scp -r -P 22 /home/koca-nexus-base/KOCA_NEXUS_V${koca_version} ip4:/data/yfzx/KOCA
                    /usr/bin/sshpass -p password scp -r -P 22 /home/koca-nexus-base/KOCA_NEXUS_V${koca_version} ip2:/data/yfzx/KOCA
                    """
                }
            }
        }

        stage('同步云端Maven'){

            when{

                expression{
                    return params.synchronize_cloudy
                }
            }

            environment{
                // 云端仓库maven配置
                cloudMavenSettings = '/home/koca-nexus-base/maven-cloud-settings.xml';
                // 云端仓库地址
                cloudNexusTarget = 'http://ip1';
                // 云端仓库maven hosted
                cloudMavenTargetUrl = 'http://ip1/repository/koca-maven/';
                // 云端仓库npm hosted
                cloudNpmTargetUrl = 'http://ip1/repository/koca-npm/';
                // 云端仓库用户名
                cloudTargetUserName = 'user'
                // 云端仓库密码
                cloudTargetPassword = 'password'
            }

            steps{

                script{

                    dir('koca-dependences'){
                        // 登录云端仓库
                        loginNexus(cloudNpmTargetUrl,cloudTargetUserName,cloudTargetPassword)
                        // 同步npm
                        npmSynchronize(nexusSource,npmSourceUrl,sourceUserName,sourcePassword,cloudNexusTarget,cloudNpmTargetUrl,cloudTargetUserName,cloudTargetPassword,deployList)
                        // 同步maven
                        mavenSynchronize(nexusSource,sourceUserName,sourcePassword,cloudNexusTarget,cloudMavenTargetUrl,cloudTargetUserName,cloudTargetPassword,cloudMavenSettings,deployList,"${synchronize_sourcejar}")
                    }
                }
            }
        }
    }
}

4、环境准备

  • 在节点服务器如:ip安装nexus
docker pull sonatype/nexus3:3.26.0
创建目录:/home/nexus/koca-nexus-base && chmod 777 /home/nexus/koca-nexus-base
启动容器:docker run -d --restart=always --privileged=true -p 8081:8081 -v /home/nexus/koca-nexus-base:/nexus-data sonatype/nexus3:3.26.0
访问nexus: http://ip:8081
重置admin用户密码:假如是:KOCA_admin123456
cd /home/nexus
创建dockerfile:DeployDockerfile,内容如下:
FROM sonatype/nexus3:3.26.0
USER root
COPY ./koca-nexus-base /nexus-data
RUN  chmod 777 /nexus-data
RUN rm -rf /nexus-data/lock
  • maven配置
<?xml version="1.0" encoding="UTF-8"?>


<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
 
  <servers>
    <server>  
      <id>koca</id>  
      <username>admin</username>  
      <password>KOCA_admin123456</password>  
    </server>  
  </servers>

   <mirrors>
    <mirror>
      <id>koca</id>
      <mirrorOf>*</mirrorOf>
      <url>http://ip:8081/repository/maven-public/</url>
    </mirror>
  </mirrors>
<profiles>

    <profile> 
      <id>koca-cd</id> 
      <repositories> 
        <repository> 
        <id>koca</id> 
        <url>http://ip:8081/repository/maven-public/</url> 
        <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases> 
        <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots> 
      </repository> 
      </repositories> 
      <pluginRepositories> 
        <pluginRepository> 
        <id>koca</id> 
        <url>http://ip:8081/repository/maven-public/</url> 
        <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases> 
        <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots> 
        </pluginRepository> 
      </pluginRepositories> 
    </profile>     
  </profiles>

  <activeProfiles>
        <activeProfile>koca-cd</activeProfile>
  </activeProfiles>
  
</settings>
  • docker安装包与手册
cd /home/nexus
mkdir jenkins/KOCA_NEXUS_PACKAGE/koca_nexus/registry,具体包内容可以解压之前的交付件进行获取