Harness 教程 03:代码仓库与触发器基础

142 阅读17分钟

提交代码,自动构建,自动测试,自动部署——这才是 CI/CD 该有的样子。

前两篇教程我们搞定了 Harness 平台搭建和第一个流水线,现在正式进入自动化触发阶段。

核心目标只有一个:让代码变化自动驱动整个交付流程


一、教程定位

在前两篇教程中,我们已经完成了 Harness 平台环境搭建,并创建了第一个 CI/CD 流水线。第 3 篇开始进入自动化触发阶段。

本篇的核心目标是:让代码提交、分支更新、Merge Request / Pull Request 事件能够自动触发 Harness Pipeline,从而实现真正意义上的"提交代码后自动构建、自动测试、自动部署"。

在国内网络环境中,代码仓库通常不是 GitHub,而是下面几类:

code复制

企业内网 GitLab
Gitee 企业版
Bitbucket Server / Bitbucket Cloud
自建 Git 服务

其中,GitLab 是国内企业最常见的选择。因此本文以 GitLab 为主线讲解,同时说明 GitHub、Bitbucket、Gitee 的处理方式。


二、适合人群

本文适合已经具备 Git 基础的初学者,包括:

code复制

会使用 git clone / git add / git commit / git push
了解 main、dev、feature 分支的区别
知道 Pull Request / Merge Request 的基本概念
已经完成 Harness Delegate、Git Connector、Harbor Connector、Kubernetes Connector 的基础配置
已经有一个可以运行的 Harness CI/CD Pipeline

本文不要求你精通 Webhook,但建议知道:

code复制

Webhook 是代码仓库在某些事件发生时主动调用外部地址的一种机制
Push 事件通常代表代码被推送
Merge Request / Pull Request 事件通常代表代码合并请求被创建、更新或合并

三、学习目标

完成本文后,你应该能够:

code复制

理解 Harness Trigger 的作用
理解 Webhook 触发和轮询触发的区别
知道国内网络环境下 GitLab/Gitee 触发器的实施限制
为 GitLab 仓库创建 Harness Webhook Trigger
实现 push main 分支后自动触发 Pipeline
实现 feature 分支提交只触发构建、不触发部署
实现 Merge Request 创建或更新时自动触发测试流水线
配置分支过滤条件
配置 Changed Files 过滤条件
配置触发后自动传递分支名和 commit sha
排查 Webhook 不触发、重复触发、触发后 Pipeline 失败等问题

四、国内网络环境下的触发架构

国内环境中,最推荐的触发链路如下:

code复制

开发人员
  ↓ git push
GitLab / Gitee / Bitbucket
  ↓ Webhook HTTPS 请求
Harness SaaS Webhook 地址
  ↓ 匹配 Trigger 条件
Harness Pipeline
  ↓ 派发任务
Harness Delegate
  ↓ 拉代码、构建、推镜像、部署
GitLab / Harbor / Kubernetes

重点要理解两件事:

第一,Webhook 请求是由 Git 仓库发起的。也就是说,GitLab 必须能够访问 Harness 的 Webhook 地址。

第二,Pipeline 真正执行构建和部署时,仍然由 Delegate 访问企业内网 GitLab、Harbor、Kubernetes。

所以国内企业落地时,经常会出现两类网络问题:

code复制

问题 1:Harness SaaS 不能访问企业内网 GitLab
解决:Connector 设置 Execute on Delegate

问题 2:企业内网 GitLab 不能访问 Harness SaaS Webhook 地址
解决:开放出站 HTTPS,或使用中转网关 / 自定义触发方式

这两个问题不要混淆。

Connector 的 Execute on Delegate 解决的是 Harness 拉代码访问内网 GitLab 的问题;Webhook 触发解决的是 GitLab 如何通知 Harness 的问题。


五、Webhook 与轮询触发的区别

1. Webhook 触发

Webhook 是推荐方式。

当 Git 仓库发生事件时,例如:

code复制

push 到 main 分支
push 到 dev 分支
创建 Merge Request
更新 Merge Request
合并 Merge Request
创建 tag

GitLab 会向 Harness 的 Webhook URL 发送 HTTP 请求。Harness 收到请求后,根据 Trigger 条件判断是否启动 Pipeline。

优点

code复制

实时性好
不需要频繁扫描仓库
资源消耗低
适合企业自动化流水线

