Creating Pub/Sub triggers

Cloud Build Pub/Sub triggers enable you to execute builds in response to Google Cloud events published over Pub/Sub. You can use information from a Pub/Sub event to parameterize your build and to decide if a build should execute in response to the event. Pub/Sub triggers can be configured to listen to any Pub/Sub topic.

This page explains how you can create a Pub/Sub trigger to build in response to events on Artifact Registry, Container Registry, and Cloud Storage.

Before you begin

  • Enable the Cloud Build API.

    Enable the API

  • Make sure your source code contains a build config file or a Dockerfile in the repository.
  • To use gcloud commands on this page, install the Cloud SDK.

Creating a build trigger that responds to Artifact Registry events

You can create a Pub/Sub trigger that responds to Artifact Registry events such as when images are pushed, tagged, or deleted. This section discusses how you can create a Pub/Sub trigger that invokes a build when a new tag is pushed to an existing image. If you are unfamiliar with Artifact Registry, see the Artifact management overview.

Console

To create a trigger that listens for a new tag pushed to an existing image in Artifact Registry using the Google Cloud Console:

  1. Open the Triggers page:

    Open the Triggers page

  2. Select your project from the top of the page and click Open.

  3. Click Create trigger.

  4. Enter the following trigger settings:

    • Name: Enter a name for your trigger.
    • Description (Optional): Enter a description for your trigger.
    • Event: Select Pub/Sub message as the event to invoke your trigger.
    • Subscription: Select the Pub/Sub topic you would like to subscribe to as the trigger event. You see all existing topics in your project in the drop-down menu.

    • Source: Select the repository to build when the trigger runs.

    • Revision: Select the branch or tag to build when the trigger runs.

      • Branch: Enter the name of the branch to invoke your build on.
      • Tag: Enter the name of the tag to invoke your build on.
    • Configuration: Select the build config file (located in your remote repository) or create an inline build config file to use for your build.

      • Type: Select the type of configuration to use for your build.
        • Cloud Build configuration file (yaml or json): Use a build config file for your configuration.
        • Dockerfile: Use a Dockerfile for your configuration.
        • Buildpacks: Use buildpacks for your configuration.
      • Location: Specify the location for your configuration.

        • Repository: If your config file is in located in your remote repository, provide the location of your build config file, the Dockerfile directory, or the buildpacks directory. If your build config type is a Dockerfile or a buildpack, you will need to provide a name for the resulting image and optionally, a timeout for your build. When you've provided the Dockerfile or buildpack image name, you'll see a preview of the docker build or pack command that your build will execute.
        • Buildpack environment variables (optional): If you selected buildpacks as your configuration type, click Add pack environment variable to specify your buildpack environment variables and values. To learn more about buildpack environment variables, see Environment variables.
        • Inline: If you selected Cloud Build configuration file (yaml or json) as your configuration option, you can specify your build config inline. Click Open Editor to write your build config file in the Google Cloud Console using YAML or JSON syntax. Click Done to save your build config.

    • Substitutions (optional): If you selected the build config file as your build config option, you can choose to define trigger-specific substitution variables using this field.

      In the following example, we want to obtain the name of the image tag from the payload and the action associated with the gcr event. To do so, create substitution variables using payload bindings.

      Specify the following variables and values below:

      Variable Name Variable Value
      _IMAGE_TAG $(body.message.data.tag)
      _ACTION $(body.message.data.action)

      body.message references the PubSubMessage published by publishers and consumed by subscribers. To see more examples of the Pub/Sub notification payload, see Notification examples.

    • Filters (optional): You can create filters within a trigger that determine whether or not your trigger will execute a build in response to the incoming payload by specifying filters on substitution variables. The filter expression must evaluate to true in order for a build to execute.

      We recommend using filtering when setting up Pub/Sub triggers on topics with several messages. Filters can be used to precisely control builds that are executed in response to incoming Pub/Sub messages. To learn about risks associated with setting up a trigger without filters, see Risks associated with an unfiltered trigger.

      In the following example, we want the trigger to execute a build if a new tag is pushed to an existing image. We use filter condition operators to check if the _IMAGE_TAG variable matches an existing tag name and if the _ACTION variable matches INSERT to look for newly added data.

      Specify the following as your filters:

      • _IMAGE_TAG != ""
      • _ACTION == INSERT

      Filtering syntax in Pub/Sub triggers use Common Expression Language (CEL) for expression evaluation. To learn more about CEL, see the cel-spec repository. To see more example syntax for filtering you could apply to your Pub/Sub triggers, see Using CEL to filter build events.

  1. Click Create to create your build trigger
  2. .

