Power Your Software Testing with AI Agents and Cloud

The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering. Test Intelligently and Ship Faster.

CI/CD

Google Cloud CI/CD Pipeline With Cloud Build and AI Agents

Build a Google Cloud CI/CD pipeline with Cloud Build: run Selenium tests on a cloud grid, gate agent-written pull requests, and add an AI test agent step.

Last Updated on:

The Google Cloud CI/CD pipeline tutorials I reviewed for this guide go straight from build to deploy with no test stage, and the older ones still push images to Container Registry. Google shut Container Registry down on March 18, 2025, and a pipeline without a test gate ships whatever a commit contains, including code an AI coding agent wrote.

AI agents are already part of production work: in Google Cloud's 2025 ROI of AI findings, 52% of executives report their organizations are now deploying AI agents in production.

This guide builds the pipeline on the current toolchain and adds a Selenium test gate that runs on the TestMu AI cloud grid. Every Maven command and console excerpt below comes from runs I made for this guide, including a parallel run that failed on two macOS sessions and the fix that turned it green. It then covers where AI agents fit: an agent that writes the pipeline, gates for the pull requests agents open, pipelines that ship agents, and an agent step that tests the deployed app.

Overview

A Google Cloud CI/CD pipeline uses Cloud Build to run each commit through containerized build and test steps defined in a cloudbuild.yaml file, stores images in Artifact Registry, and releases them with Cloud Run, GKE or Cloud Deploy. AI agents can now write that pipeline, open the pull requests it checks, and run test steps inside it.

Which Google Cloud Services Make Up the Pipeline?

  • Cloud Build: Runs every build step in its own Docker container from a cloudbuild.yaml file, and a trigger starts the build when code reaches a connected GitHub, GitLab or Bitbucket repository.
  • Artifact Registry: Stores the container images and Maven or npm packages a build produces, at a pkg.dev address. New pipelines push their images here.
  • Container Registry: Shut down, with image writes unavailable since March 18, 2025. Google-owned gcr.io images, including the Cloud Build builder images, still work.
  • Cloud Source Repositories: Closed to new customers since June 17, 2024, so new pipelines connect an external Git host through Developer Connect or Cloud Build repositories (2nd gen).

Where Do Tests and AI Agents Fit?

  • Test stage: A Maven step in cloudbuild.yaml runs Selenium tests on the TestMu AI cloud grid, and any failed test stops the build before the release step.
  • Pipeline authoring: Google's experimental Gemini CLI Extension for CI/CD lets an agent generate a cloudbuild.yaml file, create the Artifact Registry repository and add the build trigger.
  • Pull request gates: Cloud Build comment control waits for an owner or collaborator to comment /gcbrun, and build approval holds a build until a Cloud Build Approver approves it.
  • Agent test step: TestMu AI's Kane CLI runs a plain-language objective against the deployed app from a cloudbuild.yaml step, and a non-zero exit fails the build.

What Is a Google Cloud CI/CD Pipeline?

A Google Cloud CI/CD pipeline automates continuous integration and continuous delivery with managed services: a Cloud Build trigger starts a build when code changes, build steps compile and test the code in containers, Artifact Registry stores the image, and Cloud Run, GKE or Cloud Deploy releases it.

Cloud Build reads the steps from a cloudbuild.yaml file in the repository. Each step runs in its own Docker container, so a test step can use any image that has the test runner installed.

ServiceRole in the pipelineStatus
Cloud BuildRuns the build, test and deploy steps in cloudbuild.yaml; triggers start builds on pushes and pull requestsCore service
Artifact RegistryStores container images and packages such as Maven, npm and PythonCore service; replaced Container Registry
Cloud DeployPromotes a release through target environments in a defined sequence, rendering with SkaffoldCore service
Cloud Run and GKERun the released containerDeploy targets
Developer ConnectConnects GitHub, GitLab or Bitbucket repositories to Cloud BuildCurrent; Cloud Build repositories (2nd gen) also works
Container RegistryStored images before Artifact RegistryShut down; image writes stopped March 18, 2025
Cloud Source RepositoriesGoogle-hosted Git repositoriesClosed to new customers since June 17, 2024

