As part of the code review process, project owners need to configure rules that govern when changes become submittable. For example, an admin might want to prevent changes from being submittable until at least a “+2” vote on the “Code-Review” label is granted on a change. Admins can define submit requirements to enforce submittability rules for changes.

Configuring Submit Requirements

Site administrators and project owners can define submit requirements in the project config. A submit requirement has the following fields:

submit-requirement.Name

A name that uniquely identifies the submit requirement. Submit requirements can be overridden in child projects if they are defined with the same name in the child project. See the inheritance section for more details.

submit-requirement.Name.description

A detailed description of what the submit requirement is supposed to do. This field is optional. The description is visible to the users in the change page upon hovering on the submit requirement to help them understand what the requirement is about and how it can be fulfilled.

submit-requirement.Name.applicableIf

A query expression that determines if the submit requirement is applicable for a change. For example, administrators can exclude submit requirements for certain branch patterns. See the exempt branch example.

Often submit requirements should only apply to branches that contain source code. In this case this parameter can be used to exclude the refs/meta/config branch from a submit requirement:

  applicableIf = -branch:refs/meta/config

This field is optional, and if not specified, the submit requirement is considered applicable for all changes in the project.

submit-requirement.Name.submittableIf

A query expression that determines when the change becomes submittable. This field is mandatory.

submit-requirement.Name.overrideIf

A query expression that controls when the submit requirement is overridden. When this expression is evaluated to true, the submit requirement state becomes OVERRIDDEN and the submit requirement is no longer blocking the change submission. This expression can be used to enable bypassing the requirement in some circumstances, for example if the change owner is a power user or to allow change submission in case of emergencies.

This field is optional.

submit-requirement.Name.canOverrideInChildProjects

A boolean (true, false) that determines if child projects can override the submit requirement.

The default value is false.

Evaluation Results

When submit requirements are configured, their results are returned for all changes requested by the REST API with the SubmitRequirementResultInfo entity.

Submit requirement results are produced from the evaluation of the submit requirements in the project config ( See Configuring Submit Requirements) as well as the conversion of the results of the legacy submit rules to submit requirement results. Legacy submit rules are label functions (see config labels), custom and prolog submit rules.

The status field can be one of:

  • NOT_APPLICABLE

    The applicableIf expression evaluates to false for the change.

  • UNSATISFIED

    The submit requirement is applicable (applicableIf evaluates to true), but the evaluation of the submittableIf and overrideIf expressions return false for the change.

  • SATISFIED

    The submit requirement is applicable (applicableIf evaluates to true), the submittableIf expression evaluates to true, and the overrideIf evaluates to false for the change.

  • OVERRIDDEN

    The submit requirement is applicable (applicableIf evaluates to true) and the overrideIf expression evaluates to true.

    Note that in this case, the change is overridden whether the submittableIf expression evaluates to true or not.

  • FORCED

    The change was merged directly bypassing code review by supplying the submit push option while doing a git push.

  • ERROR

    The evaluation of any of the applicableIf, submittableIf or overrideIf expressions resulted in an error.

Query Expression Syntax

All applicableIf, submittableIf and overrideIf expressions use the same syntax and operators available for searching changes. In addition to that, submit requirements support extra operators.

Submit Requirements Operators

authoremail:'EMAIL_PATTERN'

An operator that returns true if the change author’s email address matches a specific regular expression pattern. The dk.brics.automaton library is used for the evaluation of such patterns.

committeremail:'EMAIL_PATTERN'

An operator that returns true if the change committer’s email address matches a specific regular expression pattern. The dk.brics.automaton library is used for the evaluation of such patterns.

uploaderemail:'EMAIL_PATTERN'

An operator that returns true if the change uploader’s primary email address matches a specific regular expression pattern. The dk.brics.automaton library is used for the evaluation of such patterns.

distinctvoters:'[Label1,Label2,…​,LabelN],value=MAX,count>1'

An operator that allows checking for distinct voters across more than one label.

2..N labels are supported, filtering by a value (MIN,MAX,integer) is optional. Count is mandatory.

Examples: distinctvoters:[Code-Review,Trust],value=MAX,count>1

distinctvoters:[Code-Review,Trust,API-Review],count>2

is:true

An operator that always returns true for all changes. An example usage is to redefine a submit requirement in a child project and make the submit requirement always applicable.

is:false

An operator that always returns false for all changes. An example usage is to redefine a submit requirement in a child project and make the submit requirement always non-applicable.

has:submodule-update

An operator that returns true if the diff of the latest patchset against the default parent has a submodule modified file, that is, a ".gitmodules" or a git link file.

