自动合并 pull request

git:auto-merge

一般用于 PR 通过 pull_request 流水线检查 和 Code Review 后,在 pull_request.mergeable 流水线中自动合并 PR无需人工点击合并按钮。

pull_request.mergeable 事件触发条件和时机参考事件

# 适用事件

  • pull_request.mergeable

# 参数

# mergeType

合并策略,默认为 auto:如果多人提交走 merge ,否则走 squash

# mergeCommitMessage

  • type: String
  • required: false

合并点提交信息。

当合并策略为 rebase 的时候,该信息无效,无需填写。

当合并策略为 merge ,默认为 chore: merge node(merged by CNB) ,会自动追加 pr 引用、reviewers 名单、pr 包含的提交人名单。举例说明:

chore: merge node(merged by CNB)

PR-URL: !916
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jack

当合并策略为 squash 时,默认值为该 pr第一条 commit message。并会自动追加 pr 引用和 reviewers 名单、pr 包含的提交人名单。举例说明:

main:
 pull_request.mergeable:
   - stages:
     - name: automerge
       type: git:auto-merge
       options:
         mergeType: squash

该配置会产生如下效果:

某个 pr (feat/model-a -> main) 中有两条提交记录,

提交记录 1,2023-10-1 日提交

feat(model-a): 给模块 A 增加一个新特性

由于某某原因,新增某某特性

close #10

提交记录 2,修复了在 cr 时被指出的一些问题,2023-10-2 日提交

fix(model-a): 修复评审中指出的问题

在自动合并后将会在 main 分支上产生一个这样的提交节点,即后续的提交记录(也就是提交记录 2)将会被抹掉

feat(model-a): 给模块 A 增加一个新特性

由于某某原因,新增某某特性

close #10

PR-URL: !3976
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jack

# mergeCommitFooter

  • type: String
  • required: false

合并点需要设置的脚注,多个脚注用 \n 分隔,仅在 mergesquash 生效。 当合并策略为 rebase 的时候,该信息无效,无需填写。

当合并策略为 mergesquash 时,会将传入信息按行加入到脚注中,再追加 pr 引用、reviewers 名单、pr 包含的提交人名单。举例说明:

main:
 pull_request.mergeable:
   - stages:
     - name: automerge
       type: git:auto-merge
       options:
         mergeType: squash
         mergeCommitMessage: "add feature for some jobs"
         mergeCommitFooter: "--story=123\n--story=456"
add feature for some jobs

--story=123
--story=456
PR-URL: !916
Reviewed-By: tom
Reviewed-By: jerry
Co-authored-by: jack

# removeSourceBranch

  • type: Boolean
  • required: false
  • default: false

合并后是否删除源分支。

源分支与目标分支不同仓库时,该值无效。

# ignoreAssignee

  • type: Boolean
  • required: false
  • default: false

是否忽略 assignee

当该 pr 有指定 assignee (指派人)的时候,本任务不会执行自动合并的逻辑。 因为 assignee 的本意就是指派某人手动来处理。

当为 true 时,可忽略 assignee 强行合并。

# 输出结果

{
    reviewedBy, // string,追加在提交信息后面的提交者信息
    reviewers, // array<string>, 走查者列表
}

# 配置样例

# 单独使用

main:
  pull_request.mergeable:
    - stages:
        - name: automerge
          type: git:auto-merge
          options:
            mergeType: merge

当分支 main 上 的 PR 触发了 mergeable 事件,那么会将这个 PRmerge 的方式自动合并。

# 配合目标分支的 push 事件使用

main:
  push:
    - stages:
        - name: build
          script: npm run build
        - name: publish
          script: npm run publish
  pull_request.mergeable:
    - stages:
        - name: automerge
          type: git:auto-merge
          options:
            mergeType: merge

当分支 main 上 的 PR 触发了 pull_request.mergeable 事件,那么会将这个 PRmerge 的方式自动合并。 在自动合并之后,会触发目标分支(main)上的 push 事件,继续执行声明的 buildpublish 流程。

这里有一个谁应该对产生的 push 事件流程负责的问题,这里的设定是这样的

  1. 如果提出 PR 者,是目标仓库的成员,那么提出 PR 的人对后续产生的 push 事件流程负责(即 push 构建流水会推送到这里)。
  2. 如果提出 PR 者,不是目标仓库的成员(比如在开源项目中,从 Forked Repo 提出 PR)。那么最后一个 Code ReviewReviewer 将对后续产生的 push 事件流程负责。

# 最佳实践

# 使用 squash 自动合并

使用 squash 合并,一次 PR 操作只在目标分支产生一个 commit 节点,并且在有权限的情况下删除源分支。

master:
  review:
    - stages:
        - name: automerge
          type: git:auto-merge
          options:
            mergeType: squash
            removeSourceBranch: true

# 使用 auto 自动选择合并类型

如果多人提交走 merge ,否则走 squash

master:
  review:
    - stages:
        - name: automerge
          type: git:auto-merge
          options:
            mergeType: auto

# 建立专用的 CR 群,交叉走查自动合并

  1. 走查通过后自动合并
  2. 记录走查者信息在提交信息中
main:
  pull_request.mergeable:
    - stages:
        - name: CR 通过后自动合并
          type: git:auto-merge
          options:
            mergeType: squash
            mergeCommitMessage: $CNB_LATEST_COMMIT_MESSAGE
          exports:
            reviewedBy: REVIEWED_BY
        - name: notify
          image: tencentcom/wecom-message
          settings:
            robot: 155af237-6041-4125-9340-000000000000
            msgType: markdown
            content: |
              > CR 通过后自动合并 <@${CNB_BUILD_USER}> 
              >  
              > ${CNB_PULL_REQUEST_TITLE}
              > [${CNB_EVENT_URL}](${CNB_EVENT_URL})
              > 
              > ${REVIEWED_BY}

  pull_request:
    - stages:
        # ...省略其它任务
        - name: notify
          image: tencentcom/wecom-message
          options:
            robot: 155af237-6041-4125-9340-000000000000
            msgType: markdown
            content: |
              > ${CURR_REVIEWER_FOR_AT}
              > 
              > ${CNB_PULL_REQUEST_TITLE}
              > [${CNB_EVENT_URL}](${CNB_EVENT_URL})
              > 
              > from ${CNB_BUILD_USER}