Jenkins迁移之pipeline共享库怎么使用

2023-05-13,

这篇文章主要介绍“Jenkins迁移之pipeline共享库怎么使用”,在日常操作中,相信很多人在Jenkins迁移之pipeline共享库怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Jenkins迁移之pipeline共享库怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    背景

    我们一直使用的 jenkins 服务还是 2.0 以下不支持 pipeline 的版本。平时创建任务多数使用 maven 项目,构建后的 shell 部署命令都是在各个 job 中独立维护。这种方式的缺点就是:
    1.脚本维护麻烦 (环境对应的服务器变更,构建入参更新等等状况);
    2.不利于后期功能扩展 (例如 java 服务想接入覆盖率服务);
    3.不利于 jenkins 项目迁移 (例如磁盘不足等原因)。
    刚好上述原因都遇到了,所以计划迁移到新的 Jenkins 服务中,所有 job 都通过 pipeline 来管理。在使用 pipelin 之后的感觉用 2 个字来形容:真香

    顺便感谢一下大佬,但是不知道他的 id,所以直接贴一下他的gitee 共享库项目地址

    我的共享库项目中缝合了大佬很多代码,写的太好了,忍不住借鉴一下

    初期需求

    迁移之初,参考了网上很多的 pipeline 使用教程。首先肯定不想在每个项目中,维护大量的 Jenkinsfile 文件 (万一需要修改,那不是得改到吐,虽然也可以用 git 项目来统一管理 jenkinsfile),最终采用了 Multibranch Pipeline with defaults(多分支流水线) + Pipeline: Multibranch with defaults 插件的方式,通过维护简单的 default jenkinfile 文件来实现 pipeline 的使用。第二个考虑的问题就是,后期对脚本的维护和扩展希望尽可能的简单,这自然就想到 pipeline 共享库的使用。

    成果展示

    先展示下目前的成果:

    1.创建 job

    这里是说在 Jenkins 中配置简单,其实还有一些信息配置的,是保存在文件或者数据库中

    2.job 参数配置

    default jenkinsfile 文件的维护 (仅仅负责调用共享库,所有的实现均在共享库项目中完成) 

    共享库

    共享库结构

    ├─resources
    │ app.json
    │ base.json
    │ host_info.json
    ├─src
    │ │
    │ └─com
    │ │ common_util.groovy
    │ │ exec_shell.groovy
    │ │ Log.groovy
    │ │
    │ ├─beans
    │ │ AppJobInfo.groovy
    │ │ HostInfo.groovy
    │ │ JavaJobInfo.groovy
    │ │ JobInfo.groovy
    │ │
    │ ├─build
    │ │ androidBuild.groovy
    │ │ build.groovy
    │ │ gradleBuild.groovy
    │ │ mavenBuild.groovy
    │ │ npmBuild.groovy
    │ │ yarnBuild.groovy
    │ │
    │ ├─deploy
    │ │ deploy.groovy
    │ │
    │ ├─enums
    │ │ BuildType.groovy
    │ │ PipelineType.groovy
    │ │ ToolsType.groovy
    │ │
    │ ├─qikqiak
    │ │ GlobalVars.groovy
    │ │
    │ └─services
    │ JacocoHandle.groovy
    └─vars
    defaultPipeline.groovy
    initParamsStage.groovy
    loadPipeline.groovy
    testPipeline.groovy
    unknownPipeline.groovy

    入口代码: loadPipeline.groovy

    def call(PipelineType pipelineType) {
        JobInfo jobInfo = creatJobInfo()
        switch (pipelineType) {
            case PipelineType.DefaultPipeline:
                defaultPipeline jobInfo
                break
            case PipelineType.TestPipeline:
                testPipeline jobInfo
                break
            default:
                unknownPipeline null
                break
        }
    }

    参数使用 jobInfo 对象管理

    /**
    针对不同类型的项目,使用不同的jobInfo:JavaJobInfo/AppJobinfo
    */
    class JobInfo {
        /**
         * 页面入参
         */
        String jobName
        String env
        BuildType buildType
        String branchName
        JobInfo(Map map){
            this.jobName = map.job_name
            this.env = map.env
            this.buildType = BuildType.getBuildTypeByKey(map.buildType)
            this.branchName = map.branchName
        }
        /**
         * 配置参数
         */
        //通用字段
        String groupName
        ToolsType toolsType
        Map<String, String> envMap
        def setConfigParams(Map map){
            this.groupName = map.groupName
            this.toolsType = com.enums.ToolsType.getToolsTypeByKey(map.toolsType)
            this.envMap = map.env_map
        }
        def getEnvKeyList(){
            return this.envMap.keySet().toList()
        }
        def getHost(){
            return this.envMap.get(this.env)
        }
        //默认项
        /**
         * 是否为自动构建
         */
        boolean isAutoBuild = false
        /**
         * 自动构建时,默认构建的环境:加入构建指令需要环境参数时
         */
        String defaultEnv = "test"
        /**
         * 默认构建方式:仅构建
         */
        BuildType defaultBuildType = BuildType.BUILD
        @NonCPS
        def setAutoBuildParams(){
            this.env = defaultEnv
            this.buildType = defaultBuildType
        }
        @Override
        @NonCPS
        public String toString() {
            return "JobInfo{" +
                    "jobName='" + jobName + '\'' +
                    ", env='" + env + '\'' +
                    ", buildType=" + buildType +
                    ", branchName='" + branchName + '\'' +
                    ", groupName='" + groupName + '\'' +
                    ", toolsType=" + toolsType +
                    ", envMap=" + envMap +
                    ", isAutoBuild=" + isAutoBuild +
                    ", defaultEnv='" + defaultEnv + '\'' +
                    ", defaultBuildType=" + defaultBuildType +
                    '}';
        }
    }

    pipeline 结构:defaultPipeline.groovy

    动态参数:initParamsStage.groovy

    stage("init params step"){
            script{
                log.info("start init params...")
                /**
                 * 先根据构建工具,来构建不同的构建参数
                 * 后期如果同一个构建工具,针对不同的job,入参类型不同,那么在根据job处理
                 */
                switch (jobInfo.toolsType){
                    case ToolsType.MVN:
                        properties([
                                parameters([
                                        choice(name:'env', choices:env_list, description:'选择构建环境'),
                                        booleanParam(defaultValue:false, name: 'isCollectCoverage',description: '是否启用jacoco收集代码覆盖率'),
                                        choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
                                                description:'选择部署方式:编译并部署、仅编译、仅部署')
                                ])
                        ])
                        break
                    case ToolsType.GRADLE:
                        if(jobInfo instanceof AppJobInfo){
                            properties([
                                    parameters([
                                            choice(name:'env', choices:env_list, description:'选择构建环境'),
                                            choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
                                                    description:'选择部署方式:编译并部署、仅编译、仅部署')
                                    ])
                            ])
                        }else{
                            properties([
                                    parameters([
                                            choice(name:'env', choices:env_list, description:'选择构建环境'),
                                            booleanParam(defaultValue:false, name: 'isCollectCoverage',description: '是否启用jacoco收集代码覆盖率'),
                                            choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
                                                    description:'选择部署方式:编译并部署、仅编译、仅部署')
                                    ])
                            ])
                        }
                        break
                    default:
                        properties([
                                parameters([
                                        choice(name:'env', choices:env_list, description:'选择构建环境'),
                                        choice(name:'buildType', choices:['buildAndDeploy', 'build', 'deploy'],
                                                description:'选择部署方式:编译并部署、仅编译、仅部署')
                                ])
                        ])
                }
            }
        }

    共享库的扩展示例

    java 服务增加 jacoco 覆盖率功能

    1.维护 JavaAppInfo 对象

    class JavaJobInfo extends JobInfo{
        boolean isCollectCoverage
        JavaJobInfo(Map map) {
            super(map)
            this.isCollectCoverage =  map.isCollectCoverage
        }
        //Jacoco相关属性
        String jacocoPort
        String projectId //jacoco覆盖率服务中,coverage_app表中的project_id字段
        String commitId
        String includes  //需要增强类的通配符表达式
        String excludes  //需要排除增强类的通配符表达式
    }

    2.在部署时,启动 jacoco

    def exec_jar(JavaJobInfo jobInfo){
        def util = new common_util()
        def log = new Log()
        def jacocoHandle = new JacocoHandle()
        //判断是否要启用jacoco服务
        if(jobInfo.isCollectCoverage){
            //先获取jacoco port
            jacocoHandle.getJacocoPort(jobInfo)
            //在获取本次构建代码最新的commit id
            jacocoHandle.getCommitId(jobInfo)
            def shell_str = "ssh root@${jobInfo.getHost()} '/home/deployscripts/deploy.sh -d jar //省略 "
            if(jobInfo.includes !=""){
                shell_str += " -I ${jobInfo.includes}"
            }
            if(jobInfo.excludes != ""){
                shell_str += " -E ${jobInfo.excludes}"
            }
            shell_str += "'"
            sh "${shell_str}"
        }else{
            sh "ssh root@${jobInfo.getHost()} '/home/deployscripts/deploy.sh -d jar //省略 " 
        }
    }

    到此,关于“Jenkins迁移之pipeline共享库怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注本站网站,小编会继续努力为大家带来更多实用的文章!

    《Jenkins迁移之pipeline共享库怎么使用.doc》

    下载本文的Word格式文档,以方便收藏与打印。