Search code examples
bashgoogle-cloud-platformgoogle-cloud-build

Cloud Build fail a build conditionally


Working on setting up a CI pipeline with GCP Cloud Build for cloud functions. Our organization likes using Behave for testing python, so I'm trying to do the following with Cloud Build:

  1. Run behave tests using functions-framework
  2. Upload the results of those tests to a bucket
  3. IF the tests succeeded, deploy the function to our test environment

As-is, the only part not working is the IF in step 3. The function is deployed regardless of whether the behave tests succeed. I believe because I'm piping the results, and the writing of the results is succeeding. I'd like steps 1 and 2 to always run, and if the behave tests failed, skip step 3 and fail the build.

I tried saving the exit code of the tests using [ 0 -eq ${PIPESTATUS[0]} ] at the end of the command string in the first step, but I'm unable how to use that value to achieve what I've described above.

The contents of my cloudbuild.yaml file:

steps:
  - id: 'run-behave-tests'
    name: 'gcr.io/my-project/my-docker-image:v1'
    entrypoint: /bin/bash
    args: [-c, 'pip install -r ./gcfs/hello/requirements.txt && cd ./gcfs/hello && (functions-framework --target=hello --signature-type=http --port=8080) & sleep 10 && cd ./gcfs/hello && behave --tags=local --format json --no-skipped --no-source --no-summary | jq ''.[] |= {"function_name": "hello"} + .'' | jq -c ".[]" > /workspace/behave_output_hello.json']
  - id: 'upload-behave-results'
    name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    args:
      - gcloud
      - storage
      - cp
      - --content-type=text/plain
      - /workspace/behave_output_hello.json
      - gs://bucketbucketbucket/behave_output.json
  - id: 'deploy-function'
    name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    args:
      - gcloud
      - functions
      - deploy
      - function-name
      - --region=us-central1
      - --source=https://MYCLOUDREPO/revisions/dev/paths/gcfs/hello
      - --trigger-http
      - --runtime=python311
      - --project=myproject
options:
  logging: CLOUD_LOGGING_ONLY

The "my-docker-image" dockerfile:

FROM python:3.11
RUN pip install behave
RUN pip install requests
RUN apt-get update
RUN apt-get install sudo
RUN sudo apt-get install jq -y

Solution

  • Do you think it might be possible to develop some conditional logic by using a bash script inside the yaml file?

    If that is feasible - the last step of the yaml file might look as:

    - id: "some identifier"
      name: 'gcr.io/cloud-builders/gcloud'
      entrypoint: 'bash'
      args:
        - '-c'
        - |
    
          if [[ -z "${example}" ]] 
          then
            echo "deploy the cloud function using your preferred method"
          else
            echo "don't deploy the cloud function"
          fi
    

    In case you need to transfer any data between steps (i.e. some test results), you may like to save that data in a local (for the Cloud Build runtime) file in one step, and read it in a subsequent step.

    echo ${some_data} > /workspace/some_data_file
    
    some_data=$(cat /workspace/some_data_file)