缺点

code复制

GitLab 必须能访问 Harness Webhook URL
公司防火墙可能拦截出站 HTTPS
内网 GitLab 如果完全不能出网,需要额外设计触发代理

2. 轮询触发

轮询是指 Harness 按固定频率检查仓库事件。

但是这里必须说明清楚:Harness 官方文档中提到的 Git Webhook Polling Frequency 当前只适用于 GitHub Webhook,并且需要开启功能开关 CD_GIT_WEBHOOK_POLLING。因此,在 GitLab / Gitee 场景中,不能默认把轮询作为通用能力来设计。

如果你使用的是国内 GitLab 或 Gitee,并且 Webhook 无法打到 Harness SaaS,实际可落地方案一般有三种:

code复制

方案一:打通 GitLab 到 Harness SaaS 的出站 HTTPS
方案二:使用企业出口代理或 API 网关中转 Webhook
方案三:使用 GitLab CI / Jenkins / 定时任务调用 Harness Custom Trigger URL

对于个人学习环境,建议优先使用 Webhook。

对于企业内网环境,建议由网络或安全团队确认 GitLab 是否允许访问:

code复制

https://app.harness.io/gateway/ng/api/webhook

六、实施前环境准备

1. Harness 资源准备

你需要已经创建好:

code复制

Org: devops-lab
Project: harness-demo
Pipeline: nodejs-harbor-k8s-dev
Delegate: cn-k8s-dev
Git Connector: gitlab_company
Harbor Connector: harbor_company
Kubernetes Connector: k8s_dev_cluster

建议给 Delegate 添加标签:

code复制

cn
k8s
dev
gitlab
harbor

这样后续 Connector 和 Pipeline 都可以明确指定由国内网络中的 Delegate 执行。


2. GitLab 仓库准备

示例仓库:

code复制

https://gitlab.company.com/devops/harness-demo-app.git

推荐分支设计:

code复制