The optional base parameter can also be supplied for merge commits like has:submodule-update,base=1, or has:submodule-update,base=2. In these cases, the operator returns true if the diff of the latest patchset against parent number identified by base has a submodule modified file. Note that the operator will return false if the base parameter is greater than the number of parents for the latest patchset for the change.

file:"'<filePattern>',withDiffContaining='<contentPattern>'"

An operator that returns true if the latest patchset contained a modified file matching <filePattern> with a modified region matching <contentPattern>.

Both <filePattern> and <contentPattern> support regular expressions if they start with the '^' character. Regular expressions are matched with the java.util.regex engine. When using regular expressions, special characters should be double escaped because the config is parsed twice when the server reads the project.config file and when the submit-requirement expressions are parsed as a predicate tree. For example, to match against modified files that end with ".cc" or ".cpp" the following applicableIf expression can be used:

  applicableIf = file:\"^.*\\\\.(cc|cpp)$\"

Below is another example that uses both <filePattern> and <contentPattern>:

  applicableIf = file:\"'^.*\\\\.(cc|cpp)$',withDiffContaining='^.*th[rR]ee$'\"

If no regular expression is used, the text is matched by checking that the file name contains the file pattern, or the edits of the file diff contain the edit pattern.

label:labelName=+1,user=non_contributor

Submit requirements support an additional user=non_contributor argument for labels that returns true if the change has a label vote matching the specified value and the vote is applied from a gerrit account that’s not the uploader, author or committer of the latest patchset. See the documentation for the labels operator in the user search page.

Unsupported Operators

Some operators are not supported with submit requirement expressions.

is:submittable

Cannot be used since it will result in recursive evaluation of expressions.

Inheritance

Child projects can override a submit requirement defined in any of their parent projects. Overriding a submit requirement overrides all of its properties and values. The overriding project needs to define all mandatory fields.

Submit requirements are looked up from the current project up the inheritance hierarchy to “All-Projects”. The first project in the hierarchy chain that sets canOverrideInChildProjects to false prevents all descendant projects from overriding it.

If a project disallows a submit requirement from being overridden in child projects, all definitions of this submit requirement in descendant projects are ignored.

To remove a submit requirement in a child project, administrators can redefine the requirement with the same name in the child project and set the applicableIf expression to is:false. Since the submittableIf field is mandatory, administrators need to provide it in the child project but can set it to anything, for example is:false but it will have no effect anyway.

Trigger Votes

Trigger votes are label votes that are not associated with any submit requirement expressions. Trigger votes are displayed in a separate section in the change page. For more about configuring labels, see the config labels documentation.

Examples

Code-Review Example

To define a submit requirement for code-review that requires a maximum vote for the “Code-Review” label from a non-uploader without a maximum negative vote:

[submit-requirement "Code-Review"]
	description = A maximum vote from a non-uploader is required for the \
	              'Code-Review' label. A minimum vote is blocking.
	submittableIf = label:Code-Review=MAX,user=non_uploader AND -label:Code-Review=MIN
	canOverrideInChildProjects = true

Exempt a branch Example

We could exempt a submit requirement from certain branches. For example, project owners might want to skip the 'Code-Style' requirement from the refs/meta/config branch.

[submit-requirement "Code-Style"]
  description = Code is properly styled and formatted
  applicableIf = -branch:refs/meta/config
  submittableIf = label:Code-Style=+1 AND -label:Code-Style=-1
  canOverrideInChildProjects = true

Branch configuration supports regular expressions as well, e.g. to exempt 'refs/heads/release/*' pattern, when migrating from the label Submit-Rule:

[label "Verified"]
  branch = refs/heads/release/*

The following SR can be configured:

[submit-requirement "Verified"]
  submittableIf = label:Verified=MAX AND -label:Verified=MIN
  applicableIf = branch:^refs/heads/release/.*

It’s possible to use a submit requirement to require a footer to be present in the commit message.

[submit-requirement "Bug-Footer"]
  description = Changes must include a 'Bug' footer
  applicableIf = -branch:refs/meta/config AND -hasfooter:\"Bug\"
  submittableIf = hasfooter:\"Bug\"

Testing Submit Requirements

The Check Submit Requirement change endpoint can be used to test submit requirements on any change. Users are encouraged to test submit requirements before adding them to the project to ensure they work as intended.

Request
  POST /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/check.submit_requirement HTTP/1.0
  Content-Type: application/json; charset=UTF-8

    {
      "name": "Code-Review",
      "submittability_expression": "label:Code-Review=+2"
    }
Response
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "name": "Code-Review",
    "status": "SATISFIED",
    "submittability_expression_result": {
      "expression": "label:Code-Review=+2",
      "fulfilled": true,
      "passingAtoms": [
        "label:Code-Review=+2"
      ]
    },
    "is_legacy": false
  }