10

Is there such an option? My use case would be running a trigger for a production build (deploys to production). Ideally, that trigger doesn't need to listen to any change since it is invoked manually via chatbot.

I saw this video CI/CD for Hybrid and Multi-Cloud Customers (Cloud Next '18) announcing there's an API trigger support, I'm not sure if that's what I need.

chriz
  • 1,826
  • 2
  • 24
  • 28
  • There is now gcloud cli alpha support for triggers if you would like to run a specific trigger ID instead of waiting for change on repo. https://cloud.google.com/sdk/gcloud/reference/alpha/builds/triggers/ https://cloud.google.com/sdk/gcloud/reference/alpha/builds/triggers/run – guille Jun 24 '19 at 19:03
  • is this fine to share? I see that this is alpha @guille – chriz Jul 11 '19 at 21:18
  • source: https://github.com/GoogleCloudPlatform/cloud-builders/issues/99#issuecomment-500077182 – guille Jul 12 '19 at 21:40

7 Answers7

8

I did same thing few days ago.

You can submit your builds using gcloud and rest api

gcloud:

gcloud builds submit --no-source  --config=cloudbuild.yaml --async --format=json

Rest API:

Send you cloudbuild.yaml as JSON with Auth Token to this url https://cloudbuild.googleapis.com/v1/projects/standf-188123/builds?alt=json

example cloudbuild.yaml:

steps:

- name: 'gcr.io/cloud-builders/docker'
  id: Docker Version
  args: ["version"]

- name: 'alpine'
  id:  Hello Cloud Build
  args: ["echo", "Hello Cloud Build"]

example rest_json_body:

{"steps": [{"args": ["version"], "id": "Docker Version", "name": "gcr.io/cloud-builders/docker"}, {"args": ["echo", "Hello Cloud Build"], "id": "Hello Cloud Build", "name": "alpine"}]}
manikantanr
  • 574
  • 3
  • 13
5

This now seems to be possible via API:

https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.triggers/run

request.json:

{
  "projectId": "*****",
  "commitSha": "************"
}

curl request (with using a gcloud command):

PROJECT_ID="********" TRIGGER_ID="*******************"; curl -X POST -T request.json -H "Authorization: Bearer $(gcloud config config-helper \
    --format='value(credential.access_token)')" \
    https://cloudbuild.googleapis.com/v1/projects/"$PROJECT_ID"/triggers/"$TRIGGER_ID":run
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
2

You can use google client api to create build jobs with python:

import operator
from functools import reduce
from typing import Dict, List, Union

from google.oauth2 import service_account
from googleapiclient import discovery


class GcloudService():
    def __init__(self, service_token_path, project_id: Union[str, None]):
        self.project_id = project_id
        self.service_token_path = service_token_path
        self.credentials = service_account.Credentials.from_service_account_file(self.service_token_path)


class CloudBuildApiService(GcloudService):
    def __init__(self, *args, **kwargs):
        super(CloudBuildApiService, self).__init__(*args, **kwargs)

        scoped_credentials = self.credentials.with_scopes(['https://www.googleapis.com/auth/cloud-platform'])
        self.service = discovery.build('cloudbuild', 'v1', credentials=scoped_credentials, cache_discovery=False)

    def get(self, build_id: str) -> Dict:
        return self.service.projects().builds().get(projectId=self.project_id, id=build_id).execute()

    def create(self, image_name: str, gcs_name: str, gcs_path: str, env: Dict = None):
        args: List[str] = self._get_env(env) if env else []
        opt_params: List[str] = [
            '-t', f'gcr.io/{self.project_id}/{image_name}',
            '-f', f'./{image_name}/Dockerfile',
            f'./{image_name}'
        ]
        build_cmd: List[str] = ['build'] + args + opt_params
        body = {
            "projectId": self.project_id,
            "source": {
                'storageSource': {
                    'bucket': gcs_name,
                    'object': gcs_path,
                }
            },
            "steps": [
                {
                    "name": "gcr.io/cloud-builders/docker",
                    "args": build_cmd,
                },
            ],
            "images": [
                [
                    f'gcr.io/{self.project_id}/{image_name}'
                ]
            ],
        }
        return self.service.projects().builds().create(projectId=self.project_id, body=body).execute()

    def _get_env(self, env: Dict) -> List[str]:
        env: List[str] = [['--build-arg', f'{key}={value}'] for key, value in env.items()]
        # Flatten array
        return reduce(operator.iconcat, env, [])

Here is the documentation so that you can implement more functionality: https://cloud.google.com/cloud-build/docs/api

Hope this helps.

yurisich
  • 6,991
  • 7
  • 42
  • 63
Tobias Ernst
  • 4,214
  • 1
  • 32
  • 30
  • I am getting: googleapiclient.errors.HttpError: "The caller does not have permission" while using a service account. I am not sure what permission I have to grant? – Stiefel Oct 25 '22 at 14:36
  • You may need to open https://console.cloud.google.com/ and enable proper api's. Afterwards you can create a service account, download the key and map it by using `service_token_path `. – Tobias Ernst Oct 26 '22 at 08:38
  • 1
    Solved it, the service account needed the role cloudbuild.builds.editor – Stiefel Oct 26 '22 at 14:13
1

If you just want to create a function that you can invoke directly, you have two choices:

  1. An HTTP trigger with a standard API endpoint
  2. A pubsub trigger that you invoke by sending a message to a pubsub topic

The first is the more common approach, as you are effectively creating a web API that any client can call with an HTTP library of their choice.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

You should be able to manually trigger a build using curl and a json payload. For details see: https://cloud.google.com/cloud-build/docs/running-builds/start-build-manually#running_builds.

Given that, you could write a Python Cloud function to replicate the curl call via the requests module.

Mithrill
  • 173
  • 1
  • 8
0

I was in search of the same thing (Fall 2022) and while I haven't tested yet I wanted to answer before I forget. It appears to be available now in gcloud beta builds triggers run TRIGGER

bajaco
  • 830
  • 1
  • 4
  • 11
-1

you can trigger a function via

gcloud functions call NAME --data 'THING'

inside your function you can do pretty much anything possibile within Googles Public API's

if you just want to directly trigger Google Cloud Builder from git then its probably advisable to use Release version tags - so your chatbot might add a release tag to your release branch in git at which point cloud-builder will start the build.

more info here https://cloud.google.com/cloud-build/docs/running-builds/automate-builds

Dan
  • 224
  • 1
  • 5
  • 1
    Right now, the only available Google Cloud Builder API is creating a trigger, but not running them. I was thinking of pushing a tag with my chatbot, but I think I have to clone it first before I can push a tag, which seems slow. I'm using cloud functions for our chatbot and don't want to run a dedicated instance just for this. – chriz Aug 19 '18 at 08:04
  • i've never tried it but i believe you can add a tag to a commit ID git tag -a v2.0 COMMIT_HASH – Dan Aug 19 '18 at 08:14
  • You misunderstood, you can certainly tag via commit hash but that requires cloning the repo first. Which make it a slow solution versus simply triggering the build via cli/api. You are suggesting git tagging via cloud functions or my chatbot right? That requires manual clone. – chriz Aug 19 '18 at 09:51