Submit requirements are rules that define when a change can be submitted. This page describes how to configure them.

Configuring Submit Requirements

Submit requirements are defined as submit-requirement subsections in the project.config file. The subsection name defines the name of the submit requirement.

Note
There are multiple options how to update project.config files, please refer to the project config documentation.
Tip
When modifying submit requirements it’s recommended to test them before updating them in the project configuration.
Warning

When adding submit requirements think about whether they should apply to the refs/meta/config branch (see the applicableIf description on how to exempt the refs/meta/config branch from a submit requirement). Since submit requirements are stored as part of the project configuration in the refs/meta/config branch, changing them through code review requires to pass the submit requirements that apply to the refs/meta/config branch. Hence by misconfiguring submit requirements for the refs/meta/config branch you can make further updates to submit requirements through code review impossible. If this happens the submit requirements can be restored by a direct push to the refs/meta/config branch.

If direct pushes are disabled or not allowed project owners can directly update the submit requirements via the Update Submit Requirement REST endpoint.

Example:
  curl -X PUT --header "Content-Type: application/json" -d '{"name": "Foo-Review", "description": "At least one maximum vote for the Foo-Review label is required", "submittability_expression": "label:Foo-Review=MAX AND -label:Foo-Review=MIN", "applicability_expression": "-branch:refs/meta/config", "canOverrideInChildProjects": true}' "https://<HOST>/a/projects/My%2FProject/submit_requirements/Foo-Review"

Tip: Googlers should use gob-curl instead of curl so that authentication is handled automatically.

Testing Submit Requirements

When modifying submit requirements it’s recommended to test them before updating them in the project configuration.

To test a submit requirement on a selected change project~branch~changeId use the Check Submit Requirement REST endpoint.

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
  }

Alternatively you can make a change that updates a submit requirement in the project.config file, upload it for review to the refs/meta/config branch and then load it from that change which is in review to test it against a change.

Request

  POST /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/check.submit_requirement?sr-name=Code-Review&refs-config-change-id=myProject~refs/meta/config~Ibc1409aef8bf0a16a76f9fa9a928bd505228fa1d HTTP/1.0

In the above example myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940 is the change against which the submit requirement is tested, Code Review is the name of the submit requirement that is tested and myProject~refs/meta/config~Ibc1409aef8bf0a16a76f9fa9a928bd505228fa1d is the change from which the Code Review submit requirement is loaded. Change myProjectrefs/meta/configIbc1409aef8bf0a16a76f9fa9a928bd505228fa1d must be a change that touches the project.config file in the refs/meta/config branch and the project.config file must contain a submit requirement with the name Code-Review.

Show Submit Requirements on Dashboards

Gerrit offers dashboards that provide an overview over a set of changes (e.g. user dashboards shows changes that are relevant to the user, change list dashboards show changes that match a change query). To understand the state of the changes knowing the status of their submit requirements is important, but submit requirements are manifold and dashboards have only limited screen space available, so showing all submit requirements in dashboards is hardly possible. This is why administrators must decide which are the most important submit requirements that should be shown on dashboards. They can configure these submit requirements in gerrit.config by setting the dashboard.submitRequirementColumns option.

Note
In order to save screen space submit requirement names on dashboards are abbreviated, e.g. a submit requirement called Foo-Bar is shown as FB.

Inheritance

Submit requirements are inherited from parent projects. Child projects may override an inherited submit requirement by defining a submit requirement with the same name, but only if overriding the submit requirement is allowed (see canOverrideInChildProjects field). Overriding an inherited submit requirement always overrides the complete submit requirement definition, overriding single fields only is not possible.

Note
To remove an inherited submit requirement in a child project, set both the applicableIf expression and the submittableIf expression to is:false.
Note
If overriding a submit requirement is disallowed in a parent project, submit requirements with the same name in child projects, that would otherwise override the inherited submit requirement, are ignored.

Labels and Submit Requirements