main:稳定主分支,可以触发部署 dev 或 test
dev:开发联调分支,可以触发构建和部署 dev
feature/*:功能分支,只触发构建和测试,不触发部署
release/*:发布分支,触发准生产部署
hotfix/*:紧急修复分支,触发特殊审批流程

个人学习时可以简化为:

code复制

main
feature/demo-trigger

3. GitLab Token 权限准备

如果希望 Harness 自动注册 GitLab Webhook,GitLab Connector 使用的 Token 需要具备足够权限。

建议使用 GitLab Project Access Token 或专用机器人账号 Token。

推荐权限:

code复制

read_repository
read_api
api

如果只做代码拉取,通常 read_repository 即可;如果需要自动注册 Webhook,通常需要 API 相关权限。

企业建议

code复制

不要使用个人账号 Token
使用专用机器人账号
Token 设置过期时间
Token 权限最小化
Token 存入 Harness Secret
Token 定期轮换

4. 网络连通性检查

在 GitLab 所在服务器或同网段机器上执行:

bash复制

curl -I https://app.harness.io/gateway/ng/api/webhook

只要能建立 HTTPS 请求即可,不要求返回 200。因为这个 URL 需要带 accountIdentifier 等参数,直接访问可能返回 400 或 405,但不能是连接超时或 DNS 解析失败。

在 Delegate Pod 内检查 GitLab:

bash复制

kubectl exec -it deploy/firstk8sdel -n harness-delegate-ng -- sh

curl -k -I https://gitlab.company.com

在 Delegate Pod 内检查 Harbor:

bash复制

curl -k -I https://harbor.company.com/v2/

如果企业网络必须走代理,则 Delegate 需要配置:

bash复制

HTTP_PROXY=http://proxy.company.com:3128
HTTPS_PROXY=http://proxy.company.com:3128
NO_PROXY=localhost,127.0.0.1,.svc,.cluster.local,gitlab.company.com,harbor.company.com,kubernetes.default.svc

注意:GitLab、Harbor、Kubernetes 内网地址必须加入 NO_PROXY,否则 Delegate 访问内网资源可能被错误转发到外部代理。


七、准备一个用于触发测试的 Pipeline

为了让触发器更容易验证,建议先在现有 Pipeline 中增加一个触发信息打印步骤。

在 CI Build Stage 最前面添加一个 Shell Script / Run Step:

bash复制

echo "===== Trigger Info ====="
echo "pipeline.triggerType: <+pipeline.triggerType>"
echo "trigger.event: <+trigger.event>"
echo "trigger.branch: <+trigger.branch>"
echo "trigger.targetBranch: <+trigger.targetBranch>"
echo "trigger.sourceBranch: <+trigger.sourceBranch>"
echo "trigger.commitSha: <+trigger.commitSha>"
echo "trigger.gitUser: <+trigger.gitUser>"
echo "trigger.repoUrl: <+trigger.repoUrl>"
echo "pipeline.executionId: <+pipeline.executionId>"

作用

code复制

判断 Pipeline 是手动运行还是 Webhook 触发
确认触发分支是否正确
确认 commit sha 是否正确
确认 MR / PR 的源分支和目标分支是否正确
排查触发条件不匹配问题

如果某些表达式在手动运行时为空,这是正常现象,因为它们只在 Webhook 触发时有值。


八、创建 GitLab Push Trigger:提交 main 分支自动触发

1. 进入 Trigger 创建入口

进入 Harness:

code复制

Project
  → Pipelines
  → nodejs-harbor-k8s-dev
  → Pipeline Studio
  → Triggers
  → New Trigger

选择:

code复制

Trigger Type: Webhook
SCM Provider: GitLab
Event: Push

2. 配置基础信息

填写:

code复制

Name: gitlab-main-push
Identifier: gitlab_main_push
Description: main 分支 push 后自动触发 CI/CD
Connector: gitlab_company
Repository: devops/harness-demo-app
Event: Push

如果界面中有 Auto-abort Previous Execution,建议开启。

作用

code复制

同一个分支短时间连续 push 多次时,自动取消旧的未完成执行
避免重复构建浪费资源
避免旧版本后部署覆盖新版本

3. 配置分支过滤条件

在 Conditions 中配置 Branch Name:

code复制

Attribute: Branch Name
Operator: Equals
Value: main

含义:

code复制

只有 push 到 main 分支时才触发
push 到 feature/* 不触发这个 Trigger

如果你希望 dev 分支也触发,可以使用 Regex:

code复制

Operator: Regex
Value: ^(main|dev)$

如果你希望 release 分支触发:

code复制

Operator: Regex
Value: ^release/.*$

企业建议

code复制

main 或 release/* 可以触发部署
feature/* 只触发构建和测试
不要让所有分支都触发部署

4. 配置 Pipeline Input

如果 Pipeline 的 codebase 分支是 Runtime Input,需要在 Trigger 的 inputYaml 中传入触发分支。

参考:

yaml复制

pipeline:
  identifier: nodejs_harbor_k8s_dev
  properties:
    ci:
      codebase:
        build:
          type: branch
          spec:
            branch: <+trigger.branch>

说明:

code复制

<+trigger.branch> 表示触发事件中的分支
当 push main 时,Pipeline 拉取 main
当 push dev 时,Pipeline 拉取 dev

如果你的 Pipeline 固定只跑 main,可以直接写死:

yaml复制

pipeline:
  identifier: nodejs_harbor_k8s_dev
  properties:
    ci:
      codebase:
        build:
          type: branch
          spec:
            branch: main

5. 保存 Trigger

点击:

code复制

Create Trigger

如果 Harness 能使用 Connector 中的 API Token 自动在 GitLab 创建 Webhook,那么保存后 GitLab 仓库里会出现对应 Webhook。

如果自动注册失败,继续看下一节手动注册。


九、手动注册 GitLab Webhook

国内企业内网 GitLab 经常因为权限、证书、网络或 API 限制导致 Harness 自动注册 Webhook 失败。这时可以手动注册。

1. 在 Harness 复制 Webhook URL

进入:

code复制

Pipeline
  → Triggers
  → gitlab-main-push
  → Copy Webhook URL

Webhook URL 通常类似:

code复制

https://app.harness.io/gateway/ng/api/webhook?accountIdentifier=xxxx

实际 URL 以 Harness 页面复制出来的为准。


2. 在 GitLab 中添加 Webhook

进入 GitLab 项目:

code复制

Project
  → Settings
  → Webhooks

填写:

code复制

URL: 粘贴 Harness Webhook URL
Secret Token: 如果 Harness Trigger 配置了 Secret,这里填写同一个 Secret
Trigger: Push events
Branch filter: main
SSL verification: 开启

如果 GitLab 使用内网代理访问外部 HTTPS,需要由网络管理员确认 GitLab 服务器能访问 Harness SaaS。

如果企业使用自签代理证书,需要确保 GitLab 服务器信任企业代理 CA,否则 Webhook 可能 TLS 失败。


3. GitLab Webhook 测试

在 GitLab Webhook 页面点击 Test,选择 Push events。

正常情况下,返回状态可能是:

code复制

200
202

或者 GitLab 页面显示请求发送成功。

如果失败,常见原因

code复制

GitLab 服务器不能访问 app.harness.io
公司防火墙阻断 HTTPS
Webhook URL 复制错误
Secret Token 不一致
SSL verification 失败
Trigger 条件不匹配

十、验证 push main 自动触发

在本地执行:

bash复制

git checkout main
echo "trigger test $(date)" >> README.md
git add README.md
git commit -m "test: trigger pipeline on main push"
git push origin main

然后进入 Harness:

code复制

Pipeline
  → Executions

预期

code复制

出现一条新的 Pipeline 执行记录
触发类型为 WEBHOOK
日志中打印 trigger.branch = main
日志中打印 trigger.commitSha 为本次提交 ID

如果 Pipeline 没有启动,查看:

code复制

Pipeline → Triggers → Activity History
GitLab → Project → Settings → Webhooks → Recent Deliveries

十一、配置 feature 分支只构建不部署

企业中常见需求:

code复制

feature/* 分支提交后只跑 CI,不部署
main 分支提交后跑 CI + CD
release/* 分支提交后跑 CI + 部署准生产

实现方式有两种。


方式一:创建独立 Pipeline

创建一个只包含 CI Build Stage 的 Pipeline:

code复制

Pipeline: nodejs-ci-only
Stages:
  - CI Build

然后创建 Trigger:

code复制

Name: gitlab-feature-push
Event: Push
Branch Condition:
  Operator: Regex
  Value: ^feature/.*$

适合初学者和小团队。

优点

code复制

结构简单
容易理解
CI 和 CD 完全隔离

缺点

code复制

Pipeline 数量会变多
重复配置可能较多

方式二:同一个 Pipeline 中按触发分支控制 Stage 执行

在 Deploy Dev Stage 上增加执行条件:

code复制

Only run when branch is main or dev

JEXL 条件示例:

code复制

<+trigger.branch> == "main" || <+trigger.branch> == "dev"

如果需要支持手动执行,可以写成:

code复制

<+pipeline.triggerType> == "MANUAL" || <+trigger.branch> == "main" || <+trigger.branch> == "dev"

这样:

code复制

手动执行时允许部署
Webhook 触发时,只有 main/dev 分支允许部署
feature/* 分支只执行 CI,不执行 Deploy

企业建议

code复制

入门阶段用独立 Pipeline
工程化阶段用模板 + Stage 条件
生产环境不要只靠分支名控制,必须叠加审批和 RBAC

十二、创建 GitLab Merge Request Trigger

Merge Request Trigger 适合代码评审场景。

常见目标:

code复制

开发人员提交 MR 到 main
Harness 自动运行单元测试
Harness 自动运行代码扫描
测试通过后,评审人员再合并
不直接部署生产

1. 创建 Trigger

进入:

code复制

Pipeline
  → Triggers
  → New Trigger

选择:

code复制

SCM Provider: GitLab
Event: Merge Request
Actions:
  - Open
  - Update
  - Reopen
  - Sync

不同 Harness 版本界面显示可能略有差异,以实际 UI 为准。


2. 配置 MR 分支条件

目标:只有合并到 main 的 MR 才触发。

配置:

code复制

Target Branch
Operator: Equals
Value: main

如果只允许 feature 分支发起 MR:

code复制

Source Branch
Operator: Regex
Value: ^feature/.*$

组合效果

code复制

source branch = feature/*
target branch = main

即:

code复制

feature/login → main 触发
bugfix/demo → main 不触发
feature/login → dev 不触发

因为 Harness Trigger 条件默认是 AND 关系,所以两个条件都满足才会触发。


3. MR Trigger 的 inputYaml

Merge Request 场景通常建议构建源分支:

yaml复制

pipeline:
  identifier: nodejs_ci_only
  properties:
    ci:
      codebase:
        build:
          type: branch
          spec:
            branch: <+trigger.sourceBranch>

如果你的 CI 工具链支持构建 MR 合并结果,也可以按团队策略调整。但初学者阶段使用源分支最简单。


4. 验证 MR 触发

本地创建功能分支:

bash复制

git checkout -b feature/mr-trigger-demo
echo "mr trigger test" >> README.md
git add README.md
git commit -m "test: mr trigger demo"
git push origin feature/mr-trigger-demo

在 GitLab 创建 Merge Request:

code复制

Source: feature/mr-trigger-demo
Target: main

预期结果

code复制

Harness 自动触发 Pipeline
trigger.event 显示 PR/MR 相关事件
trigger.sourceBranch = feature/mr-trigger-demo
trigger.targetBranch = main

十三、配置 Changed Files 过滤:只在指定目录变更时触发

在 Monorepo 场景中,一个仓库可能包含多个服务:

code复制

repo/
├── services/
│   ├── user-service/
│   ├── order-service/
│   └── payment-service/
├── frontend/
├── docs/
└── deploy/

如果每次改 README 都触发全部流水线,会浪费资源。

可以配置 Changed Files 条件。


1. 只在 Node.js 服务变更时触发

配置:

code复制

Changed Files
Operator: Regex
Value: ^services/nodejs-demo/.*$

或者:

code复制

Value: ^app/.*|^docker/.*|^k8s/.*$

适用于本文示例仓库:

code复制

app/ 变更时触发
docker/ 变更时触发
k8s/ 变更时触发
README.md 变更不触发

2. 企业实践建议

Monorepo 建议按服务拆分 Trigger:

code复制

user-service-push-trigger
order-service-push-trigger
payment-service-push-trigger
frontend-push-trigger

每个 Trigger 只监听自己的目录:

code复制

^services/user-service/.*
^services/order-service/.*
^frontend/.*

这样可以明显减少无效构建。


十四、配置 Header / Payload 条件

在高级场景中,可以基于 Webhook Header 或 Payload 做精细过滤。

1. Header 条件

GitLab Webhook 通常会包含事件类型 Header。

可配置:

code复制

Attribute:
<+trigger.header['X-Gitlab-Event']>

Operator:
Equals

Value:
Push Hook

Merge Request 场景:

code复制

Value:
Merge Request Hook

2. Payload 条件

可以读取 GitLab Webhook 的 JSON 内容。

例如限制触发用户:

code复制

Attribute:
<+trigger.payload.user_username>

Operator:
Equals

Value:
harness-bot

或者排除机器人提交:

code复制

JEXL:
<+trigger.payload.user_username> != "dependabot"

实际 Payload 字段要以 GitLab Webhook 的真实请求体为准。不同 Git 提供商字段不完全一致,不能把 GitHub 的 payload 字段直接套到 GitLab 上。


十五、配置 Custom Trigger:适配 Gitee 或完全内网场景

如果你的代码仓库是 Gitee,或者企业内网 Git 服务不属于 Harness 原生支持的 Git 事件提供商,可以使用 Custom Trigger。

适用场景

code复制

Gitee 企业版没有使用 Harness 原生 Git Trigger
企业自建 Git 服务
GitLab 无法直接向 Harness 注册标准 Webhook
通过 GitLab CI 或 Jenkins 转发触发 Harness
内网安全团队要求所有外发请求经过统一网关

1. 创建 Custom Trigger

进入 Harness:

code复制

Pipeline
  → Triggers
  → New Trigger
  → Webhook
  → Custom

填写:

code复制

Name: custom-git-push
Identifier: custom_git_push

配置 Secret Token。

保存后复制 Custom Webhook URL。


2. 通过 GitLab CI 转发触发

如果 GitLab 不能直接使用原生 Webhook,也可以在 .gitlab-ci.yml 中调用 Harness Custom Trigger。

示例:

yaml复制

stages:
  - trigger_harness

trigger_harness_pipeline:
  stage: trigger_harness
  image: curlimages/curl:8.8.0
  script:
    - |
      curl -X POST "$HARNESS_TRIGGER_URL" \
        -H "Content-Type: application/json" \
        -H "X-Harness-Token: $HARNESS_TRIGGER_TOKEN" \
        -d "{
          \"branch\": \"$CI_COMMIT_REF_NAME\",
          \"commitSha\": \"$CI_COMMIT_SHA\",
          \"repoUrl\": \"$CI_PROJECT_URL\",
          \"user\": \"$GITLAB_USER_LOGIN\"
        }"
  only:
    - main
    - dev

需要在 GitLab CI/CD Variables 中配置:

code复制

HARNESS_TRIGGER_URL
HARNESS_TRIGGER_TOKEN

注意

code复制

不要把 Trigger URL 和 Token 写死在仓库中
不要把 Token 输出到日志
生产环境建议通过企业网关审计外发请求

3. Custom Trigger inputYaml 示例

在 Harness Trigger 中可以把自定义 payload 传给 Pipeline。

示例:

yaml复制

pipeline:
  identifier: nodejs_harbor_k8s_dev
  properties:
    ci:
      codebase:
        build:
          type: branch
          spec:
            branch: <+trigger.payload.branch>
  variables:
    - name: commitSha
      type: String
      value: <+trigger.payload.commitSha>
    - name: repoUrl
      type: String
      value: <+trigger.payload.repoUrl>

然后在 Pipeline 中可以打印:

bash复制

echo "branch: <+pipeline.variables.branch>"
echo "commitSha: <+pipeline.variables.commitSha>"

根据实际 UI,变量名和 inputYaml 要与 Pipeline 中定义的 Runtime Input 或变量保持一致。


十六、模拟"轮询替代方案":定时检查 Git 提交

如果企业确实无法使用 Webhook,又不是 GitHub Polling 适用场景,可以使用"定时触发 + 脚本检查 commit"的方式替代。

架构

code复制

Harness Scheduled Trigger
  ↓
Pipeline 定时运行
  ↓
Delegate 执行脚本
  ↓
查询 GitLab 最新 commit
  ↓
与上次记录 commit 比较
  ↓
有变化则继续执行构建
  ↓
无变化则退出

这不是 Harness 原生 Git 轮询触发,而是一种可落地的工程替代方案。


1. 创建 Scheduled Trigger

创建一个定时触发器:

code复制

Trigger Type: Scheduled
Cron: 每 5 分钟执行一次

建议不要太频繁。

code复制

个人学习:10 分钟一次
企业测试:5~15 分钟一次
生产环境:按需求评估,不建议高频轮询

2. 检查最新 commit 脚本

在 Pipeline 的第一步执行:

bash复制

set -e

GITLAB_URL="https://gitlab.company.com"
PROJECT_PATH="devops%2Fharness-demo-app"
BRANCH="main"
TOKEN="<+secrets.getValue('gitlab_access_token')>"

LATEST_COMMIT=$(curl -s --header "PRIVATE-TOKEN: ${TOKEN}" \
  "${GITLAB_URL}/api/v4/projects/${PROJECT_PATH}/repository/branches/${BRANCH}" \
  | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')

echo "Latest commit: ${LATEST_COMMIT}"

if [ -z "${LATEST_COMMIT}" ]; then
  echo "无法获取最新 commit"
  exit 1
fi

echo "请在企业落地中把 LATEST_COMMIT 写入 Redis、ConfigMap、对象存储或内部配置中心,并与上次值比较"

真正企业落地时,建议把上次 commit 保存到:

code复制

Redis
MySQL
对象存储
Kubernetes ConfigMap
内部配置中心

个人学习可以先打印 commit,理解机制即可。


十七、触发器 YAML 示例

下面给出一个 GitLab Push Trigger 的参考 YAML。实际字段以 Harness UI 生成结果为准,建议先在界面创建成功,再切换 YAML 保存。

yaml复制

trigger:
  name: gitlab-main-push
  identifier: gitlab_main_push
  enabled: true
  description: main 分支 push 自动触发 CI/CD
  orgIdentifier: devops_lab
  projectIdentifier: harness_demo
  pipelineIdentifier: nodejs_harbor_k8s_dev
  source:
    type: Webhook
    spec:
      type: Gitlab
      spec:
        type: Push
        spec:
          connectorRef: gitlab_company
          autoAbortPreviousExecutions: true
          payloadConditions: []
          headerConditions: []
          repoName: devops/harness-demo-app
          actions: []
          branchRegex: main
  inputYaml: |
    pipeline:
      identifier: nodejs_harbor_k8s_dev
      properties:
        ci:
          codebase:
            build:
              type: branch
              spec:
                branch: <+trigger.branch>

重要提示:如果你的 Harness UI 生成的字段不是 branchRegex,不要强行照抄。正确做法是:

code复制

先用 Visual Editor 创建 Trigger
配置 Branch Condition
保存后切换到 YAML
以 Harness 自动生成的 YAML 为准

十八、Pipeline 中使用触发变量

触发后常用变量:

code复制

<+pipeline.triggerType>
<+trigger.event>
<+trigger.branch>
<+trigger.targetBranch>
<+trigger.sourceBranch>
<+trigger.commitSha>
<+trigger.gitUser>
<+trigger.repoUrl>
<+trigger.payload.xxx>
<+trigger.header['Header-Name']>

推荐在 CI Build Stage 增加版本变量:

bash复制

IMAGE_TAG="<+trigger.commitSha>"

if [ -z "$IMAGE_TAG" ]; then
  IMAGE_TAG="<+pipeline.sequenceId>"
fi

echo "IMAGE_TAG=${IMAGE_TAG}"

更推荐的镜像 Tag 策略:

code复制

开发环境:<+pipeline.sequenceId>
测试环境:<+trigger.commitSha>
生产环境:Git Tag / release-日期-流水号

十九、避免重复触发

重复触发是企业落地中很常见的问题。

常见原因

code复制

同一个 GitLab 仓库注册了多个 Harness Webhook
既配置了 Push Trigger 又配置了 MR Trigger,且事件重叠
GitLab System Hook 和 Project Webhook 同时触发
Trigger 条件过宽
自动注册失败后又手动注册,导致重复

排查方式

code复制

GitLab → Project → Settings → Webhooks
检查是否有多个类似 Harness URL

Harness → Pipeline → Triggers
检查是否有多个 Trigger 监听同一事件

Harness → Trigger Activity History
查看同一事件是否命中多个 Trigger

治理建议

code复制

一个仓库一个触发策略清单
一个事件只由一个 Trigger 负责
Trigger 命名体现事件与分支
开启 Auto-abort Previous Execution
使用 Branch / Changed Files 条件缩小触发范围

二十、常见问题排查

1. Git push 后没有触发 Pipeline

排查顺序:

code复制

GitLab 服务器上测试:

bash复制

curl -I https://app.harness.io/gateway/ng/api/webhook

2. Webhook 注册失败

常见原因

code复制

GitLab Token 权限不足
Connector 没有启用 API Access
仓库地址写错
Repository 不存在
Token 未授权 SSO
GitLab 自签证书不被信任
Harness SaaS 无法调用 GitLab API

解决建议

code复制

确认 Token 有 api 权限
确认 Connector API Access 可用
确认 GitLab URL 正确
内网 GitLab 建议手动注册 Webhook

3. Trigger 命中了,但 Pipeline 启动失败

常见原因

code复制

Pipeline 有 Runtime Input,但 Trigger 没传
inputYaml 写错
分支不存在
代码仓库 Connector 拉不到代码
Delegate 网络不通
Pipeline YAML 校验失败

处理

code复制

查看 Pipeline Execution 错误
查看 inputYaml
手动使用同样分支运行一次 Pipeline
进入 Delegate Pod 验证 GitLab 连通性

4. Push 到 feature 分支也部署了

原因

code复制

Trigger 分支条件过宽
Deploy Stage 没有限制执行条件
所有分支共用同一个部署 Pipeline

解决

code复制

Push Trigger 只允许 main/dev
feature/* 单独使用 CI-only Pipeline
Deploy Stage 增加条件:只允许 main/dev

5. Merge Request 没有触发

检查

code复制

Trigger Event 是否选择 Merge Request
Action 是否包含 Open / Update / Sync
Source Branch / Target Branch 条件是否匹配
GitLab Webhook 是否勾选 Merge request events
GitLab Recent Deliveries 是否成功

6. 触发了两次

检查

code复制

GitLab 项目 Webhook 是否重复
GitLab System Hook 是否也配置了
Harness 中是否有多个 Trigger 监听同一事件
是否同时使用 Push 和 MR Update,且同一次操作产生两个事件

二十一、企业最佳实践

1. 分支触发策略

推荐

code复制

feature/*:
  只触发 CI 构建和测试

dev:
  触发 CI + 自动部署开发环境

main:
  触发 CI + 自动部署测试环境,或等待审批后部署

release/*:
  触发准生产部署,必须审批

tag v*:
  触发生产发布,必须审批 + 变更单

2. Trigger 命名规范

建议

code复制

{git平台}-{事件}-{分支}-{用途}

gitlab-push-main-deploy-dev
gitlab-push-feature-ci
gitlab-mr-feature-to-main-ci
gitlab-tag-release-prod
custom-gitee-push-main-ci

3. Webhook 安全规范

code复制

启用 Secret Token
限制 GitLab 出站访问目的地
避免 Trigger URL 泄露
Webhook Token 存入 Secret
定期轮换 Token
企业网关记录外发请求审计
不要把 Custom Trigger URL 写入代码仓库

4. 多环境触发治理

推荐做法

code复制

feature/* → CI only
dev → deploy dev
main → deploy test
release/* → deploy pre
tag → deploy prod

不要让同一个 Trigger 同时承担所有环境。


5. Monorepo 治理

如果一个仓库中有多个服务,必须配置 Changed Files。

示例

code复制

user-service:
  ^services/user-service/.*

order-service:
  ^services/order-service/.*

frontend:
  ^frontend/.*

这样可以避免:

code复制

修改文档触发全部服务构建
修改一个服务触发所有服务部署
流水线资源被无效消耗

6. 审批与权限

触发器负责自动启动流程,但不应该绕过权限治理。

建议

code复制

dev 自动部署
test 可选审批
pre 必须审批
prod 必须审批 + 变更单 + 多人确认

即使 Push main 自动触发,也不要自动部署生产。


二十二、练习 1:配置 main 分支 Push 触发

目标

code复制

push main 后自动触发 nodejs-harbor-k8s-dev Pipeline

操作

bash复制

git checkout main
echo "main trigger test" >> README.md
git add README.md
git commit -m "test: main push trigger"
git push origin main

验收

code复制

Harness 出现新执行记录
trigger.branch = main
trigger.commitSha = 当前提交 ID
Pipeline 成功执行

二十三、练习 2:配置 feature 分支过滤

目标

code复制

push feature/* 后只触发 CI,不触发 Deploy

操作

bash复制

git checkout -b feature/trigger-filter
echo "feature trigger test" >> README.md
git add README.md
git commit -m "test: feature trigger filter"
git push origin feature/trigger-filter

验收

code复制

CI Pipeline 被触发
Deploy Stage 不执行
或者 nodejs-ci-only Pipeline 被触发

二十四、练习 3:配置 Merge Request 触发

目标

code复制

创建 feature/* → main 的 MR 后自动运行 CI

操作

code复制

验收

code复制

Harness 自动触发 MR Pipeline
trigger.sourceBranch = feature/mr-demo
trigger.targetBranch = main

二十五、验收标准

完成本文后,你应该达到以下结果:

code复制

已创建 GitLab Push Trigger
已创建 main 分支过滤条件
已验证 push main 自动触发 Pipeline
已理解 feature 分支只构建不部署的实现方式
已创建 Merge Request Trigger
已配置 Source Branch / Target Branch 条件
已理解 Changed Files 过滤在 Monorepo 中的作用
已了解 Gitee / 自建 Git 的 Custom Trigger 方案
已了解 Polling Frequency 当前不适合作为 GitLab/Gitee 通用方案
已掌握 Trigger Activity History 和 GitLab Recent Deliveries 排查方法

二十六、本篇总结

本篇完成了 Harness 代码仓库与触发器基础能力的落地。

你需要重点记住:

code复制

Webhook 是 Harness Git 事件触发的主流方式
国内 GitLab/Gitee 场景要重点关注网络出站能力
Connector 的 Execute on Delegate 解决的是 Harness 访问内网 Git 的问题
Webhook 解决的是 Git 仓库通知 Harness 的问题
分支过滤是企业触发治理的第一道门
MR / PR 触发适合代码评审和质量检查
Changed Files 适合 Monorepo 降低无效构建
Gitee 或自建 Git 可使用 Custom Trigger 适配
GitLab/Gitee 不要默认宣称支持 Harness 原生轮询触发
生产发布不能只依赖触发器,必须叠加审批、权限、审计和回滚