Filtering builds in notifications

Cloud Build can notify you of updates to your build status by sending you notifications to desired channels, such as Slack or your SMTP server. You can use Common Expression Language (CEL), an open-source language used to evaluate expressions, to filter on build events you want to be notified about. To learn more about notifiers, see cloud-build-notifiers.

This page explains how you can filter build events using CEL.

CEL support in filtering build events

Cloud Build currently provides CEL support in the filter string in notifier config files. In your notifier configuration file, you can specify the filter string to filter on build events. The example below shows a notifier config file that uses the filter string to filter on build events with a SUCCESS status:


    apiVersion: cloud-build-notifiers/v1
    kind: my-notifier
    metadata:
      name: my-notifier-one
    spec:
      notification:
        filter: build.status == Build.Status.SUCCESS
        delivery:
          url: https://notifier.com/one
          

To view a complete example of a notifier config file, see example files for the Slack, SMTP, or HTTP notifier.

Filtering examples

Cloud Build uses CEL with the variable, build, on fields listed in the Build resource to access fields associated with your build event such as your trigger ID, image list, or substitution values. You can use the filter string to filter build events in your notifier config file using any field listed in the Build resource. To find the exact syntax associated with your field, see the cloudbuild.proto file.

Filtering by trigger ID

To filter by trigger ID, specify the value of your trigger ID in the filter field using build.build_trigger_id, where trigger-id is your trigger ID as a string:

filter: build.build_trigger_id == trigger-id

Filtering by status

To filter by status, specify the build status you want to filter on in the filter field using build.status.

The following example shows how to filter build events with a SUCCESS status using the filter field:

filter: build.status == Build.Status.SUCCESS

You can also filter builds with varying statuses. The following example shows how to filter build events that have a SUCCESS, FAILURE, or TIMEOUT status using the filter field:

filter: build.status in [Build.Status.SUCCESS, Build.Status.FAILURE, Build.Status.TIMEOUT]

To see additional status values you can filter by, see Status under the Build resource reference.

Filtering by tag

To filter by tag, specify the value of your tag in the filter field using build.tags, where tag-name is the name of your tag:

filter: tag-name in build.tags

You can filter based on the number of tags specified in your build event using size. In the following example, the filter field filters build events that have exactly two tags specified with one tag specified as v1:

filter: size(build.tags) == 2 && "v1" in build.tags

Filtering by images

To filter by images, specify the value of your image in the filter field using build.images, where image-name is the full name of your image as listed in Container Registry such as gcr.io/example/image-one:

filter: image-name in build.images

In the following example, the filter filters on build events that have either gcr.io/example/image-one or gcr.io/example/image-two specified as image names:

filter: "gcr.io/example/image-one" in build.images || "gcr.io/example/image-two" in build.images

Filtering by time

You can filter build events based on a build's create time, start time, or finish time by specifying one of the following options in your filter field: build.create_time, build.start_time, or build.finish_time.

In the following example, the filter field uses timestamp to filter build events with a request time to create the build at July 20, 2020 at 6:00 AM:

filter: build.create_time == timestamp("2020-07-20:T06:00:00Z")

You can also filter on build events by time comparisons. In the following example, the filter field uses timestamp to filter build events with a start time between July 20, 2020 at 6:00 AM and July 30, 2020 at 6:00 AM.

filter: timestamp("2020-07-20:T06:00:00Z") >= build.start_time && build.start_time <= timestamp("2020-07-30:T06:00:00Z")

To learn more about how timezones are expressed in CEL, see the language definition for timezones.

To filter by duration of a build, you can use duration to compare timestamps. In the following example, the filter field uses duration to filter build events with a builds that run for at least five minutes:

filter: build.finish_time - build.start_time >= duration("5m")

Filtering by substitution

You can filter by substitution by specifying the substitution variable in the filter field using build.substitutions. In the following example, the filter field lists builds that contain the substitution variable substitution-variable and checks if the substitution-variable matches the specified substitution-value:

filter: build.substitutions[substitution-variable] == substitution-value

Where:

  • substitution-variable is the name of your substitution variable.
  • substitution-value is the name of your substitution value.

You can also filter by default substitution variable values. In the following example, the filter field lists builds that have the branch name master and builds that have the repository name github.com/user/my-example-repo. The default substitution variables BRANCH_NAME and REPO_NAME are passed in as keys to the build.substitutions:

filter: build.substitutions["BRANCH_NAME"] == "master" && build.substitutions["REPO_NAME"] == "github.com/user/my-example-repo"

If you want to filter on strings using regular expressions, you can use the built-in matches function. In the example below, the filter field filters for builds with a status of FAILURE or TIMEOUT and that also have a build substitution variable TAG_NAME with a value that matches the regular expression v{DIGIT}.{DIGIT}.{3 DIGITS}).

filter: build.status in [Build.Status.FAILURE, Build.Status.TIMEOUT] && build.substitutions["TAG_NAME"].matches("^v\\d{1}\\.\\d{1}\\.\\d{3}$")`

To see a list of default substitution values, see Using default substitutions.

What's next