Labels define voting categories for reviewers to score changes. Often a label is accompanied by a submit requirement to check the votes on the label, e.g. with a submittableIf expression that checks that:

  • the label was approved: label:My-Label=MAX

  • the label has no veto: -label:My-Label=MIN

  • the label was not self-approved: label:My-Label=MAX,user=non_uploader

  • the label was approved by multiple users: label:My-Label,count>1

Submit requirements that check votes for a single label often have the same name as the label, e.g.:

[label "Code-Review"]
  function = NoBlock
  value = -2 This shall not be submitted
  value = -1 I would prefer this is not merged as is
  value = 0 No score
  value = +1 Looks good to me, but someone else must approve
  value = +2 Looks good to me, approved
  defaultValue = 0
[submit-requirement "Code-Review"]
  description = At least one maximum vote for label 'Code-Review' is required
  submittableIf = label:Code-Review=MAX,user=non_uploader AND -label:Code-Review=MIN
  canOverrideInChildProjects = true

Trigger Votes

Trigger votes are votes on labels that are not associated with any submit requirement expressions, i.e. the submittability of changes doesn’t depend on these votes.

Voting on labels that have no impact on the submittability of changes usually serves the purpose to trigger processes, e.g. a vote on a Presubmit-Ready label can be a signal to run presubmit integration tests. Hence these votes are called trigger votes.

Trigger votes are displayed in a separate section in the change page.

Deprecated ways to control when changes can be submitted

Using submit requirements is the recommended way to control when changes can be submitted. However, historically there are other ways for this, which are still working, although they are deprecated:

  • Label functions:

    Label definitions can contain a function that impacts the submittability of changes (MaxWithBlock, AnyWithBlock, MaxNoBlock). These functions are deprecated and setting them is no longer allowed, however if they are (already) set for existing label definitions they are still respected. For new labels the function should be set to NoBlock and then submit requirements should be used to control when changes can be submitted (using submittableIf = label:My-Label=MAX AND -label:My-Label=MIN is equivalent to MaxWithBlock, using submittableIf = -label:My-Label=MIN is equivalent to AnyWithBlock, using submittableIf = label:My-Label=MAX is equivalent to using MaxNoBlock).

  • ignoreSelfApproval flag on labels:

    Labels can be configured to ignore self approvals. This flag only works in combination with the deprecated label functions (see above) and hence it is deprecated as well. Instead use a submittableIf expression with the label operator and the user=non_uploader argument. See the Code Review submit requirement example.

  • Prolog rules:

    Projects can define prolog submit rules that control when changes can be submitted. It’s still possible to have Prolog submit rules, but they are deprecated and support for them will be dropped in future Gerrit releases. Hence it’s recommended to use submit requirements instead.

When checking whether changes can be submitted Gerrit takes results of label functions and Prolog submit rules into account, in addition to the submit requirements.

Plugin provided submit rules

Plugins can contribute submit rules by implementing the SubmitRule extension point (see Pre-submit Validation Plugins).

When checking whether changes can be submitted Gerrit takes results of plugin-provided submit rules into account, in addition to the submit requirements.

Submit Requirement Evaluation

Submit requirements are evaluated whenever a change is updated. To decide whether changes can be submitted, the results of label functions, Prolog submit rules and plugin-provided submit rules are taken into account, in addition to the submit requirements. For this the results of label functions, Prolog submit rules and plugin-provided submit rules are converted to submit requirement results.

Submit requirement results are returned in the REST API when retrieving changes with the SUBMIT_REQUIREMENTS option (e.g. via the Get Change Detail REST endpoint or the Query Changes REST endpoint). If requested, submit requirements are included as SubmitRequirementResultInfo entities into ChangeInfo (field submit_requirements).

The status field of submit requirement results 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 submit requirement is overridden regardless of 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.

Note
Gerrit can be configured to return a 500 internal server error response instead of setting the status to ERROR (see the change.propagateSubmitRequirementErrors option that can be set in gerrit.config).

submit-requirement subsection

Each submit-requirement subsection defines a submit requirement.

The name of the submit-requirement subsection defines the name that uniquely identifies the submit requirement. It is shown to the user in the web UI when the submit requirement is applicable.

