In this part we describe how to specify which events in Gerrit (E.g.: “Change Merged”, or “User ‘John Doe’ voted ‘+2’ for ‘Code-Review’ on a change”) trigger which actions (e.g.: “Set issue’s status to ‘Resolved’”) on the ITS.
Actions on the ITS and conditions for the action to take place are configured through rule bases. A rule base is a git config file and may contain an arbitrary number of rules. Each rule can have an arbitrary number of conditions and actions. A rule fires all associated actions, once all of its conditions are met.
A simple rule bases file may look like
[rule "rule1"]
event-type = change-merged
action = add-standard-comment
[rule "rule2"]
event-type = comment-added
approvalCodeReview = -2,-1
action = add-comment Oh my Goodness! Someone gave a negative code review in Gerrit on an associated change.
This snippet defines two rules (rule1, and rule2). On merging a change that’s associated to some issues, rule1 adds a predefined standard comment for “Change Merged” to each such issue. If someone adds a comment to a change that is associated to some issues and votes “-2”, or “-1” for “Code-Review”, rule2 adds the comment “Oh my Goodness! Someone gave a negative code review in Gerrit on an associated change.” to each such issue.
The order of rules in a rule base file need not be respected. So in the above example, do not rely on rule1 being evaluated before rule2.
Rule bases can be defined in two scopes:
Global rules are picked up by all configured ITS plugins and they are defined in a rule base file named actions.config.
Plugin specific rules are picked up only by its-storyboard plugin and they are defined in a rule base file named actions-its-storyboard.config.
A second aspect of rules bases scope is what projects they apply to; in this case the rules can be:
The generic scope refers to rules that apply to all projects that enable ITS integration on the gerrit site; they are defined on rule base files located inside the gerrit_site/etc/its/ folder.
Project-specific rules are defined on rule base files located on the refs/meta/config branch of a project and they apply exclusively to the project that defines them (or that inherits them) and, possibly, to child projects (see further explanations about rules inheritance below). Project specific rules take precedence over generic rules, i.e, when they are defined, generic rules do not apply to the project.
Thus, to define global generic rules, i.e., rules that are picked up by all the ITS plugins and that apply to all the projects that enable any ITS integration, they should be defined in the gerrit_site/etc/its/actions.config rule base file.
Rules defined in the gerrit_site/etc/its/actions-its-storyboard.config rule base file have generic but plugin specific scope, i.e., they apply to all projects on the gerrit site that enable integration with its-storyboard.
On the other hand, if the rule base file actions.config is created on the refs/meta/config branch of project ‘P’, the rules defined on this file will have global but project specific scope, i.e, they apply to all the ITS integrations defined for this project. Thus, if project ‘P’ integrates with ITS system ‘x’ and with ITS system ‘y’, the rules are applied to these two ITS integrations.
Contrarily, rules defined on the rule base file actions-its-storyboard.config created on the refs/meta/config branch of project ‘P’ have project and plugin specific scope, i.e., they apply only to the its-storyboard integration defined for project ‘P’.
Finally, is important to notice that if global and plugin specific rules are defined, the final set of rules applied is the merge of them and this is true either if they are defined in generic or project specific scope.
For project specific rules, i.e., those defined on the refs/meta/config branch of a project, inheritance is honored, similar to what is done in other cases of project configurations.
Thus, if project ‘P’ defines project specific rules, these are applied to children projects of project ‘P’ that enable an ITS integration.
This inheritance, however, is capped at the closest level, which means that if a project defines at least one of the rule bases files, (actions.config or actions-its-storyboard.config), the presence of these files is not evaluated for any of the project’s parents.
Thence, and continuing the example, if project ‘Q’ is a child of project ‘P’ and project ‘Q’ enables ITS integration, rules defined in project ‘P’ apply to project ‘Q’. If however, project ‘Q’ defines its own set of rules, either on file actions.config or actions-its-storyboard.config (or both), the rules defined by project ‘P’ no longer apply to project ‘Q’ , i.e., rules defined in project ‘Q’ override and replace any rules defined on any parent project.
The same applies to the rules defined at the site level: if any project defines their own rule base files, the global ones defined in the gerrit_site/etc/its/ folder do not apply to this project.
Each rule consists of three items: A name, a set of conditions, and a set of actions.
The rule’s name (rule1, and rule2 in the above example) is currently not used and only provided for convenience.
For each rule the option action is interpreted as action. Any other option of a rule is considered a condition.
Each of a rule’s actions is taken for events that meet all of a rule’s conditions. If a rule contains more than one action specifications, the order in which they are given need not be respected.
There is no upper limit on the number of elements in a rules set of conditions, and set of actions. Each of those sets may be empty.
The conditions are lines of the form
name = value1, value2, ..., valueN
and match (if ‘value1’ is not !), if the event comes with a property ‘name’ having ‘value1’, or ‘value2’, or …, or ‘valueN’. So for example to match events that come with an association property having subject, or footer-Bug, the following condition can be used:
association = subject,footer-Bug
If ‘value1’ is !, the conditon matches if the event does not come with a property ‘name’ having ‘value2’, or …, or ‘valueN’. So for example to match events that do not come with a status property having DRAFT, the following condition can be used:
status = !,DRAFT
The properties exposed by events depend on the kind of event.
For all events, the event’s class name is provided in the event property. Most native Gerrit events provide the event-type property. So event-type (or event for other events fired by plugins) allows you to write filters that fire only for a certain type of event.
The common properties for each event are
eventissueissue being 23, and once with issue being 47).associationissue got associated to this event. See [Property: association][property-association].its-nameits-storyboard). This property can be used to make a rule in the rulebase match only for certain ITS plugins, if more than one is installed.For example
[rule "someRuleForBugzillaOnly"]
its-name = its-bugzilla
approvalCodeReview = -2
action = add-comment Heya Bugzilla users, the change had a -2 Code-Review approval.
[rule "someRuleForJiraOnly"]
its-name = its-jira
approvalCodeReview = -2
action = add-comment Dear JIRA users, the change had a -2 Code-Review approval.
would report the “Heya Bugzilla…” text only through its-bugzilla for changes that had a -2 Code-Review and have an association through its-bugzilla. And for changes that had a -2 Code-Review and have an association through its-jira, its-jira would report “Dear Jira users, …”.
The further properties are listed in the event’s corresponding subsection below:
associationassociationThe property association describes how the issue got associated to this event.
An event typically has several association properties. Possible values are:
somewheresubjectbodyfooterfooter-<Key>So for example, if the footer would contain a line
Fixes-Issue: issue 4711
then a property association with value footer-Fixes-Issue would get added to the event for issue “4711”.
added@<Association-Value>association property is not set for RefUpdatedEvents)issue id occurs at <Association-Value> in the most recent patch set of the change, and either the event is for patch set 1 or the issue id does not occur at <Association-Value> in the previous patch set.
So for example if issue “4711” occurs in the subject of patch set 3 (the most recent patch set) of a change, but not in patch set 2. When adding a comment to this change, the event for issue “4711” would get a property ‘association’ with value added@subject.
abandonerEmailabandonerNameabandonerUsernameeventcom.google.gerrit.server.events.ChangeAbandonedEventevent-typechange-abandonedreasonIn addition to the above properties, the event also provides properties for the abandoned [Change][common-properties-for-events-on-a-change], and its most recent [Patch Set][common-properties-for-events-on-a-patch-set].
eventcom.google.gerrit.server.events.ChangeMergedEventevent-typechange-mergedsubmitterEmailsubmitterNamesubmitterUsernameIn addition to the above properties, the event also provides properties for the merged [Change][common-properties-for-events-on-a-change], and its most recent [Patch Set][common-properties-for-events-on-a-patch-set].
eventcom.google.gerrit.server.events.ChangeRestoredEventevent-typechange-restoredreasonrestorerEmailrestorerNamerestorerUsernameIn addition to the above properties, the event also provides properties for the restored [Change][common-properties-for-events-on-a-change], and it’s most recent [Patch Set][common-properties-for-events-on-a-patch-set].
NOTE: For consistency with the other events, the author-... properties of the CommentAddedEvent do not refer to the author of the comment, but refer to the author of the change’s latest patch set. The author of the comment is accessible via the commenter-... properties.
commenterEmailcommenterNamecommenterUsernamecommenteventcom.google.gerrit.server.events.CommentAddedEvent+event-typecomment-addedFor each new or changed approval that has been made for this change, a property of key approval<LabelName> and the approval’s value as value is added. So for example voting “-2” for the approval “Code-Review” would add the following property:
approvalCodeReview-2In addition to the above properties, the event also provides properties for the [Change][common-properties-for-events-on-a-change] the comment was added for, and it’s most recent [Patch Set][common-properties-for-events-on-a-patch-set].
eventcom.google.gerrit.server.events.PatchSetCreatedEventevent-typepatchset-createdIn addition to the above properties, the event also provides properties for the uploaded [Patch Set][common-properties-for-events-on-a-patch-set], and the [Change][common-properties-for-events-on-a-change] it belongs to.
eventcom.google.gerrit.server.events.RefUpdatedEventevent-typeref-updatedprojectrefrefs/heads/master).refSuffixmaster).refPrefixrefs/heads/).revisionrevisionOldsubmitterEmailsubmitterNamesubmitterUsernameeventcom.google.gerrit.server.events.WorkInProgressStateChangedEventevent-typewip-state-changedchangerEmailchangerNamechangerUsernameeventcom.google.gerrit.server.events.PrivateStateChangedEventevent-typeprivate-state-changedchangerEmailchangerNamechangerUsernamebranchchangeIdchangeNumberchangeUrlformatChangeUrlownerEmailownerNameownerUsernameprojectsubjectcommitMessagestatusnull, NEW, SUBMITTED, MERGED, or ABANDONED )topicprivatewipauthorEmailauthorNameauthorUsernamecreated-ondeletionsinsertionsparentspatchSetNumberrefrefs/changes/11/4711/5).revisionuploaderEmailuploaderNameuploaderUsernamesourceits or gerrit. its sourced events are fired by its actions. e.g. fire-event-on-commits action fires its sourced events. gerrit sourced events are directly fired by the Gerrit event system.Lines of the form
action = name param1 param2 ... paramN
represent the action name being called with parameters param1, param2, … paramN.
The following actions are available:
add-comment][action-add-comment]add-standard-comment][action-add-standard-comment]add-soy-comment][action-add-soy-comment]create-version-from-property][action-create-version-from-property]log-event][action-log-event]Further actions may be provided by its-storyboard.
The add-comment action adds the given parameters as comment to any associated rule.
So for example
action = add-comment This is a sample command
would add a comment “This is a sample command” to associated issues.
If no parameters are given, no comment gets added.
The add-standard-comment action adds predefined comments to associated issues for change abandoned, merged, restored, and patch set created events. For other events, no comment is added to the associated issues.
The added comments contain the person responsible for the event (abandoner, merger, …), the change’s subject, a reason (if one has been given), and a link to the change.
The add-soy-comment action renders a Closure template (soy) for the event and adds the output as comment to any associated issue.
So for example
action = add-soy-comment TemplateName
would render the template etc/its/templates/TemplateName.soy add the output as comment to associated issues.
example for what the soy template will look like (note @param is required with correct variables.)
{namespace etc.its.templates}
{template TemplateName kind="text"}
{@param changeNumber: string}
{@param formatChangeUrl: string}
Comment for change {$changeNumber} added. See {$formatChangeUrl}
{/template}
Any [property][event-properties] of the event may be used from templates. So for example $subject in the above example refers to the event’s subject property, and $changeNumber would refer to the change’s number.
The add-property-to-field action adds an event property value to an ITS designated field.
The field is expected to be able to hold multiple values. The ITS field value deduplication depends on the its implementation.
Example with the event property branch and a field identified as labels:
action = add-property-to-field branch labels
The create-version-from-property action creates a version in the ITS project by using an event property value as the version value.
This is useful when you want to create a new version in the ITS when a tag is created in the Gerrit project.
Example with the event property ref:
action = create-version-from-property ref
The fire-event-on-commits action start by collecting commits using a collector then fire the event on each collected commit.
This is useful when you want to trigger rules on a multiple past commits.
Available collectors are:
since-last-tag: Collects all commits between the current ref and previous tagTo avoid to trigger issue actions twice for the same event, you should condition your rule on the event property source.
Example:
action = fire-event-on-commits since-last-tag
The log-event action appends the event’s properties to Gerrit’s log.
Logging happens at the info level per default, but can be overriden by adding the desired log level as parameter. Supported values are error, warn, info, and debug). So for example
action = log-event error
appends the event’s properties to Gerrit’s log at error level. All other parameters are ignored.
This action is useful, when testing rules or trying to refine conditions on rules, as it make the available properties visible.