GitHub Actions, GitLab CI and Jenkins can also deploy to Google Cloud, and the best CI/CD tools roundup compares them. This guide stays with Cloud Build because it runs inside your Google Cloud project and its triggers connect straight to the repository.

Google Cloud CI/CD Pipeline Architecture

A push or a pull request moves through these stages in order, and the test gate sits between the image build and the release:

  • Commit - A developer or an AI coding agent pushes a branch or opens a pull request on GitHub, GitLab or Bitbucket.
  • Trigger - The Cloud Build trigger that matches the event starts a build from cloudbuild.yaml.
  • Build - A gcr.io/cloud-builders/docker step builds the image and pushes it to an Artifact Registry repository at a pkg.dev address.
  • Test - A Maven step runs the browser tests on a cloud grid. A failed test makes Maven exit non-zero, which fails the build before the release step runs.
  • Release - A gcloud run deploy step updates Cloud Run, or Cloud Deploy promotes the release from staging to production.

Which tests belong at the test stage depends on how long they take, and the CI/CD testing guide maps test types to pipeline stages.

Note

Note: Point your Cloud Build test step at TestMu AI and run it across 3,000+ browser/OS combinations, or on 10,000+ real devices for mobile coverage. Create a free account

What Has Changed in the Google Cloud CI/CD Toolchain?

Two services from the original Google Cloud CI/CD toolchain no longer serve new pipelines: Container Registry is shut down, and Cloud Source Repositories is closed to new customers. Cloud Build, Artifact Registry and Cloud Deploy remain the core services. These are the changes to plan for when you build or update a pipeline:

  • Container Registry shutdown - Google shut down Container Registry on March 18, 2025, and writing images to it is no longer possible. Push new images to an Artifact Registry repository, which uses a pkg.dev address.
  • Builder images - Google-owned images with gcr.io URLs are not affected by the shutdown, so Cloud Build builders such as gcr.io/cloud-builders/docker, used in the files below, keep working.
  • Cloud Source Repositories access - Cloud Source Repositories has not been available to new customers since June 17, 2024. Organizations that used it before that date are not affected, and Google names Secure Source Manager, a regionally deployed, single-tenant managed source code repository, as an alternative.
  • Repository connections - Cloud Build connects to GitHub, GitHub Enterprise, GitLab, GitLab Enterprise Edition, Bitbucket Cloud and Bitbucket Data Center through Developer Connect or Cloud Build repositories (2nd gen). The 1st gen option stays available as a legacy choice.

The tutorial in this guide connects a GitHub repository to a Cloud Build trigger, so it depends on neither Container Registry nor Cloud Source Repositories.

Where Do AI Agents Fit in a Google Cloud CI/CD Pipeline?

AI agents now write Google Cloud pipeline configurations, open the pull requests those pipelines check, run as test steps inside them, and are the release some pipelines ship. Each role comes with its own human check:

RoleToolWhat it doesHuman check
Writes the pipelineGemini CLI Extension for CI/CD (experimental)Generates cloudbuild.yaml and creates the Artifact Registry repository, Git connection and build triggerYou review the generated files; the agent asks questions before it changes the project
Opens pull requestsCoding agents such as Gemini CLI or Claude CodePushes branches that fire pull request triggers/gcbrun comment control and build approval
Tests the buildKane CLI step in cloudbuild.yamlRuns a plain-language objective against the deployed appA non-zero exit fails the build
Is the releaseagents-cli infra cicdBuilds a Cloud Build or GitHub Actions pipeline for an AI agentManual approval before production

An Agent That Writes the Pipeline

Google's Gemini CLI Extension for CI/CD gives a coding agent skills and a Model Context Protocol (MCP) server for Google Cloud. Its tools create Artifact Registry repositories, Git connections and Cloud Build triggers, deploy to Cloud Run, and scan the workspace for secrets before any code leaves your machine.