Note
By using the same name as an inherited submit requirement, the inherited submit requirement can be overridden, if overriding is allowed (see canOverrideInChildProjects field). Details about overriding submit requirements are explained in the inheritance section.

Submit requirements must at least define a submittableIf expression that defines when a change can be submitted.

Example:
[submit-requirement "Verified"]
  description = CI result status for build and tests is passing
  applicableIf = -branch:refs/meta/config
  submittableIf = label:Verified=MAX AND -label:Verified=MIN
  canOverrideInChildProjects = true

The fields that can be set for submit requirements are explained below.

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 user 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. If a submit requirement is not applicable it is hidden in the web UI. For example, this allows to exempt a branch from the submit requirement.

Tip

Often submit requirements should only apply to branches that contain source code. In this case the applicableIf condition can be used to exclude the refs/meta/config branch from the 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 can be submitted. 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 uploader is a trusted bot 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.

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

label:'<label><operator><value>,users=human_reviewers'

Extension of the label predicate that allows matching changes that have a matching vote from all human reviewers. Votes from service users (members of the Service Users group) and the change owner are ignored.

If reviewers by email are present then "user=all_reviewers" doesn’t match if the expected value is other than 0. Reviewers by email are reviewers that don’t have a Gerrit account. Without Gerrit account they cannot vote on the change, which means changes that have any such reviewers never match when a vote from all reviewers is expected.

If a change has no human reviewers, this operator doesn’t match (because a human review is required but no human reviewer is present).

Examples: label:Code-Review=MAX,users=human_reviewers

label:Code-Review>=1,users=human_reviewers

The 'users' arg cannot be combined with other arguments ('count', 'user', 'group').

'label:Code-Review=MAX,users=human_reviewers' can be used to implement "Want-Code-Review-From-All" functionaly, see link#require-code-review-approvals-from-all-human-reviewers-example[examples below].

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:LabelExpression

The label operator allows to match changes that have votes matching the given LabelExpression. The LabelExpression can be anything that’s supported for the label query operator.

If used in submit requirement expressions, this operator supports an additional user=non_contributor argument. This argument works similar to the user=non_uploader argument and returns true if the change has a matching label vote that is applied by a user that’s not the uploader, author or committer of the latest patchset.

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.

Examples

Require Code-Review approval from a non-uploader

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

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\"

Require Code-Review approvals from all human reviewers

The following submit requirement requires a 'Code-Review' approval ('Code-Review+1' or 'Code-Review+2') from all human reviewers of the change. Votes from service users (members of the Service Users group) and the change owner are ignored.

The 'applicableIf' condition makes this submit requirement show up in the UI only if it is not satisfied (to keep the submit requirement showing when it is satisfied omit the 'applicableIf' condition).

If a change has no human reviewers, this submit requirement is unsatisfied (because a human review is required but no human reviewer is present).

[submit-requirement "Want-Code-Review-From-All"]
  description = A 'Code-Review' vote is required from all human \
                reviewers (service users that are reviewers are \
                ignored).
  applicableIf = -label:Code-Review>=1,users=human_reviewers
  submittableIf = label:Code-Review>=1,users=human_reviewers

It is possible to configure the 'Want-Code-Review-From-All' submit requirement so that it only applies when a 'Want-Code-Review: all' footer is present in the commit message. This way users can enable this submit requirement on demand by including this footer into their commit messages.

The 'applicableIf' condition checks for the 'Want-Code-Review: all' footer and makes this submit requirement show up in the UI only if it is not satisfied (to keep the submit requirement showing when it is satisfied omit the '-label:Code-Review>=1,users=human_reviewers' predicate from the 'applicableIf' condition).

Note, the footer key cannot contain underscores (e.g. using 'Want_Code_Review: all' as the footer does not work).

[submit-requirement "Want-Code-Review-From-All"]
  description = A 'Code-Review' vote is required from all human \
                reviewers (service users that are reviewers are \
                ignored).
  applicableIf = footer:\"Want-Code-Review: all\" -label:Code-Review>=1,users=human_reviewers
  submittableIf = label:Code-Review>=1,users=human_reviewers

For more information about the "users=human_reviewers" arg see above.