---
url: /en/build/internal-steps/git/reviewer.md
---
`git:reviewer`

\==Configure reviewers or assignees== to add or remove reviewers/assignees to a PR,
with the option to specify a range of alternative reviewers/assignees.

Terminology: `reviewer` is the person who reviews the PR, while `assignee` is the person
assigned to handle the PR (shown as the assignee on the PR page). The two are independent,
and this task can add/remove either of them separately.

* [Applicable Events](#git-reviewer-applicable-events)
* [Parameters](#git-reviewer-parameters)
* [Output Results](#git-reviewer-output)
* [Configuration Examples](#git-reviewer-configuration-examples)
* [Best Practices](#git-reviewer-best-practices)

## Applicable Events {#git-reviewer-applicable-events}

* `pull_request`
* `pull_request.target`
* `pull_request.update`

Under `pull_request` and `pull_request.update` events,
the trigger will check if the initiator has permission to operate on reviewers/assignees.
This check is not performed under the `pull_request.target` event. For PRs submitted across repositories,
there may be cases where the initiator lacks permission. In such cases,
it is recommended to use the `pull_request.target` event.

## Parameters {#git-reviewer-parameters}

The list below gives an overview of all `git:reviewer` parameters.

* [type](#git-reviewer-parameters-type): Operation type; add/remove reviewers or assignees
* [reviewers](#git-reviewer-parameters-reviewers): Reviewers or assignees to add or remove
* [count](#git-reviewer-parameters-count): Number of reviewers/assignees to add
* [exclude](#git-reviewer-parameters-exclude): Exclude specified users
* [reviewersConfig](#git-reviewer-parameters-reviewersConfig): File-based or inline reviewer/assignee config
* [role](#git-reviewer-parameters-role): Role scope of members that can be added
* [skip\_on\_wip](#git-reviewer-parameters-skip_on_wip): Whether to skip PRs in the WIP state

Detailed descriptions for each parameter are provided below.

### type {#git-reviewer-parameters-type}

* type: [REVIEW\_OPERATION\_TYPE](#git-reviewer-parameters-type-definitions-REVIEW_OPERATION_TYPE)
* required: `false`
* default: `add-reviewer`

Operation type:

* `add-reviewer`: Add reviewers, selecting a specified number of reviewers from the `reviewers` parameter
* `add-reviewer-from-repo-members`: Select one reviewer directly from repository members and add them as a reviewer
* `add-reviewer-from-group-members`:
  Select one reviewer from the repository's parent organization
  (direct superior organization) and add them as a reviewer
* `add-reviewer-from-outside-collaborator-members`:
  Select one reviewer from the repository's external collaborators and add them as a reviewer
* `remove-reviewer`: Remove specified members from existing reviewers
* `add-assignee`: Add assignees, adding members specified in the `reviewers` parameter
* `remove-assignee`: Remove specified members from existing assignees

### reviewers {#git-reviewer-parameters-reviewers}

* type: `Array<String>` | `String`
* required: `false`

Usernames of reviewers to add or remove. Multiple usernames can be separated by `,` or `;`.

Effective when `type` is `add-reviewer`, `remove-reviewer`, `add-assignee`, or `remove-assignee`.

If both `reviewers` and `reviewersConfig` are set, they are merged as a union;
see [Precedence](#git-reviewer-parameters-reviewersConfig-merge).

### count {#git-reviewer-parameters-count}

* type: `Number`
* required: `false`

Specify the number of reviewers or assignees to add, randomly selecting the specified number of reviewers or assignees.

* When `type` is `add-reviewer` or `add-assignee`, the default value for `count` is the number of `reviewers`,
  meaning all are added.
* When `type` is `add-reviewer-from-repo-members`, `add-reviewer-from-group-members`,
  or `add-reviewer-from-outside-collaborator-members`:
  * If the target branch is a protected branch with a requirement for reviewer approvals,
    the default value for `count` is the number of reviewers required for approval.
  * In other cases, the default value for `count` is 1.

If the number of existing reviewers or assignees is `< count`, then fill up to the specified count.

If the number of existing reviewers or assignees is `>= count`, then no action is taken.

### exclude {#git-reviewer-parameters-exclude}

* type: `Array<String>` | `String`
* required: `false`

Exclude specified users.

### reviewersConfig {#git-reviewer-parameters-reviewersConfig}

* type: [IReviewersConfig](#git-reviewer-parameters-type-definitions-IReviewersConfig) | `String`
* required: `false`

Configuration that matches reviewers/assignees by **changed files**. When a changed file
matches a path rule in the config, the corresponding users are included in the candidate
scope of reviewers/assignees.

Effective when `type` is `add-reviewer` or `add-assignee`.

`reviewersConfig` supports the following two formats. Pick one as needed
(the `String` file-path format is recommended):

| Format | Value | Description |
| --- | --- | --- |
| `String` (simple) | Relative path to a config file | Parsed as CODEOWNERS when the file name (case-insensitive) is `codeowners`; otherwise parsed as JSON |
| Inline object (complex) | `{ "file path": "user1,user2" }` | JSON format only; CODEOWNERS is not supported |

Here, the `key` is the relative file path (prefix match, so subfiles under a directory also match),
and the `value` is the usernames of reviewers or assignees separated by commas `,`.

#### Format 1: Config file path (simple format, recommended)

Pass the relative path to the configuration file. When the file name (case-insensitive)
is `codeowners`, it is parsed as CODEOWNERS format; otherwise, it is parsed as JSON format.

* Parsed as JSON: use the `.json` suffix

```json title="reviewers-config.json"
{
  "./src": "name1,name2",
  ".cnb.yml": "name3"
}
```

* Parsed as CODEOWNERS: the file name is `codeowners` (recommended path: `.cnb/codeowners`)

```text title=".cnb/codeowners"
# Write general rules first, specific rules last
*                       @global-team
*.js                    @fe-team
/src/frontend/          @frontend-owner
/src/frontend/auth.js   @security-team
```

CODEOWNERS syntax rules:

* Each line is `<pattern> @owner1 @owner2 ...`; `pattern` follows gitignore-style matching.
* The last matching pattern wins (write general rules first, specific rules last).
* Lines starting with `#` are comments.
* A pattern with no owners excludes that path.
* Only `@username` owners are currently resolved to repository members;
  email-format and `@org/team` owners are ignored with a warning.

::::: warning Note
The file is read from the workspace at task execution time, which corresponds
to the current ref (for PR events, this is the source branch). This differs from
the repository-level CODEOWNERS approval requirement, which reads from the base branch.
:::::

#### Format 2: Inline object (complex format)

Configure the "file path -> reviewer" mapping inline in `.cnb.yml`.
JSON format only; CODEOWNERS is not supported:

```json title="Inline object structure"
{
  "./src": "name1,name2",
  ".cnb.yml": "name3"
}
```

#### Precedence when combined with `reviewers` {#git-reviewer-parameters-reviewersConfig-merge}

`reviewers` and `reviewersConfig` are **merged (union), not overridden**:

1. First, `reviewersConfig` matches the changed files to produce a set of candidates;
   these candidates are then merged into the list specified by `reviewers`, deduplicated
   into a **single candidate pool**.
2. `count` then decides the final result:
   * If `count` is not specified: **all** users in the candidate pool are added.
   * If `count` is specified: **`count` users are randomly sampled** from the candidate
     pool (all of them if there are fewer than `count`).

Therefore, put common reviewers in `reviewers` and per-directory/file reviewers in
`reviewersConfig`; there is no need to duplicate entries on both sides.

### role {#git-reviewer-parameters-role}

* type: [ROLE\_TYPE](#git-reviewer-parameters-type-definitions-ROLE_TYPE)
* required: `false`

Roles that reviewers or assignees can have include: `Developer`, `Master`, `Owner`. If `Developer` is selected,
members with `Developer` and higher permissions can be added, including `Developer`, `Master`, `Owner`.

### skip\_on\_wip {#git-reviewer-parameters-skip\_on\_wip}

* type: `Boolean`
* required: `false`
* default: `true`

Whether to skip the operation when the pull request is a WIP pull request. The default value is `true`.

* `true`: the operation will be skipped when the pull request is a WIP pull request.
* `false`: the operation will be performed regardless of whether the pull request is a WIP pull request.

### Type Definitions {#git-reviewer-parameters-type-definitions}

#### REVIEW\_OPERATION\_TYPE {#git-reviewer-parameters-type-definitions-REVIEW\_OPERATION\_TYPE}

* `Enum<String>`:
  add-reviewer | add-reviewer-from-repo-members | add-reviewer-from-group-members |
  add-reviewer-from-outside-collaborator-members | remove-reviewer | add-assignee | remove-assignee

#### IReviewersConfig {#git-reviewer-parameters-type-definitions-IReviewersConfig}

```javascript
{
    [key: String]: String
}
```

#### ROLE\_TYPE {#git-reviewer-parameters-type-definitions-ROLE\_TYPE}

* `Enum<String>`: Developer | Master | Owner

## Output Results {#git-reviewer-output}

Output result for adding reviewers:

```json
{
  "reviewers": [],
  "reviewersForAt": []
}
```

Output result for adding assignees:

```json
{
  "assignees": [],
  "assigneesForAt": []
}
```

## Configuration Examples {#git-reviewer-configuration-examples}

* Adding reviewers and assignees:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers
          type: git:reviewer
          options:
            type: add-reviewer
            reviewers: aaa;bbb

        - name: Add Assignees
          type: git:reviewer
          options:
            type: add-assignee
            reviewers: ccc;ddd
```

* Delete reviewers or assignees:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Remove Reviewers
          type: git:reviewer
          options:
            type: remove-reviewer
            reviewers: aaa

        - name: Remove Assignees
          type: git:reviewer
          options:
            type: remove-assignee
            reviewers: aaa
```

* Combining with `ifModify`, adding reviewers and assignees when specific files are modified:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Review for Configuration Changes
          ifModify:
            - ".cnb.yml"
            - "configs/**"
          type: git:reviewer
          options:
            type: add-reviewer
            reviewers: bbb

        - name: Assign for Configuration Changes
          ifModify:
            - ".cnb.yml"
            - "configs/**"
          type: git:reviewer
          options:
            type: add-assignee
            reviewers: ccc
```

* Combining with `if`, adding specific reviewers or assignees under certain conditions:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Release after Hours? Requires Reviewers.
          if: |
            [ $(date +%H) -ge 18 ]
          type: git:reviewer
          options:
            type: add-reviewer
            reviewers: bbb

        - name: Release after Hours? Requires Assignees.
          if: |
            [ $(date +%H) -ge 18 ]
          type: git:reviewer
          options:
            type: add-assignee
            reviewers: ccc
```

* Randomly selecting one person to review the code:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Random Selection
          image: tencentcom/random
          settings:
            from:
              - aaa
              - bbb
          exports:
            result: CURR_REVIEWER
        - name: Show Current Reviewer
          script: echo ${CURR_REVIEWER}
        - name: Add Reviewer
          type: git:reviewer
          options:
            type: add-reviewer
            reviewers: ${CURR_REVIEWER}
```

* Using `reviewersConfig` (config file path) to match reviewers by changed files:

The complete `.cnb.yml`:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers by Changed Files
          type: git:reviewer
          options:
            type: add-reviewer
            # Relative path to the config file; parsed as JSON when it ends with .json
            reviewersConfig: reviewers-config.json
            count: 2
```

The accompanying config file:

```json title="reviewers-config.json"
{
  "frontend": "loviselu,angelzou",
  "orange-ci": "loviselu,cristophwan",
  "infra": "robinzhxie,loviselu"
}
```

* Using `reviewersConfig` (CODEOWNERS format) to match reviewers by changed files:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers by CODEOWNERS
          type: git:reviewer
          options:
            type: add-reviewer
            # Parsed as CODEOWNERS when the file name is codeowners
            reviewersConfig: .cnb/codeowners
```

```text title=".cnb/codeowners"
# Write general rules first, specific rules last
*                       @global-team
/src/frontend/          @frontend-owner
/src/frontend/auth.js   @security-team
```

* Using `reviewersConfig` (inline object) to match reviewers by changed files:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers by Changed Files
          type: git:reviewer
          options:
            type: add-reviewer
            reviewersConfig:
              "./src": "name1,name2"
              ".cnb.yml": "name3"
```

* Using `reviewers` and `reviewersConfig` together (union):

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers
          type: git:reviewer
          options:
            type: add-reviewer
            # Reviewers matched by changed files
            reviewersConfig: reviewers-config.json
            # Common reviewers, unioned with the above and randomly sampled (2)
            reviewers: loviselu,robinzhxie,wenqiuli
            count: 2
```

* Selecting one reviewer from current repository members for review:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewer
          type: git:reviewer
          options:
            type: add-reviewer-from-repo-members
```

## Best Practices {#git-reviewer-best-practices}

### Randomly Assign Reviewers and Notify

Randomly select N reviewers for a PR and send a notification to WeChat Enterprise:

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: Add Reviewers
          type: git:reviewer
          options:
            reviewers: aaa,bbb,ccc,ddd
            count: 2
          exports:
            reviewersForAt: CURR_REVIEWER_FOR_AT
        - name: Notify
          image: tencentcom/wecom-message
          settings:
            msgType: markdown
            robot: "your-robot-key"
            content: |
              > ${CURR_REVIEWER_FOR_AT}
              > ${CNB_PULL_REQUEST_TITLE}
              > [${CNB_EVENT_URL}](${CNB_EVENT_URL})
              > from ${CNB_BUILD_USER}
```

### Auto-Merge after Approval and Notify

```yaml title=".cnb.yml"
main:
  review:
    - stages:
        - name: Auto-Merge after CR Approval
          type: git:auto-merge
          options:
            mergeType: squash
            removeSourceBranch: true
          exports:
            reviewedBy: REVIEWED_BY
        - name: Notify
          image: tencentcom/wecom-message
          settings:
            msgType: markdown
            robot: "your-robot-key"
            content: |
              > Auto-Merge after CR Approval <@${CNB_BUILD_USER}>
              > ${CNB_PULL_REQUEST_TITLE}
              > [${CNB_EVENT_URL}](${CNB_EVENT_URL})
              > ${REVIEWED_BY}
```
