18

I have the following cloudbuild.yaml file:

substitutions:
    _CLOUDSDK_COMPUTE_ZONE: us-central1-a 
    _CLOUDSDK_CONTAINER_CLUSTER: $_CLOUDSDK_CONTAINER_CLUSTER
steps:
- name: gcr.io/$PROJECT_ID/sonar-scanner:latest
  args:
    - '-Dsonar.host.url=https://sonar.test.io'
    - '-Dsonar.login=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    - '-Dsonar.projectKey=test-service'
    - '-Dsonar.sources=.'
- id: 'build test-service image'
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME/$BRANCH_NAME:$SHORT_SHA', '.']
- id: 'push test-service image'
  name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/$REPO_NAME/$BRANCH_NAME:$SHORT_SHA']
- id: 'set test-service image in yamls'
  name: 'ubuntu'
  args: ['bash','-c','sed -i "s,TEST_SERVICE,gcr.io/$PROJECT_ID/$REPO_NAME/$BRANCH_NAME:$SHORT_SHA," k8s/*.yaml']
- id: kubectl-apply
  name: 'gcr.io/cloud-builders/kubectl'
  args: ['apply', '-f', 'k8s/']
  env:
  - 'CLOUDSDK_COMPUTE_ZONE=${_CLOUDSDK_COMPUTE_ZONE}'
  - 'CLOUDSDK_CONTAINER_CLUSTER=${_CLOUDSDK_CONTAINER_CLUSTER}'
images: ['gcr.io/$PROJECT_ID/$REPO_NAME/$BRANCH_NAME:$SHORT_SHA']

I would like to make the sonar-scanner step conditional (if we are on the production branch, I want to skip the sonar step; other branches should run that step). I would also like to use the same cloudbuild.yaml across all branches.

Is it possible to do this?

Tanner Stern
  • 128
  • 1
  • 8
Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102

2 Answers2

28

You have 2 solutions

  1. Make 2 triggers, each one with their own configuration. 1 on Prod, 1 on UAT/DEV.
  2. You can script your execution. It's dirty but you keep only 1 CI/CD config file
steps:
- name: gcr.io/$PROJECT_ID/sonar-scanner:latest
  entrypoint: 'bash'
  env:
  - 'BRANCH_NAME=$BRANCH_NAME'
  script: |
    #!/usr/bin/env bash
    if [ $BRANCH_NAME != 'prod' ]; then
      sonar-scanner \
        -Dsonar.host.url=https://sonar.test.io \
        -Dsonar.projectKey=test-service \
        -Dsonar.sources=.
    fi
Adam Lassek
  • 35,156
  • 14
  • 91
  • 107
guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • thankyou for writing anwser. Can you please describe more about this ``. didn't got it. I have to change value there or just keep as it is. – Harsh Manvar Oct 04 '19 at 15:21
  • 1
    Of course, you have built a custom "cloud builder". At the end of this container, the last line, you write `ENTRYPOINT` . It's this same to put there. I guess it's `sonar-scanner` (it is in the sonarQube doc) – guillaume blaquiere Oct 04 '19 at 15:30
  • Thankyou for writing back i got i will try it thanks once again. – Harsh Manvar Oct 05 '19 at 16:12
  • https://stackoverflow.com/questions/58502210/gcp-cloudbuild-yaml-conditional-step-error – Harsh Manvar Oct 22 '19 at 10:28
  • can you please have a look at this : https://stackoverflow.com/questions/58502210/gcp-cloudbuild-yaml-conditional-step-error – Harsh Manvar Oct 22 '19 at 10:28
10

It is not (yet) possible to create conditional steps in cloud build, as is possible with gitlab-ci for example. What we did is to create multiple projects within GCP. You could create a project for development, staging and production. They are all sourced from the same git repository to keep environments identical to each other. This means they have the same cloudbuild.yaml file.

If you would somehow need to run a particular script only in the development environment, for example, an end-to-end test, you would specify a condition on $BRANCH_NAME or $PROJECT_ID within the build step itself. However, making too much of these conditionals will harm maintainability and your environments won't be an exact mirror of eachother. Nevertheless, here is a simple example:

---
timeout: 300s
steps:
  # Branch name conditional
  - name: gcr.io/google.com/cloudsdktool/cloud-sdk
    entrypoint: bash
    args:
      - -c
      - |
        if [[ "$BRANCH_NAME" == "develop" ]]
        then
          echo "Development stuff only"
        elif [[ "$BRANCH_NAME" == "release" ]]
        then
          echo "Acceptance stuff only"
        elif [[ "$BRANCH_NAME" == "main" ]]
        then
          echo "Production stuff only"
        fi

Besides building different projects per environment, I would also recommend building a project per domain or application. This means you have a logical separation between the data stored in the projects. You can then group all the development projects under a folder called development etc. Those folders are part of an organization or even another folder.

This logical grouping is one of the real benefits of using GCP, I find it very convenient. Azure has a somewhat similar structure with resource groups and subscriptions. AWS also has a resource group structure.

Cloudkollektiv
  • 11,852
  • 3
  • 44
  • 71
  • thanks for taking out time and writing answer. did same job have a different project with cloud build trigger on corresponding branches. – Harsh Manvar Jun 19 '20 at 13:40