Build and test Go applications

This page explains how to use Cloud Build to build, test, and deploy Go applications.

Before you begin

The instructions on this page assume that you are familiar with Go. In addition:

Configure the service account

The examples in this document use a user-specified service account. To create the service account used by Cloud Build, run the following command in Google Cloud CLI:

gcloud iam service-accounts create cloud-build-go \
--description="Build and test Go applications" \
--display-name="Cloud Build Go" \
--project="PROJECT_ID"

The default compute service account (used by Cloud Run) needs permission to act as the new service account. First, determine the name of the compute service account in your project:

gcloud iam service-accounts list --filter="email:-compute@developer.gserviceaccount.com"

Next, grant the Service Account User (roles/iam.serviceAccountUser) role:

gcloud iam service-accounts add-iam-policy-binding \
COMPUTE_SERVICE_ACCOUNT_EMAIL  \
--member="serviceAccount:cloud-build-go@PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"

Replace COMPUTE_SERVICE_ACCOUNT_EMAIL with the default compute service account email address printed by the previous command.

Configure IAM permissions

Ensure that you have the permissions that you need:

To get the permissions that you need to perform builds in Cloud Build, ask your administrator to grant you the Cloud Build Service Account (roles/cloudbuild.builds.builder) IAM role on your build service account. For more information about granting roles, see Manage access to projects, folders, and organizations.

You might also be able to get the required permissions through custom roles or other predefined roles.

To get the permissions that you need to store built images in Artifact Registry, ask your administrator to grant you the Artifact Registry Writer (roles/artifactregistry.writer) IAM role on your build service account.

To get the permissions that you need to store test logs in Logging, ask your administrator to grant you the Storage Object Creator (roles/storage.objectCreator) IAM role on your build service account.

To get the permissions that you need to deploy the application to Cloud Run, ask your administrator to grant you the Cloud Run Developer (roles/run.developer) IAM role on your build service account.

Configure Go builds

The public golang image from Docker Hub supports building using Go modules. Using this image as a build step in your Cloud Build config file lets you invoke go commands within the image. Arguments passed to this build step are passed to the golang tool directly, allowing you to run any go command in this image.

This section shows an example build config file for a Go app from the cloud-build-samples Git repository. It has build steps to build the app, add unit tests, and after the tests pass, to containerize and deploy the app.