It installs into Gemini CLI with gemini extensions install https://github.com/gemini-cli-extensions/cicd, and Google also publishes it as a Claude Code plugin. Before it changes your project, the agent asks questions such as which region and service name to use, and it can only do what your Application Default Credentials allow.

The extension's repository calls it an "EXPERIMENTAL PROJECT" and says: "Do not use this extension in production environments or with business-critical Google Cloud projects." Treat what it generates as a draft: review the cloudbuild.yaml in a pull request like any other change, and give the pipeline's service account only the roles its steps need.

Gates for Agent-Written Pull Requests

An agent that can open pull requests can also edit cloudbuild.yaml, so decide which pull requests may start a build at all. Cloud Build's GitHub triggers offer comment control: when it is set to Required, a build for any contributor's pull request runs only after an owner or collaborator comments /gcbrun.

For triggers that deploy or read secrets, also require approval. Cloud Build then marks each build as pending until someone with the Cloud Build Approver role approves it, and the gcloud flag for this is --require-approval.

These gates control when a build runs. Review and merge rules for the code itself are covered in CI/CD for agent-written code, and a step that diagnoses failed runs is covered in how to build an agent-native CI pipeline.

Google's own AI troubleshooting does not reach this stage yet: the supported-products list for Gemini Cloud Assist investigations includes Cloud Run and Google Kubernetes Engine, but not Cloud Build.

Pipelines That Ship AI Agents

When the release is itself an AI agent, Google's agents-cli sets up the pipeline. Running agents-cli infra cicd --staging-project my-staging-project --prod-project my-prod-project provisions staging and production with Terraform, connects the GitHub repository, and configures Cloud Build or GitHub Actions for these stages:

  • Pull request - Runs unit and integration tests.
  • Merge to main - Builds the container, pushes it to Artifact Registry, deploys it to staging and runs automated load testing.
  • Production - Waits for manual approval, then deploys the same container image that was tested in staging.

The same CLI's agents-cli eval run command grades the agent against an evaluation dataset. The older Agent Starter Pack now receives critical fixes only; its GitHub repository says active development has moved to agents-cli.

Load tests and evaluation datasets cover throughput and expected answers, and conversational agents also need scenario testing. TestMu AI's Agent Testing runs generated scenarios against chat, voice and phone agents and scores chat and voice runs on 9 quality dimensions.

Its Agent Testing CLI reads LT_USERNAME and LT_ACCESS_KEY from the environment and runs a suite without prompts when you pass --yes, so it can run as a Cloud Build step after the staging deploy. The continuous AI agent testing guide covers which of those checks belong at each stage between pull request and production.

How to Run Selenium Tests in a Cloud Build Pipeline

This walkthrough uses TestMu AI's Java-TestNG-Selenium sample repository, whose three TestNG classes test the to-do app on the Selenium Playground. The repository's own cloudbuild.yaml fails today: its pom.xml has no local profile and expects the suite file through -Dsuite, so the file's mvn test -P local step stops with "testSuiteXmlFiles0 has null value" before any test runs.

The tests run on TestMu AI's Automation Cloud, a cloud grid of 3,000+ browser/OS combinations. By default each session keeps a video, screenshots, a command log and the Selenium log, and setting the network and console capabilities in LT:Options adds network and console logs. Those records are the first place to look when a test step fails in Cloud Build.

Youtube thumbnail

Prerequisites

  • A TestMu AI account - Copy the username and access key from the TestMu AI dashboard under Credentials.
  • A fork of the sample repository - On GitHub, GitLab or Bitbucket, so Cloud Build can connect to it.
  • A Google Cloud project - With billing and the Cloud Build and Secret Manager APIs enabled.
  • A service account for the trigger - It needs the Secret Manager Secret Accessor role (roles/secretmanager.secretAccessor) on the two secrets you create next.

Store the Credentials in Secret Manager

