Running bash scripts (original) (raw)

This page explains how to configure Cloud Build to run bash scripts within a build step. If you're new to Cloud Build, read thequickstarts and theBuild configuration overview first.

You can run bash scripts within a build step to configure a number of workflows including:

Using the script field

Cloud Build provides a script field that you can use to specify shell scripts to execute in a build step. The script field takes a single string value.

You can prefix the string value with a shebangto specify the shell to interpret the script. For example, add #!/usr/bin/env bash to specify the Bash shell. If you don't prefix the script string with a shebang, Cloud Build uses #!/bin/sh which is the basic sh shell, not Bash shell.

If you specify script in a build step, you cannot specify args or entrypointin the same step.

The following snippet demonstrates the script field:

YAML

steps:
- name: 'bash'
  script: |
    #!/usr/bin/env bash
    echo "Hello World"
- name: 'ubuntu'
  script: echo hello
- name: 'python'
  script: |
    #!/usr/bin/env python
    print('hello from python')

JSON

{
  "steps": [
  {
    "name": "bash",
    "script": "#!/usr/bin/env bash echo 'Hello World'"
  },
  {
    "name": "ubuntu",
    "script": "echo hello"
  },
  {
    "name": "python",
    "script": "#!/usr/bin/env python\nprint('hello from python')\n"
  }
  ]
}

Using substitutions with the script field

Scripts don't directly support substitutions, but they support environment variables. You can map substitutions to environment variables, either automatically all at once, or manually by defining every environment variable yourself.

Map substitutions automatically

YAML

steps:  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Hello $_USER"  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Your project ID is $PROJECT_ID"  
options:  
  automapSubstitutions: true  
substitutions:  
  _USER: "Google Cloud"  

JSON

{  
  "steps": [  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Hello $_USER'"  
    },  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'"  
    }  
  ],  
  "options": {  
    "automap_substitutions": true  
  },  
  "substitutions": {  
    "_USER": "Google Cloud"  
  }  
}  

YAML

steps:  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Hello $_USER"  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Your project ID is $PROJECT_ID"  
  automapSubstitutions: true  
substitutions:  
  _USER: "Google Cloud"  

JSON

{  
  "steps": [  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Hello $_USER'"  
    },  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'",  
      "automap_substitutions": true  
    }  
  ],  
  },  
  "substitutions": {  
    "_USER": "Google Cloud"  
  }  

Additionally, you can make the substitutions available as environment variables in the entire build, then ignore them in one step. SetautomapSubstitutions to true at the build level, then set the same field to false in the step where you want to ignore the substitutions. In the following example, even though mapping substitutions is enabled at the build level, the project ID will not be printed in the second step, becauseautomapSubstitutions is set to false in that step:

YAML

steps:  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Hello $_USER"  
- name: 'ubuntu'  
  script: |  
    #!/usr/bin/env bash  
    echo "Your project ID is $PROJECT_ID"  
  automapSubstitutions: false  
options:  
  automapSubstitutions: true  
substitutions:  
  _USER: "Google Cloud"  

JSON

{  
  "steps": [  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Hello $_USER'"  
    },  
    {  
      "name": "ubuntu",  
      "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'",  
      "automap_substitutions": false  
    }  
  ],  
  "options": {  
    "automap_substitutions": true  
  },  
  },  
  "substitutions": {  
    "_USER": "Google Cloud"  
  }  

Map substitutions manually

You can manually map the substitutions to environment variables. Every environment variable is defined at the step level using the envfield, and the scope of the variables is restricted to the step where they are defined. This field takes a list of keys and values.

The following example shows how to map the substitution $PROJECT_ID to the environment variable BAR:

YAML

steps:
- name: 'ubuntu'
  env:
  - 'BAR=$PROJECT_ID'
  script: 'echo $BAR'

JSON

{
  "steps": [
    {
      "name": "ubuntu",
      "env": [
        "BAR=$PROJECT_ID"
      ],
      "script": "echo $BAR"
    }
  ]
}

Running bash scripts on disk

If you have your bash script saved in a file, store the file along with your build source, and reference the script file within your build config file:

YAML

steps:
- name: 'bash'
  args: ['./myscript.bash']

JSON

{
  "steps": [
  {
    "name": "bash",
    "args": [
      "./myscript.bash"
     ]
  }
  ]
}

To use a bash script on file if bash is not the default entrypoint of the image you're using, add an entrypoint field pointing to bash:

YAML

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args: ['tools/myScript.sh','--foo']

JSON

{
  "steps": [
  {
    "name": "gcr.io/cloud-builders/gcloud",
    "entrypoint": "bash",
    "args": [
      "tools/myScript.sh",
      "--foo"
    ]
  }
  ]
}

To run bash commands using the bash image, specify bash as the nameof the build step, and the command in the args field:

YAML

steps:
- name: 'bash'
  args: ['echo', 'I am running a bash command']

JSON

{
  "steps": [
    {
      "name": "bash",
      "args": [
        "echo",
        "I am running a bash command"
       ]
    }
  ]
}

If the image you're using comes prepackaged with bash but if bash is not the default entrypoint, add an entrypoint field pointing to bash. In the example below, the bash entrypoint is used to run gcloud commands that query Cloud Build for build status, listing builds with a failed status.

YAML

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'bash'
  args:
  - '-eEuo'
  - 'pipefail'
  - '-c'
  - |-
    gcloud builds list > builds.txt
    while read line; do
        if grep -q "FAILURE" <<< "$line"; then
            echo "$line"
        fi
    done < builds.txt

JSON

{
  "steps": [
  {
    "name": "gcr.io/google.com/cloudsdktool/cloud-sdk",
    "entrypoint": "bash",
    "args": [
      "-eEuo",
      "pipefail",
      "-c",
      "gcloud builds list > builds.txt\nwhile read line; do\n    if grep -q \"FAILURE\" <<< \"$line\"; then\n        echo \"$line\"\n    fi\ndone < builds.txt"
    ]
  }
  ]
}

The -c flag in the code above is used to execute multi-line commands. Any string you pass after -c is treated as a command. For more information on running bash commands with -c, see thebash documentation.

What's next