SDM query language
|CloudBees SDM is a preview, with early access for select preview members. Product features and documentation are frequently updated. If you find an issue or have a suggestion, please contact CloudBees Support. Learn more about the preview program.|
The same expression syntax is for both the target filter and criteria. The most basic expression is a comparison of the following form:
<PATH> <OPERATOR> <VALUE>
On the left-hand side, the
<PATH> is made up of field names, joined with periods. The path starts at the selected data type. For example, if the type is
GithubPullRequest, then the path could be
author.login. The path can also traverse relationships to other data types, for example:
repository.name, where the
. indicates that
name is a child value of
On the right-hand side,
<VALUE> may be a string in single (
') or double quotes (
"), an integer or floating-point number, a boolean (
null. The type of the value should match the type of the field at the end of the path. For fields of type
DateTime, the value may be a string that represents a time, encoded as per '2007-12-03T10:15:30'. For fields of type
Timestamp, you need to compare against an integer. The value can also use the function
now() that represents the point in time at which the policy is evaluated. The function takes an optional string argument that represents a delta from the current time in days and/or hours, for example,
now('-1 day 6 hours') or
In the center, the
<OPERATOR> compares the field at the end of the path with the given value. For a numeric or date/time field, the valid operators are
>=. For string fields, the
~ operator can be used to compare against a POSIX regular expression, for example,
title ~ '.WIP.'. For boolean fields and comparison with
null, only the
!= operators are valid.
In a comparison, the path must only include single-valued fields. For list fields, use the
size()function returns the number of items in the list. The size can then be used for a numeric comparison, for example,
reviewRequests.size() > 0.
average()function takes the name of a numeric field as an argument and returns the average of the values for that field in the list. The average can then be used for numeric comparison, for example,
builds.average(duration) > 20.
any()function evaluates to
trueif any of the items in the list match the expression passed as an argument to the function, for example,
reviewRequests.any(requestedReviewer.login = 'xxx'). The
<PATH>expressions in the
anyargument are evaluated relative to the items in the list
none()function is the inverse of
any(): it evaluates to
trueif none of the items in the list match the expression.
For lists that represent relationships to other types, the
last() functions may also be used.
orderBy()function takes one or more arguments, separated by commas, with each being the name of a field used to order the list. The default order is ascending. The field name can be wrapped by the
desc()function to sort in descending order. For example,
pullRequestReviews.orderBy(author.login, desc(submittedAt))would sort the pull request reviews firstly by author login in ascending alphabetical order and then, for each login, in descending order of submission time, i.e., with the most recent submission first.
first()function returns the first value in a list.
last()function returns the last value in a list.
After a call to
last() functions can be used to retrieve the first and last item from the ordered list respectively. For example,
pullRequestReviews.orderBy(submittedAt).last().state = 'APPROVED' checks that the state of the last submitted pull request review is
slice() function can also be used after
orderBy() to return a subset of a list.
slice() takes one or two numeric arguments that represent zero-based indexes:
slice(5)will return a new list from the start of the original list (index 0) up to, but excluding, the entity at index 5, i.e. the first five entities in the list.
slice(2, 5)will return a list inclusive of the first argument and exclusive of the second argument, i.e. the three entities at index positions 2, 3, and 4.
The example orders the
pullRequestReviews by the
submittedAt field and returns a subset of the list containing the first four entities before checking if any has a state of
pullRequestReviews.orderBy(submittedAt).slice(4).any(state = 'APPROVED')
You can use the
contains() function for lists of scalar types. Unlike the functions mentioned above, the argument to
contains() must be a simple value, not an expression.
The logical operators
or can be used to combine boolean expressions (in order of precedence), with parentheses used to override the default order of precedence. For example:
state = 'OPEN' and (changedFiles > 10 or not author.login = 'xxx')
The example below provides a more complex expression that selects any repository associated with the
ACME Rockets product that has any items with a label of
do not merge. The labels are case sensitive.
repository.products.any(name='ACME Rockets') and state = 'OPEN' and labels.none(name = 'wip' or name = 'do not merge')