Keep the access key out of cloudbuild.yaml and the trigger settings by storing both values in Secret Manager:

  • Create the username secret with printf '%s' "$LT_USERNAME" | gcloud secrets create lt-username --data-file=-.
  • Create the access key secret the same way, named lt-access-key.
  • Grant the trigger's service account the Secret Manager Secret Accessor role on both secrets with gcloud secrets add-iam-policy-binding.

Connect the Repository and Create a Trigger

  • In the Google Cloud console, open Cloud Build, go to Repositories, and link your fork through Developer Connect or a Cloud Build repositories (2nd gen) connection.
  • Open Triggers, select Create trigger, then choose the repository and an event: Push to a branch or Pull request.
  • Under Configuration, choose Cloud Build configuration file (yaml or json), with the location set to Repository.
  • Under Service account, select the account that can read the two secrets, then save the trigger.

Write the cloudbuild.yaml File

Replace the repository's cloudbuild.yaml with this file. It runs the suite in the official Maven image, reads the credentials from Secret Manager, and selects the TestNG suite through a _SUITE substitution that defaults to single.xml:

steps:
- id: 'selenium-suite'
  name: 'maven:3.9-eclipse-temurin-21'
  entrypoint: 'bash'
  args: ['-c', 'mvn -B test -Dsuite=$_SUITE']
  secretEnv: ['LT_USERNAME', 'LT_ACCESS_KEY']
substitutions:
  _SUITE: 'single.xml'
availableSecrets:
  secretManager:
  - versionName: projects/$PROJECT_ID/secrets/lt-username/versions/latest
    env: 'LT_USERNAME'
  - versionName: projects/$PROJECT_ID/secrets/lt-access-key/versions/latest
    env: 'LT_ACCESS_KEY'
options:
  logging: CLOUD_LOGGING_ONLY
  • secretEnv - Exposes LT_USERNAME and LT_ACCESS_KEY to the Maven step, and the tests read them with System.getenv().
  • -Dsuite=$_SUITE - Supplies the suite file that pom.xml expects. Give a second trigger the substitution _SUITE set to parallel.xml.
  • options.logging - CLOUD_LOGGING_ONLY is required when the trigger runs as a user-specified service account.

I did not run this file on Cloud Build, because I had no Google Cloud project for this guide, so check its syntax with a YAML validator before you commit it. The Maven command it runs did run against the TestMu AI grid from a fresh clone: mvn -B test -Dsuite=single.xml passed its one Chrome on Windows 10 test and reported BUILD SUCCESS in 25.5 seconds.

Run the Suite in Parallel

Parallel testing with parallel.xml runs the three classes at once: Safari and Chrome on macOS Sonoma, and Chrome on Windows 10. The first time I ran it, two of the three tests failed, and three runs in a row failed the same way:

[ERROR] Tests run: 3, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 22.62 s <<< FAILURE! -- in TestSuite
[ERROR] com.lambdatest.TestNGTodo3.basicTest -- Time elapsed: 5.641 s <<< FAILURE!
[ERROR] com.lambdatest.TestNGTodo1.basicTest -- Time elapsed: 8.609 s <<< FAILURE!
[INFO] BUILD FAILURE

Both failures came from the Add button. Chrome on macOS reported an ElementClickInterceptedException because the playground's Cookiebot consent banner would receive the click at point (1145, 700), and Safari failed on the same click with a generic WebDriverException.

A probe found the banner on macOS Sonoma about eight seconds after the page loaded, and no banner within 20 seconds on Windows 10, which is why only the macOS tests broke. In Cloud Build, that non-zero Maven exit would fail the step before any deploy step ran.

The fix dismisses the banner with an explicit wait before the test clicks anything. Add this class next to the tests and call ConsentBanner.dismissIfShown(driver) right after each driver.get():

package com.lambdatest;
import java.time.Duration;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;

