04. CI/CD - GitLab 集成 Jenkins 自动构建

发布时间 2023-04-10 22:59:20作者: Dy1an

Webhook

Jenkins 一般是企业选择比较多的 CI/CD 构建工具,虽然 GitLab CI/CD 本身的功能也很强。但是在于管理和隔离上更倾向于 Jenkins。

使用 GitLab 触发 Jenkins 构建一般采用的都是 Webhook 的方式。为此需要给 Jenkins 安装一个比较专业的用于配置 Webhook 的插件:

  • Generic Webhook Trigger

还需要安装一个解析 JSON 的插件,该插件会提供 readJSON 语法,方便解析 JSON:

  • Pipeline Utility Steps

如图所示:

安装完成之后会在 Job 的配置页面多出下面选项:

测试远程触发

新建一个流水线任务:


配置 Webhook:


配置一个测试流水线:


保存之后命令行测试:

curl http://192.168.2.100:38080/generic-webhook-trigger/invoke?token=gitlab-pipeline-demo-I0rKRhikePecy58e

我这里对 Jenkins 配置了 NodePort Service,方便后面外网端口转发访问,所以访问地址是这个。

请求成功后会返回一个 JSON 数据:

{"jobs":{"gitlab-pipeline-demo":{"regexpFilterExpression":"","triggered":true,"resolvedVariables":{},"regexpFilterText":"","id":149,"url":"queue/item/149/"}},"message":"Triggered jobs."}

可以看到任务已经触发构建:

GitLab 配置触发构建

这里使用的是外网的 GitLab 服务,所有想要触发 Jenkins,那么 Jenkins 必须能够被外网访问到。

当然,如果本地有配置安装 GitLab,可以使用本地的 GitLab 进行配置即可。

新建一个 demo 项目:


配置 Webhook:


保存后可以手动触发一次:


测试提交代码触发:


查看触发:

获取 GitLab 传递的参数

获取 POST 传递过来的所有数据:


在 Pipeline 中使用它:


此时再次使用 GitLab 触发构建:

可以看到具体相关的 Git POST 的信息,可以使用:

https://www.json.cn

将这个 JSON 格式化一下,其中比较有用一点的数据包含以下:

{
    "ref":"refs/heads/main",
    "checkout_sha":"bae6ece9bbfba3a7c8d049846b17a7f54449215f",
    "user_name":"不知名换皮工程师",
    "user_username":"goer31",
    "user_email":"1214966109@qq.com",
    "user_avatar":"https://gitlab.com/uploads/-/system/user/avatar/14222477/avatar.png",
    "project":{
        "name":"demo",
        "web_url":"https://gitlab.com/ezopscn/demo",
        "path_with_namespace":"ezopscn/demo",
    },
    "commits":[
        {
            "message":"Add new file",
            "title":"Add new file",
            "author":{
                "name":"不知名换皮工程师",
                "email":"1214966109@qq.com"
            },
        },
        {
            "message":"Initial commit",
            "title":"Initial commit",
            "author":{
                "name":"不知名换皮工程师",
                "email":"1214966109@qq.com"
            },
        }
    ],
    "total_commits_count":2,
}

在 Pipeline 中获取想要的数据:

// 获取 GitLab 传入的数据并解析
WebhookData = readJSON text: "${webhook_data}"

//分支名称
env.branchName = WebhookData.ref - "refs/heads/"

// 优化构建显示
// 构建描述
currentBuild.description = "提交次数:" + WebhookData.total_commits_count
// 构建标题
currentBuild.displayName = env.branchName + " pushed by " + WebhookData.user_username

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo '获取 POST 数据的方式:'
                echo "方式1:映射的方式"
                echo WebhookData["user_name"]
                echo WebhookData["project"]["name"]
                echo "方式2:. 的方式"
                echo WebhookData.user_name
                echo WebhookData.project.name
            }
        }
    }
}

触发构建后效果:

GitLab 创建分支不触发构建

之前因为在配置 Webhook 的时候指定了只有当 main 分支有 push 行为的时候才会触发接口,但日常使用中可能会有不能指定分支的情况。这时候就会出现当用户创建分支的时候也会触发构建。显然这种情况应该忽略掉。

此时将 GitLab Webhook 调整为 All branchs 状态:


新建一个分支:


可以看到触发了一次构建:


此时就需要去剔除创建分支这种情况,通过 JSON 可以看到明显的特征:

"before":"0000000000000000000000000000000000000000",

befor 或者 after 字段是 40 个 0 只要过滤这种情况即可,但是先要拿到这些数据,建议直接在 post content 中变量获取:

object_kind


before


after


在插件的 GitHub 仓库中有提到相关的配置:

https://github.com/jenkinsci/generic-webhook-trigger-plugin/tree/master/src/test/resources/org/jenkinsci/plugins/gwt/bdd/gitlab

如图所示:

配置方式:


Jenkins 中配置过滤规则:


此时再次创建分支测试:

可以发现 Jenkins 并未触发构建。

当然,如果想忽略空提交,也可以使用类似的方法:

Given filter is configured with text: $object_kind $after $total_commits_count
Given filter is configured with expression: ^push\s.{40}\s[^0].*

重新构建 GitLab 触发的任务

如果想在 Jenkins 重新触发上次构建,就会出现因为不是 GitLab 触发而没有 POST 数据的问题。这可能导致 Pipeline 出现问题。

为此,需要安装一个插件用于解决这个问题:

  • Rebuilder

安装完成后打开已经构建的任务:

集成配置阶段差不多就这样,具体应用需要根据实际情况编写对应的 Pipeline。