gcloud

To create a trigger that listens for a new tag pushed to an existing image in Artifact Registry using the gcloud commands:

  1. Open a terminal window.
  2. Run the gcloud alpha command to create a build trigger in your project. In the example below, the trigger is configured to respond to builds with a tag matching prod and an action matching INSERT based on the specified payload as defined by the substitution variable, _IMAGE_TAG.

     gcloud alpha builds triggers create pubsub \
       --name=TRIGGER_NAME \
       --topic=projects/PROJECT_ID/topics/TOPIC_NAME \
       --build-config=BUILD_CONFIG \ # or --inline-config=INLINE_BUILD_CONFIG
       --substitutions=\
         _IMAGE_TAG_='$(body.message.data.tag)'
         _ACTION='$(body.message.data.action)'
       --filter='_IMAGE_TAG == "" && _ACTION == "INSERT"'
       --repo=REPO_NAME
       --tag=TAG_NAME  # or --branch=BRANCH_NAME
    

    Where:

    • TRIGGER_NAME is the name of your trigger.
    • PROJECT_ID is the ID of your Cloud project.
    • TOPIC_NAME is the name of Pub/Sub topic you've subscribed to.
    • BUILD_CONFIG is the path to your build config file.
    • INLINE_BUILD_CONFIG is the path to your inline build config file.
    • REPO_NAME is the name of the source repository the build is invoked on.
    • TAG_NAME is the name of your tag if you want to set your trigger to build on a tag.
    • BRANCH_NAME is the name of your branch if you want to set your trigger to build on a branch.

Creating a build trigger that responds to Container Registry events

You can create a Pub/Sub trigger that responds to Container Registry events such as when images are pushed, tagged, or deleted. This section discusses how you can create a Pub/Sub trigger that invokes a build when an image matches a tag set up by a custom filter. If you are unfamiliar with Container Registry, see the Quickstart for Container Registry to learn how to push and pull images with tags.

Console

To create a trigger that listens for an image push in Container Registry and matches based on a tag name using the Google Cloud Console:

  1. Open the Triggers page:

    Open the Triggers page

  2. Select your project from the top of the page and click Open.

  3. Click Create trigger.

  4. Enter the following trigger settings:

    • Name: Enter a name for your trigger.
    • Description (Optional): Enter a description for your trigger.
    • Event: Select Pub/Sub message as the event to invoke your trigger.
    • Subscription: Select the Pub/Sub topic you would like to subscribe to as the trigger event. You see all existing topics in your project in the drop-down menu.

    • Source: Select the repository to build when the trigger runs.

    • Revision: Select the branch or tag to build when the trigger runs.

      • Branch: Enter the name of the branch to invoke your build on.
      • Tag: Enter the name of the tag to invoke your build on.
    • Configuration: Select the build config file (located in your remote repository) or create an inline build config file to use for your build.

      • Type: Select the type of configuration to use for your build.
        • Cloud Build configuration file (yaml or json): Use a build config file for your configuration.
        • Dockerfile: Use a Dockerfile for your configuration.
        • Buildpacks: Use buildpacks for your configuration.
      • Location: Specify the location for your configuration.

        • Repository: If your config file is in located in your remote repository, provide the location of your build config file, the Dockerfile directory, or the buildpacks directory. If your build config type is a Dockerfile or a buildpack, you will need to provide a name for the resulting image and optionally, a timeout for your build. When you've provided the Dockerfile or buildpack image name, you'll see a preview of the docker build or pack command that your build will execute.
        • Buildpack environment variables (optional): If you selected buildpacks as your configuration type, click Add pack environment variable to specify your buildpack environment variables and values. To learn more about buildpack environment variables, see Environment variables.
        • Inline: If you selected Cloud Build configuration file (yaml or json) as your configuration option, you can specify your build config inline. Click Open Editor to write your build config file in the Google Cloud Console using YAML or JSON syntax. Click Done to save your build config.

    • Substitutions (optional): If you selected the build config file as your build config option, you can choose to define trigger-specific substitution variables using this field.

      In the following example, we want to obtain the name of the image tag from the payload and the action associated with the gcr event. To do so, create substitution variables using payload bindings.

      Specify the following variables and values below:

      Variable Name Variable Value
      _IMAGE_TAG $(body.message.data.tag)
      _ACTION $(body.message.data.action)

      body.message references the PubSubMessage published by publishers and consumed by subscribers. To see more examples of the Pub/Sub notification payload, see Notification examples.

    • Filters (optional): You can create filters within a trigger that determine whether or not your trigger will execute a build in response to the incoming payload by specifying filters on substitution variables. The filter expression must evaluate to true in order for a build to execute.

      We recommend using filtering when setting up Pub/Sub triggers on topics with several messages. Filters can be used to precisely control builds that are executed in response to incoming Pub/Sub messages. To learn about risks associated with setting up a trigger without filters, see Risks associated with an unfiltered trigger.

      In the following example, we want the trigger to execute a build if the name of the _IMAGE_TAG tag variable matches a specific tag name, such as prod. You can specify your filter condition operator as "==" for exact matching. You can also check for the action associated with your gcr event as well. For example, you may want to specify _ACTION is INSERT to look for newly added data.

      Specify the following as your filters:

      • _IMAGE_TAG == prod
      • _ACTION == INSERT

      Filtering syntax in Pub/Sub triggers use Common Expression Language (CEL) for expression evaluation. To learn more about CEL, see the cel-spec repository. To see more example syntax for filtering you could apply to your Pub/Sub triggers, see Filtering builds.

  1. Click Create to create your build trigger
  2. .

gcloud

To create a trigger that listens for an image push in Container Registry and matches based on a tag name using gcloud commands:

  1. Open a terminal window.
  2. Run the gcloud alpha command to create a build trigger in your project. In the example below, the trigger is configured to respond to builds with a tag matching prod and an action matching INSERT based on the specified payload as defined by the substitution variable, _IMAGE_TAG.

     gcloud alpha builds triggers create pubsub \
       --name=TRIGGER_NAME \
       --topic=projects/PROJECT_ID/topics/TOPIC_NAME \
       --build-config=BUILD_CONFIG \ # or --inline-config=INLINE_BUILD_CONFIG
       --substitutions=\
         _IMAGE_TAG_='$(body.message.data.tag)'
         _ACTION='$(body.message.data.action)'
       --filter='_IMAGE_TAG == "prod" && _ACTION == "INSERT"'
       --repo=REPO_NAME
       --tag=TAG_NAME  # or --branch=BRANCH_NAME
    

    Where:

    • TRIGGER_NAME is the name of your trigger.
    • PROJECT_ID is the ID of your Cloud project.
    • TOPIC_NAME is the name of Pub/Sub topic you've subscribed to.
    • BUILD_CONFIG is the path to your build config file.
    • INLINE_BUILD_CONFIG is the path to your inline build config file.
    • REPO_NAME is the name of the source repository the build is invoked on.
    • TAG_NAME is the name of your tag if you want to set your trigger to build on a tag.
    • BRANCH_NAME is the name of your branch if you want to set your trigger to build on a branch.

Creating a build trigger that responds to Cloud Storage events

You can create a Pub/Sub trigger that responds to Cloud Storage events such as when a new binary is pushed to an existing storage bucket. This section discusses how you can create a Pub/Sub trigger that responds with a build when deploying a new binary to an uploaded bucket. If you are unfamiliar with Cloud Storage, see the Quickstarts.

Console