public final class ConsentBanner {
  private static final By DIALOG = By.id("CybotCookiebotDialog");
  private static final By ALLOW =
      By.cssSelector("#CybotCookiebotDialog [id$='AllowallSelection']");
  public static void dismissIfShown(WebDriver driver) {
    try {
      new WebDriverWait(driver, Duration.ofSeconds(12))
          .until(ExpectedConditions.elementToBeClickable(ALLOW)).click();
      new WebDriverWait(driver, Duration.ofSeconds(5))
          .until(ExpectedConditions.invisibilityOfElementLocated(DIALOG));
    } catch (TimeoutException noBannerOnThisMachine) { }
  }
}

With the helper in all three classes, the same parallel run passed. The 12-second wait runs to its limit on machines that never show the banner, which is why this run took longer:

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 44.06 s -- in TestSuite
[INFO] BUILD SUCCESS
[INFO] Total time:  47.517 s

If a coding agent writes or maintains these tests, the Selenium skill gives it TestMu AI's patterns for this kind of code: explicit waits instead of sleeps, credentials from environment variables, and a pass or fail status reported for every session. For larger suites, HyperExecute splits tests across machines and retries flaky ones automatically, instead of opening every session from one Maven process.

Test a Private App Through the Tunnel

A build can also test the image it just built before anything is deployed. Each Cloud Build step runs attached to a local Docker network named cloudbuild, which lets steps communicate, so you can start the app and the TestMu AI tunnel as detached containers on that network and reach the app by its container name.

Part 1 starts the app image that an earlier step built, then the tunnel's Docker image, with a tunnel name taken from $BUILD_ID:

# cloudbuild.yaml, part 1 of 2: start the app and the tunnel
steps:
- id: 'app'
  name: 'gcr.io/cloud-builders/docker'
  args: ['run', '-d', '--name=app', '--network=cloudbuild', '$_APP_IMAGE']
- id: 'tunnel'
  name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args:
  - '-c'
  - >-
    docker run -d --name=lt --network=cloudbuild lambdatest/tunnel
    --user $$LT_USERNAME --key $$LT_ACCESS_KEY
    --tunnelName gcb-$BUILD_ID --infoAPIPort 15000
  secretEnv: ['LT_USERNAME', 'LT_ACCESS_KEY']

Part 2 waits for the tunnel's info API, then runs the suite with the tunnel name and the app's URL in the environment:

# cloudbuild.yaml, part 2 of 2: wait for the tunnel, then run the suite
- id: 'tunnel-ready'
  name: 'curlimages/curl'
  args: ['-s', '--retry-connrefused', '--connect-timeout', '5', '--max-time', '5',
         '--retry', '30', '--retry-delay', '2', '--retry-max-time', '60',
         'http://lt:15000/api/v1.0/info']
- id: 'selenium-suite'
  name: 'maven:3.9-eclipse-temurin-21'
  entrypoint: 'bash'
  args: ['-c', 'mvn -B test -Dsuite=$_SUITE']
  env: ['LT_TUNNEL_NAME=gcb-$BUILD_ID', 'BASE_URL=http://app:8080/']
  secretEnv: ['LT_USERNAME', 'LT_ACCESS_KEY']
# Then add the availableSecrets and options blocks from the first file.

The tests need two more LT:Options capabilities and the target URL from the environment:

// In setup(), next to the other LT:Options capabilities
ltOptions.setCapability("tunnel", true);
ltOptions.setCapability("tunnelName", System.getenv("LT_TUNNEL_NAME"));

// In the test, in place of the hard-coded playground URL
driver.get(System.getenv("BASE_URL"));

The repository's original file named every tunnel GCloud and added --load-balanced. Load-balanced tunnels that share a name act as a single pool, so two builds running at once could route a test through the other build's tunnel, which cannot reach this build's app. A name built from $BUILD_ID keeps each build on its own tunnel, and the readiness check replaces the original 20-second sleep step.

I ran the same sequence on my machine with tunnel 3.2.36, the same flags and the same curl options, using a local web server as the app on a hostname that only that machine resolves. The info API answered HTTP 500 with "Server not initialized" until the tunnel connected, curl kept retrying, and the check passed about six seconds after launch.

