二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Nexus系列文章

  • Jenkins系列文章

    • Jenkins入门系列笔记汇总整理
    • 前言与介绍
    • Jenkins初始部署与简单配置
    • Jenkins各配置选项介绍
    • Jenkins中一个项目的构建
    • Jenkins配置项目构建的钉钉通知
    • Jenkins忘记管理员密码怎么办
    • Jenkins与gitlab的交互探微
    • Jenkins根目录详解
    • Jenkins插件之显示构建时间
    • Jenkins插件之批量修改配置
    • Jenkins配置简单构建邮件推送
    • Jenkins复杂邮件推送配置详解
    • Jenkins配置复杂构建邮件推送
    • Jenkins构建安卓项目之前的一些唠叨
    • Jenkins构建安卓项目配置
    • Jenkins与Gitlab分支的交互
    • Jenkins构建nodejs项目
    • 使用docker部署Jenkins及初始配置
    • 配置gitlab提交代码Jenkins自动构建
    • Jenkins回滚方案探微
    • Jenkins角色控制(小黄锁)探微
    • Jenkins构建的应用配置问题解决探微
    • Jenkins构建中tag的应用
    • Jenkins插件之Ansicolor(神器)
    • 最基础核心的Jenkins功能部署一个java应用
    • Jenkins+sonar构建代码扫描
    • Jenkins+docker+gitlab将应用部署到docker
    • Jenkins参数化构建犀利插件Active-Choices-Plugin
    • 记一次将代码中参数外显到构建历史中的操作
    • Jenkins升级与迁移的经验分享
    • pipeline笔记之从一个简单的项目构建开始
    • Jenkinsfile声明式语法详解
    • 自动构建的原始配置以及pipeline中的用法
    • 多分支构建的实践与思考
    • 使用Jenkinsfile类前端项目的部署与回滚
    • 如何在Jenkinsfile中定义一个全局的时间戳变量
    • Jenkins中自由风格回滚方案的最佳实践
    • Jenkins中pipeline风格回滚方案的最佳实践
    • pipeline结合ansible剧本进行批量的部署与回滚配置
    • 最近配置安卓iOS打包本地化流程中一些值得记录的内容
    • pipeline中如何在environment环节声明一个含有通配符的变量
    • git-Parameter插件在pipeline共享库中的实践详解
    • jenkins作为ci检测代码是否合并的实践
      • 1,gitlab 配置
      • 2,Jenkins 配置
      • 3,验证
    • 将Jenkins共享库的Jenkinsfile放到ci静态检测的实践
    • Jenkins的pipeline实践之GitSCM参数配置项详解
    • Jenkins中pipeline对接CMDB接口获取主机列表的发布实践
    • Jenkins有任务无法kill提示即将关闭
    • Jenkins基于Share Library共享库的最佳实践探索
    • Jenkins结合MySql Database插件的平台化实践思路
    • Jenkins-Groovy中三元表达式的用法
    • Jenkins-Groovy中Switch的高阶用法
    • Jenkins-pipeline之利用activity choice插件对接查询MySQL数据实现动态参数化的功能
    • CentOS通过yum快速安装Jenkins
    • Jenkins-pipeline语法之错误处理详解(文末有干货)
    • Jenkins常用插件汇总以及简单介绍
    • Jenkins所遇报错汇总及解决
    • Jenkins管理维护运维规范
  • ELK笔记

  • Kubernetes笔记

  • LLM专题

  • 系列专题
  • Jenkins系列文章
二丫讲梵
2021-08-22
目录

jenkins作为ci检测代码是否合并的实践

文章发布较早,内容可能过时,阅读注意甄别。

通常我们使用 Jenkins 完成了项目上线整个 CICD 的流程,这是应对高速发展的业务的方案,随着业务进程的发展,一定会到一个以稳定为第一要务的阶段,在这个阶段中,保障高质量的代码上线是其核心,于是,我们就需要着手针对代码检测做一些工作。

这些工作,可以通过与 Gitlab 结合的静态 ci 检测来进行,很多地方介绍的都是基于 gitlab-ci 或者其他诸如 drone 之类的工具来进行,我这里则结合 Jenkins 来进行分析。因为在我的概念中,一直觉得 gitlab 好好做一个代码管理工具就可以了,不必引入过多外部依赖,从而给代码管理本身带来不稳定因素。

为方便演示,我这里以一个 NGINX 配置文件集成的场景来进行讲解。

一些现实教训告诉我们,很多时候的故障或者异常超 80%都是因为变更引起的,所以我们将所有 NGINX 的配置收归到 gitlab 进行管理,如果要调整就走代码上线的流程,减少直接上机操作的次数。

接下来展示整个配置流程,主要分享思路,具体静态检查逻辑根据需求可进行调整。

# 1,gitlab 配置

gitlab 配置的核心在于,我们首先要控制一些指定分支的权限,比如控制 master 分支不能直接 push,且仅有Maintainers权限的人能够 merge,配置位置:进入项目--->Settings--->Repository--->Protected Branches:

image-20210822162832429

这样我们只把部分 leader 赋予Maintainers权限,即可控制到代码的上线,必须经过这几个大佬的手才行。

注意:如果在实际生产中,这里要控制的分支,也许 master 未必合适,因为 master 常常应对着正式环境地发布,讲究稳定的同时也考虑一些紧急场景的效率,因此,实际生产中,或许这里控制住预发环境的 pre 分支会更合适!

接着我们要勾选一个相当重要的配置项,only allow merge requests to be merged if the pipeline succeeds,配置位置:进入项目--->Settings--->General--->Merge request settings:

image-20210822163504049

此配置项决定了仅当流水线成功时才能够进行 merge,否则 merge 按钮将会是灰色的,使得Maintainers无法进行代码合并。

# 2,Jenkins 配置

我们创建如下流水线作为当前项目的 ci 配置:

pipeline {
    agent {
        label "slave_test_go"
    }
    environment {
        // 服务名称
        SERVICE_NAME="${JOB_BASE_NAME}"
        MODE="DEPLOY"
        REASON="无"
        REMOTE_HOST="占位"
        _VERSION="测试验证"
        // 主项目地址
        GIT_URL = "https://gitlab.test.com/ops/openrestyConfig.git"
    }
    parameters {
        string(name: 'BRANCH', defaultValue: 'master', description: '请输入将要构建的代码分支')
    }
    options {
        timestamps() // 输出构建日志打印时间信息
        timeout(time: 10, unit: 'MINUTES') // 设置构建超时时间
        buildDiscarder(logRotator(numToKeepStr: '15')) // 设置历史构建保留次数
        gitLabConnection('gitlab-token') // 操作gitlab的token
    }
    triggers{
        gitlab(triggerOnPush: false,triggerOnMergeRequest: true,branchFilterType: 'All',secretToken: "${env.GIT_TOKEN}") // 预留Gitlab提交自动构建
    }
    stages {
        stage('置为pending') {
            steps {
                script {
                    try {
                        updateGitlabCommitStatus name: 'build', state: 'pending'
                    }catch(exc) {
                        env.REASON = "置为pending出错"
                        throw(exc)
                    }
                }
            }
        }
        stage('拉取代码') {
            steps {
                script {
                    try {
                        env.CAUSE = currentBuild.getBuildCauses()[0].(userId)
                        if ("${CAUSE}" == 'null') {
                            env.BRANCH = sh(script: 'echo ${gitlabBranch}',  returnStdout: true).trim()
                        }
                        checkout(
                            [$class: 'GitSCM', doGenerateSubmoduleConfigurations: false, submoduleCfg: [], extensions: [[$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true]],
                            branches: [[name: "$BRANCH"]],userRemoteConfigs: [[url: "${env.GIT_URL}", credentialsId: "cicd-pass"]]]
                        )
                        // 定义全局变量
                        env.COMMIT_ID   = sh(script: 'git log --pretty=format:%h',  returnStdout: true).trim() // 提交ID
                        env.COMMIT_USER = sh(script: 'git log --pretty=format:%an', returnStdout: true).trim() // 提交者
                        env.COMMIT_TIME = sh(script: 'git log --pretty=format:%ai', returnStdout: true).trim() // 提交时间
                        env.COMMIT_INFO = sh(script: 'git log --pretty=format:%s',  returnStdout: true).trim() // 提交信息
                    }catch(exc) {
                        env.REASON = "拉取代码出错"
                        throw(exc)
                    }
                }
            }
        }
        stage('检测项目') {
            steps {
                script {
                    try {
                        docker.image('reg.test.com/base/openresty:1.19.3.2').inside(" -v /etc/hosts:/etc/hosts") {
                            sh '''nginx -c $WORKSPACE/nginx.conf -t'''
                        }
                    }catch(exc) {
                        env.REASON = "检测项目出错"
                        throw(exc)
                    }
                }
            }
        }
    }
    post {
        success {
            updateGitlabCommitStatus(name: 'build', state: 'success')
            addGitLabMRComment comment: "🤖Jenkins ci check success🥳, see the log: ${BUILD_URL}console"
        }
        failure {
            updateGitlabCommitStatus(name: 'build', state: 'failed')
            addGitLabMRComment comment: "🤖Jenkins ci check failed🤯, see the log: ${BUILD_URL}console"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

这里有几个要点:

  • gitLabConnection:要在系统管理中创建一个可操作 gitlab 的 token,非常重要,如果没有此项配置,则流水线无法将状态回调给 gitlab 项目。

    配置位置:系统管理--->系统配置--->Gitlab:

    image-20210822164215918

  • 这里限制了 triggers 条件仅为 merge 时触发,当前还可以根据需求限制固定分支,从而将 ci 检测控制在指定的范围里。

  • 触发构建之前,首先将状态置为 pennding,从而让 gitlab 项目无法 merge。

  • 拉完代码之后,我们借助集成好的镜像对 NGINX 配置文件进行语法检测。

  • 然后在最后借助流水线的 post 能力,将不同的状态回调给 gitlab。

关于如何配置自动触发的流水线,这里就不展开了,可以参考:自动构建的原始配置以及 pipeline 中的用法 (opens new window)。只不过在 gitlab 添加 hook 的时候仅配置 merge event 即可。

# 3,验证

这个时候我们可以走正常开发流程,新需求从 master 切出来一个独立的分支,调整完成之后,提交自己的普通分支,然后创建一个 merge request:

image-20210822165603446

注意,此时 merge 按钮仍旧是绿色的,这是一个不足之处,只有当流水线开始触发,将状态置为 pennding 时才会转变,如果你知道有更好的办法控制这个按钮,欢迎留言交流。

接着就会自动触发流水线进行静态检测,如果成功,则会有如下显示:

image-20210822165933221

此时需要进行 merge 的同学其实不必再纠结提交配置文件的语法是否有问题,只需要 Review 下 Changes 的内容即可决定是否 merge。

如果失败,则状态如下:

image-20210822171048655

注意,当流水线检测失败之后,gitlab 的 merge 状态也会变成灰色无法 merge,并提示:The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure,那么对应的开发同学就需要解决掉对应的冲突或者问题之后方可再次提交 merge,自己的代码才能够通过这道关卡而上线。

其他资料:

  • Jenkins 插件 gitlab-plugin 的官方文档 (opens new window)
微信 支付宝
#Jenkins
上次更新: 2025/03/06, 21:25:58
git-Parameter插件在pipeline共享库中的实践详解
将Jenkins共享库的Jenkinsfile放到ci静态检测的实践

← git-Parameter插件在pipeline共享库中的实践详解 将Jenkins共享库的Jenkinsfile放到ci静态检测的实践→

最近更新
01
学习周刊-总第212期-2025年第21周
05-22
02
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
03
学习周刊-总第211期-2025年第20周
05-15
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式