To build the example Go application:

  1. Build and test: If you've defined unit tests in your application, you can configure Cloud Build to run the tests by adding the following fields in a build step:

    • name: Set the value of this field to golang to use the golang image from Docker Hub for your task.
    • entrypoint: Set the value of this field to /bin/bash. This lets you run multi-line bash commands directly from the build step.
    • args: The args field of a build step takes a list of arguments and passes them to the image referenced by the name field. In the following example, the args field takes the arguments for:
      • Running the test log formatter to download the test log output.
      • Printing the log output.
      • Saving test results in sponge.log.
      • Outputting the results in sponge.log to a JUNIT XML file. The name of the JUNIT XML file is constructed using the short version of the commit ID associated with your build. A subsequent build step will save the logs in this file to Cloud Storage.
    steps:
      # Run tests and save to file
      - name: golang:1.23
        entrypoint: /bin/bash
        args: 
          - -c
          - |
            go install github.com/jstemmer/go-junit-report/v2@latest
            2>&1 go test -timeout 1m -v ./... | /go/bin/go-junit-report -set-exit-code -iocopy -out ${SHORT_SHA}_test_log.xml
  2. Containerize the app: After adding the build step to ensure that the tests have passed, you can build the application. Cloud Build provides a pre-built Docker image that you can use to containerize your Go application. To containerize your app, add the following fields in a build step:

    • name: Set the value of this field to gcr.io/cloud-builders/docker to use the prebuilt docker image for your task.
    • args: Add the arguments for the docker build command as values for this field.

    The following build step builds the image myimage and tags it with the short version of your commit ID. The build step uses substitutions for project ID, repository name, and short SHA values therefore these values are automatically substituted at build time. Note that you will need to create or have an existing Docker repository in Artifact Registry to store the image.

    # Docker Build
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 
             'us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA', '.']
  3. Push the container to Artifact Registry: You can store the built container in Artifact Registry, which is a Google Cloud service that you can use to store, manage, and secure build artifacts. To do this, you'll need to have an existing Docker repository in Artifact Registry. To configure Cloud Build to store the image in an Artifact Registry Docker repository, add a build step with the following fields:

    • name: Set the value of this field to gcr.io/cloud-builders/docker to use the official docker builder image for your task.
    • args: Add the arguments for the docker push command as values of this field. For the destination URL, enter the Artifact Registry Docker repository where you want to store the image.

    The following build step pushes the image that you built in the previous step to Artifact Registry:

    # Docker push to Google Artifact Registry
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA']
  4. Deploy the container to Cloud Run: To deploy the image on Cloud Run, add a build step with the following fields:

    • name: Set the value of this field to google/cloud-sdk to use the gcloud CLI image to invoke the gcloud command to deploy the image on Cloud Run.
    • args: Add the arguments for the gcloud run deploy command as the values of this field.

    The following build step deploys the previously built image to Cloud Run:

    # Deploy to Cloud Run
    - name: 'gcr.io/cloud-builders/gcloud'
      args: ['run', 'deploy', 'helloworld-${SHORT_SHA}', 
             '--image=us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA', 
             '--region', 'us-central1', '--platform', 'managed']
  5. Save test logs to Cloud Storage: You can configure Cloud Build to store any test logs in Cloud Storage by specifying an existing bucket location and path to the test logs.

    The following build step stores the test logs that you saved in the JUNIT XML file to a Cloud Storage bucket:

    # Save test logs to Google Cloud Storage
    artifacts:
      objects:
        location: gs://$_BUCKET_NAME/
        paths:
          - ${SHORT_SHA}_test_log.xml

    The following snippet shows the complete build config file for the all previous steps:

    steps:
      # Run tests and save to file
      - name: golang:1.23
        entrypoint: /bin/bash
        args: 
          - -c
          - |
            go install github.com/jstemmer/go-junit-report/v2@latest
            2>&1 go test -timeout 1m -v ./... | /go/bin/go-junit-report -set-exit-code -iocopy -out ${SHORT_SHA}_test_log.xml
    
      # Docker Build
      - name: 'gcr.io/cloud-builders/docker'
        args: ['build', '-t', 
               'us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA', '.']
    
      # Docker push to Google Artifact Registry
      - name: 'gcr.io/cloud-builders/docker'
        args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA']
    
      # Deploy to Cloud Run
      - name: 'gcr.io/cloud-builders/gcloud'
        args: ['run', 'deploy', 'helloworld-${SHORT_SHA}', 
               '--image=us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA', 
               '--region', 'us-central1', '--platform', 'managed']
    
    # Save test logs to Google Cloud Storage
    artifacts:
      objects:
        location: gs://$_BUCKET_NAME/
        paths:
          - ${SHORT_SHA}_test_log.xml
    # Store images in Google Artifact Registry
    images:
      - us-central1-docker.pkg.dev/$PROJECT_ID/$_AR_REPO_NAME/myimage:$SHORT_SHA
  6. Start the build using the gcloud CLI or create a build trigger:

Google Cloud CLI

Run the following command, using --substitutions to specify the substitution variables used in cloudbuild.yaml:

gcloud builds submit --region=us-central1 --config=cloudbuild.yaml \
--default-buckets-behavior=REGIONAL_USER_OWNED_BUCKET \
--service-account= projects/PROJECT_ID/serviceAccounts/cloud-build-go@PROJECT_ID.iam.gserviceaccount.com \
--substitutions=_AR_REPO_NAME="_AR_REPO_NAME",_BUCKET_NAME="_BUCKET_NAME",SHORT_SHA="SHORT_SHA"

Replace _AR_REPO_NAME with the name of your Artifact Registry repository.

Replace _BUCKET_NAME with the name of your Cloud Storage bucket for test logs.

Replace SHORT_SHA with a short generic text string, such as "temp_fake_sha", as a value for SHORT_SHA isn't provided when running using gcloud CLI.

Build Triggers

Follow the steps in Create a build trigger. In the Substitution variables field, you must also provide the name of your Artifact Registry repository and the name of your Cloud Storage bucket for test logs.

What's next