The test then loaded the page through the tunnel and passed in 18.47 seconds. Its session record in build 107374001 shows tunnel: true and the per-build tunnel name.

Skip the setup and install the Selenium Skill for Claude Code, Copilot & Cursor with one command.

Selenium

How to Add an AI Test Agent Step to cloudbuild.yaml

Add a step that installs Kane CLI and runs a plain-language objective against the deployed app; a failed objective exits non-zero and fails the build. Kane CLI is TestMu AI's agentic quality verifier: it drives a real Chrome browser and passes a run only when evidence such as DOM state, URL changes or network responses confirms the expected result.

The official node image has no Chrome, so the step uses --ws-endpoint, which the CLI's help describes as a Playwright WebSocket connection such as a TestMu AI wss:// URL. Store that URL as a third secret, lt-browser-wss, mapped to LT_BROWSER_WSS in availableSecrets:

- id: 'agent-check'
  name: 'node:22'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    npm install -g @testmuai/kane-cli
    kane-cli run "Search for iPhone, add the first result to the cart, and verify the cart shows 1 item" \
      --url "$_APP_URL" --ws-endpoint "$$LT_BROWSER_WSS" \
      --username "$$LT_USERNAME" --access-key "$$LT_ACCESS_KEY" \
      --headless --agent --timeout 300
  secretEnv: ['LT_USERNAME', 'LT_ACCESS_KEY', 'LT_BROWSER_WSS']

Set _APP_URL to the address of the release under test. A Cloud Run revision deployed with --no-traffic --tag gets its own tagged URL without serving traffic, which makes it a safe target for this check.

I did not run this step for this guide. Its flags match kane-cli run --help in Kane CLI 0.8.20, and its exit codes follow the Kane CLI CI/CD documentation: 0 when the objective passes, 1 when an assertion fails, 2 for errors such as a failed login, and 3 for a timeout.

Keep the Selenium suite next to the agent step. The suite repeats fixed assertions across browsers on every build, while the agent step checks a user journey written in plain language and saves an evidence pack with step screenshots, network logs and console logs for every run.

Kane CLI - Testing Agent in Your Terminal

Conclusion

Fork the sample repository, store your TestMu AI credentials in Secret Manager, and point a Cloud Build trigger at the cloudbuild.yaml above with _SUITE set to single.xml. When that build is green, add the consent-banner helper, switch to parallel.xml, and then add the tunnel steps and the Kane CLI step.

The Selenium with TestNG documentation lists the capabilities each test can set, and the online Selenium Grid page shows which browsers and operating systems you can target.

Author

...

Samyak Goyal

Blogs: 31

  • Linkedin

Samyak Goyal is a Senior Member of Technical Staff at TestMu AI engineering Kane CLI, the command-line tool that runs browser automation from the terminal, where a flow described in natural language executes in a real Chrome browser and returns pass or fail with shareable proof. He is a backend engineer with 4+ years of experience, previously an SDE at Innovaccer, where he built APIs, introduced Kafka, and cut deployment from weeks to hours. Samyak also builds multi-agent systems, skill-orchestration frameworks, and a personal copilot that indexes 200+ microservice repositories.

Reviewer

...

Himanshu Sheth

Reviewer

  • Linkedin

Himanshu Sheth is the Director of Marketing (Technical Content) at TestMu AI, with over 8 years of hands-on experience in Selenium, Cypress, and other test automation frameworks. He has authored more than 130 technical blogs for TestMu AI, covering software testing, automation strategy, and CI/CD. At TestMu AI, he leads the technical content efforts across blogs, YouTube, and social media, while closely collaborating with contributors to enhance content quality and product feedback loops. He has done his graduation with a B.E. in Computer Engineering from Mumbai University. Before TestMu AI, Himanshu led engineering teams in embedded software domains at companies like Samsung Research, Motorola, and NXP Semiconductors. He is a core member of DZone and has been a speaker at several unconferences focused on technical writing and software quality.

Add to Google preferred sources

Summarise with AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Google Cloud CI/CD Pipeline FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests