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 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 |
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.
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" }
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 toMaxWithBlock
, usingsubmittableIf = -label:My-Label=MIN
is equivalent toAnyWithBlock
, usingsubmittableIf = label:My-Label=MAX
is equivalent to usingMaxNoBlock
).
-
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 theuser=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.
-
ERROR
The evaluation of any of the applicableIf, submittableIf or overrideIf expressions resulted in an error, i.e. because the expression is not parseable.
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.
[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 = -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
- 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 likehas:submodule-update,base=1
, orhas:submodule-update,base=2
. In these cases, the operator returns true if the diff of the latest patchset against parent number identified bybase
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 thejava.util.regex
engine. When using regular expressions, special characters should be double escaped because the config is parsed twice when the server reads theproject.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 followingapplicableIf
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 givenLabelExpression
. TheLabelExpression
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/.*
Require a footer
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.
Part of Gerrit Code Review