To create a trigger that listens to Cloud Storage events using the Google Cloud Console:

  1. Open the Triggers page:

    Open the Triggers page

  2. Select your project from the top of the page and click Open.

  3. Click Create trigger.

  4. Enter the following trigger settings:

    • Name: Enter a name for your trigger.
    • Description (Optional): Enter a description for your trigger.
    • Event: Select Pub/Sub message as the event to invoke your trigger.
    • Subscription: Select the Pub/Sub topic you would like to subscribe to as the trigger event. You see all existing topics in your project in the drop-down menu.

    • Source: Select the repository to build when the trigger runs.

    • Revision: Select the branch or tag to build when the trigger runs.

      • Branch: Enter the name of the branch to invoke your build on.
      • Tag: Enter the name of the tag to invoke your build on.
    • Configuration: Select the build config file (located in your remote repository) or create an inline build config file to use for your build.

      • Type: Select the type of configuration to use for your build.
        • Cloud Build configuration file (yaml or json): Use a build config file for your configuration.
        • Dockerfile: Use a Dockerfile for your configuration.
        • Buildpacks: Use buildpacks for your configuration.
      • Location: Specify the location for your configuration.

        • Repository: If your config file is in located in your remote repository, provide the location of your build config file, the Dockerfile directory, or the buildpacks directory. If your build config type is a Dockerfile or a buildpack, you will need to provide a name for the resulting image and optionally, a timeout for your build. When you've provided the Dockerfile or buildpack image name, you'll see a preview of the docker build or pack command that your build will execute.
        • Buildpack environment variables (optional): If you selected buildpacks as your configuration type, click Add pack environment variable to specify your buildpack environment variables and values. To learn more about buildpack environment variables, see Environment variables.
        • Inline: If you selected Cloud Build configuration file (yaml or json) as your configuration option, you can specify your build config inline. Click Open Editor to write your build config file in the Google Cloud Console using YAML or JSON syntax. Click Done to save your build config.

    • Substitutions (optional): If you selected the build config file as your build config option, you can choose to define trigger-specific substitution variables using this field.

      In this example, we want to watch for the deployment of a new binary when it is uploaded to a bucket. To obtain this data, we can create substitution variables using payload bindings.

      Specify the following variables and values below:

      Variable Name Variable Value
      _EVENT_TYPE $(body.message.attributes.eventType)
      _BUCKET_ID $(body.message.attributes.bucketId)
      _OBJECT_ID $(body.message.attributes.objectId)

      body.message references the PubSubMessage published by publishers and consumed by subscribers. To see more examples of the Pub/Sub notification payload, see Notification examples.

    • Filters (optional): You can create filters within a trigger that determine whether or not your trigger will execute a build in response to the incoming payload by specifying filters on substitution variables. The filter expression must evaluate to true in order for a build to execute.

      We recommend using filtering when setting up Pub/Sub triggers on topics with several messages. Filters can be used to precisely control builds that are executed in response to incoming Pub/Sub messages. To learn about risks associated with setting up a trigger without filters, see Risks associated with an unfiltered trigger.

      Since we want the trigger to execute a build if the new binary has been deployed to a specific bucket, we can use "==" operator to check for exact matches. You can also use the "matches" keyword if you want to match by regular expression.

      Specify the following as your filters:

      • _EVENT_TYPE == OBJECT_FINALIZE
      • _OBJECT_ID matches ^<object-id>$
      • _BUCKET_ID matches ^<bucket-id>$
  1. Click Create to create your build trigger
  2. .

gcloud

To create a build trigger that listens to build events with a specific event type in Cloud Storage:

  1. Open a terminal window.
  2. Run the gcloud alpha command to create a build trigger in your project. In the example below, the trigger is configured to respond to builds with a Cloud Storage event associated with a new binary pushed to an existing storage bucket:

     gcloud alpha builds triggers create pubsub \
       --name=TRIGGER_NAME \
       --topic=projects/PROJECT_ID/topics/TOPIC_NAME \
       --build-config=BUILD_CONFIG \ # or --inline-config=INLINE_BUILD_CONFIG
       --substitutions=\
         _EVENT_TYPE='$(body.message.attributes.eventType)'
         _BUCKET_ID='$(body.message.attributes.bucketId)'
         _OBJECT_ID='$(body.message.attributes.objectId)'
       --filter='_EVENT_TYPE == "OBJECT_FINALIZE" && _OBJECT_ID.matches("<object-id>") && _BUCKET_ID.matches("<bucket-id>")'
       --repo=REPO_NAME
       --tag=TAG_NAME  # or --branch=BRANCH_NAME
    

    Where:

    • TRIGGER_NAME is the name of your trigger.
    • PROJECT_ID is the ID of your Cloud project.
    • TOPIC_NAME is the name of Pub/Sub topic you've subscribed to.
    • BUILD_CONFIG is the path to your build config file.
    • INLINE_BUILD_CONFIG is the path to your inline build config file.
    • REPO_NAME is the name of the source repository the build is invoked on.
    • TAG_NAME is the name of your tag if you want to set your trigger to build on a tag.
    • BRANCH_NAME is the name of your branch if you want to set your trigger to build on a branch.

Risks associated with an unfiltered trigger

If you have not configured filters on your Pub/Sub trigger, your trigger may end up invoking an infinite number of builds if your trigger modifies an artifact or object which unintentionally publishes a new message to the topic it's listening to. For example, your trigger may invoke an infinite number of builds if your trigger:

  • Points to a gcr topic.
  • Creates any image or tag in gcr.
  • Points to a gcs topic for a specific object in your bucket and modifies that object.

If you encounter an infinite loop, you can delete your trigger or update it to point to a separate topic to avoid incurring additional charges for each build you invoke.

Using CEL to filter build events

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 build 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