必须选“merged results”子选项的merge request events,因其在mr实际合并后触发,确保代码已落地目标分支;push events仅响应直接推送,无法覆盖标准code review流程下的合并部署场景。

GitLab Webhook 触发条件选 “Merge Request Events” 还是 “Push Events”?
合并后触发部署,必须选 Merge Request Events,而不是 Push Events。前者在 MR 被实际合并(merge commit 写入目标分支)时触发;后者只在直接 push 到分支时触发——如果走标准 Code Review 流程,开发人员不会直接 push 到 main 或 master,所以 Push Events 会漏掉绝大多数部署机会。
注意:GitLab 默认不勾选 Merge Request Events,且该事件类型有两个子选项:Merge requests(MR 创建/更新时触发)和 Merged results(仅合并成功后触发)。必须勾选后者,否则 Jenkins 可能被重复触发多次。
-
Merged results是唯一能确保“代码已落地目标分支”的信号 - 若同时勾选
Job events或Pipeline events,可能引发冗余构建,建议关闭 - Webhook URL 后需带
token=xxx参数(Jenkins 远程触发要求),否则请求会被拒绝
Jenkins 项目里怎么接住 GitLab 的合并事件?
Jenkins 本身不原生解析 GitLab Webhook 的 MR 数据,靠的是“远程触发器 + 参数化构建”组合。关键不是写复杂插件,而是让 Jenkins 主动从 GitLab API 拉取上下文。
配置要点:
- 在 Jenkins 项目中启用
Trigger builds remotely,并设置一个 secret token(比如deploy-on-merge) - 构建参数声明为
branchName(默认值填main),用于后续拉取最新代码 - 构建步骤第一行加 shell 命令:
curl -sS "https://gitlab.example.com/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests?state=merged&per_page=1" -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" | jq -r '.[0].source_branch'—— 这样能准确拿到刚被合并的源分支名,避免依赖不可靠的 webhook payload 字段 - 后续用
git checkout $branchName && git pull origin $branchName确保部署的是真正合并进去的代码
为什么 Webhook 请求总显示 “Connection refused” 或超时?
这不是 Jenkins 配置问题,而是网络可达性问题。GitLab 实例发出的 HTTP 请求,目标是 Jenkins 的 http://jenkins-host:8080/job/my-project/build?token=xxx 地址,但这个地址对 GitLab 服务器来说可能根本不可达。
常见断点:
- Jenkins 运行在
localhost:8080,而 GitLab 在另一台机器上 —— 此时 GitLab 根本连不到localhost - Jenkins 绑定在
127.0.0.1:8080,没监听外网 IP;需改JENKINS_OPTS="--httpListenAddress=0.0.0.0 --httpPort=8080" - 防火墙或安全组拦截了 8080 端口(尤其云主机);GitLab 服务器出向、Jenkins 服务器入向都要放行
- GitLab 使用内网域名(如
jenkins.internal),但该域名在 GitLab 宿主机 DNS 中未解析 —— 改用 IP 或补/etc/hosts
部署脚本里要不要做分支校验?
要,而且必须做。Webhook 可能被误触发、重放或来自非预期分支,不校验就上线等于裸奔。
简单有效的校验方式:
- 在 Jenkins 构建脚本开头加:
if [ "$branchName" != "main" ] && [ "$branchName" != "release/*" ]; then echo "Skip deploy: branch $branchName not allowed"; exit 0; fi - 不要只依赖 GitLab Webhook 传来的
object_attributes.target_branch,它可能被伪造;以 Jenkins 参数或 API 拉取结果为准 - 如果用
git pull origin $branchName,务必确认该分支确实存在且有新提交,否则可能部署旧版本 - 生产环境建议加锁机制(如文件锁或 Redis 键),防止同一时间多个 MR 合并导致并发部署冲突
最易被忽略的一点:GitLab Webhook 发送的是 HTTP POST,但 Jenkins 远程触发器只认 GET 请求。别在 Webhook 里设成 POST —— 它会静默失败,日志里只显示 “No crumb found”,而不是明确报错。











