替换变量值

在构建配置文件中使用 substitutions 以在构建时替代特定变量。

对于那些直到构建时才知道值的变量,或者使用不同的变量值重用现有构建请求,替代变量很有用。

Cloud Build 提供内置替代变量,您也可以定义自己的替代变量。在构建的 stepsimages 中使用 substitutions 可在构建时解析它们的值。

本页面介绍了如何使用默认替代变量或者定义自己的 substitutions

使用默认替代变量

Cloud Build 为所有构建提供以下默认替代变量:

  • $PROJECT_ID:您的 Cloud 项目的 ID
  • $BUILD_ID:您的构建的 ID
  • $PROJECT_NUMBER:您的项目编号
  • $LOCATION:与构建关联的区域

Cloud Build 为触发器调用的构建提供以下默认替代变量:

  • $TRIGGER_NAME:与触发器关联的名称
  • $COMMIT_SHA:与您的构建关联的提交 ID
  • $REVISION_ID:与您的构建关联的提交 ID
  • $SHORT_SHACOMMIT_SHA 的前七个字符
  • $REPO_NAME:代码库的名称
  • $REPO_FULL_NAME:代码库的完整名称,包括用户或组织
  • $BRANCH_NAME:您的分支名称
  • $TAG_NAME:您的标记名称
  • $REF_NAME:您的分支或标记名称
  • $TRIGGER_BUILD_CONFIG_PATH:构建执行期间使用的 build 配置文件的路径;否则,如果构建是在触发器上以内嵌方式配置的,或构建使用 DockerfileBuildpack,则为空字符串。
  • $SERVICE_ACCOUNT_EMAIL:您用于构建的服务帐号的电子邮件地址。这是默认服务帐号或用户指定的服务账号。
  • $SERVICE_ACCOUNT:服务帐号的资源名称,格式为 projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL

Cloud Build 提供以下特定于 GitHub 的默认替代变量,用于拉取请求触发器:

  • $_HEAD_BRANCH:拉取请求的标头分支
  • $_BASE_BRANCH:拉入请求的基本分支
  • $_HEAD_REPO_URL:拉取请求的标头代码库网址
  • $_PR_NUMBER:拉取请求编号

如果默认替代变量不可用(例如无源构建或使用存储源的构建),则会使用空字符串替换出现的缺失变量。

使用 gcloud builds submit 启动构建时,您可以使用 --substitutions 参数指定通常来自触发构建的变量。具体来说,您可以手动提供以下变量的值:

  • $TRIGGER_NAME
  • $COMMIT_SHA
  • $REVISION_ID
  • $SHORT_SHA
  • $REPO_NAME
  • $REPO_FULL_NAME
  • $BRANCH_NAME
  • $TAG_NAME
  • $REF_NAME
  • $TRIGGER_BUILD_CONFIG_PATH
  • $SERVICE_ACCOUNT_EMAIL
  • $SERVICE_ACCOUNT

例如,以下命令使用 TAG_NAME 替代变量:

gcloud builds submit --config=cloudbuild.yaml \
    --substitutions=TAG_NAME="test"

以下示例使用默认替代变量 $BUILD_ID$PROJECT_ID$PROJECT_NUMBER$REVISION_ID

YAML

steps:
# Uses the ubuntu build step:
# to run a shell script; and
# set env variables for its execution
- name: 'ubuntu'
  args: ['bash', './myscript.sh']
  env:
  - 'BUILD=$BUILD_ID'
  - 'PROJECT_ID=$PROJECT_ID'
  - 'PROJECT_NUMBER=$PROJECT_NUMBER'
  - 'REV=$REVISION_ID'

# Uses the docker build step to build an image called my-image
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/my-image', '.']

# my-image is pushed to Artifact Registry
images:
- '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/my-image'

JSON

{
  "steps": [{
      "name": "ubuntu",
      "args": [
        "bash",
        "./myscript.sh"
      ],
      "env": [
        "BUILD=$BUILD_ID",
        "PROJECT_ID=$PROJECT_ID",
        "PROJECT_NUMBER=$PROJECT_NUMBER",
        "REV=$REVISION_ID"
      ]
    }, {
      "name": "gcr.io/cloud-builders/docker",
      "args": ["build", "-t", "gcr.io/$PROJECT_ID/my-image", "."]
    }],
  "images": [
    "gcr.io/$PROJECT_ID/my-image"
  ]
}

以下示例演示了使用 docker 构建步骤构建映像的构建请求,然后使用默认的 $PROJECT_ID 替代变量将映像推送到 Artifact Registry:

在此示例中:

  • 构建请求包含一个构建步骤,在 gcr.io/cloud-builders 中使用 docker 构建步骤来构建 Docker 映像。
    • 该步骤中的 args 字段指定传递给 docker 命令的参数,在此示例中,系统将调用 build -t gcr.io/my-project/cb-demo-img .(使用您的项目 ID 替换 $PROJECT_ID 后)。
  • images 字段包含映像的名称。如果构建成功,则生成的映像将推送到 Artifact Registry。如果构建未成功创建映像,则构建将失败。

YAML

steps:
- name: gcr.io/cloud-builders/docker
  args: ["build", "-t", "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/cb-demo-img", "."]
images:
- '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/cb-demo-img'

JSON

{
  "steps": [{
      "name": "gcr.io/cloud-builders/docker",
      "args": ["build", "-t", "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/cb-demo-img", "."]
    }],
  "images": [
    "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/cb-demo-img"
  ]
}

使用用户定义的替代变量

您也可以定义自己的替代变量。用户定义的替代变量必须遵循以下规则:

  • 替代变量必须以下划线 (_) 开头,并且只能使用 大写字母和数字(遵循正则表达式格式 _[A-Z0-9_]+)。这样做可以防止与内置替代变量产生冲突。要使用 以 $ 开头的表达式,您必须使用 $$. For example:
    • $FOO is invalid since it is not a built-in substitution.
    • $$FOO 计算结果为文字字符串 $FOO
  • 参数数量的上限为 200 个。参数键的长度上限为 100 个字节,参数值的长度上限为 4000 个字节。
  • 您可以使用以下两种方式之一来指定变量:$_FOO${_FOO}

    • $_FOO${_FOO} 计算结果均为 _FOO 的值。但是,${} 允许替代变量在两侧都没有空格的情况下也能够起作用,这意味着允许使用 ${_FOO}BAR 等替代变量。
    • $$ lets you include a literal $ in the template. For example:
      • $_FOO evaluates to the value of _FOO.
      • $$_FOO 计算结果为文字字符串 $_FOO
      • $$$_FOO evaluates to the literal string $ followed by the value of _FOO.

    To use the substitutions, use the --substitutions argument in the gcloud command or specify them in the config file.

    The following example shows a build config with two user-defined substitutions called _NODE_VERSION_1 and _NODE_VERSION_2:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
              '--build-arg',
              'node_version=${_NODE_VERSION_1}',
              '-t',
              '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_1}',
              '.']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build',
              '--build-arg',
              'node_version=${_NODE_VERSION_2}',
              '-t',
              '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_2}',
              '.']
    substitutions:
        _NODE_VERSION_1: v6.9.1 # default value
        _NODE_VERSION_2: v6.9.2 # default value
    images: [
        '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_1}',
        '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_2}'
    ]
    

    JSON

    {
        "steps": [{
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "--build-arg",
                "node_version=${_NODE_VERSION_1}",
                "-t",
                "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_1}",
                "."
            ]
        }, {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
                "build",
                "--build-arg",
                "node_version=${_NODE_VERSION_2}",
                "-t",
                "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_2}",
                "."
            ]
        }],
        "substitutions": {
            "_NODE_VERSION_1": "v6.9.1",
            "_NODE_VERSION_2": "v6.9.2",
        },
        "images": [
            "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_1}",
            "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/build-substitutions-nodejs-${_NODE_VERSION_2}"
        ]
    }
    

    To override the substitution value you specified in the build config file, use the --substitutions flag in the gcloud builds submit command. Note that substitutions are a mapping of variables to values rather than arrays or sequences. You can override default substitution variable values except for $PROJECT_ID and $BUILD_ID. The following command overrides the default value for _NODE_VERSION_1 specified in the previous build config file:

    gcloud builds submit --config=cloudbuild.yaml \
      --substitutions=_NODE_VERSION_1="v6.9.4",_NODE_VERSION_2="v6.9.5" .
    

    By default, the build returns an error if there's a missing substitution variable or a missing substitution. However, you can set the ALLOW_LOOSE option to skip this check.

    The following snippet prints "hello world" and defines an unused substitution. Because the ALLOW_LOOSE substitution option is set, the build will be successful despite the missing substitution.

    YAML

    steps:
    - name: 'ubuntu'
      args: ['echo', 'hello world']
    substitutions:
        _SUB_VALUE: unused
    options:
        substitutionOption: 'ALLOW_LOOSE'
    

    JSON

    {
        "steps": [
        {
            "name": "ubuntu",
            "args": [
                "echo",
                "hello world"
            ]
        }
        ],
        "substitutions": {
            "_SUB_VALUE": "unused"
    },
        "options": {
            "substitution_option": "ALLOW_LOOSE"
        }
    }
    

    If your build is invoked by a trigger, the ALLOW_LOOSE option is set by default. In this case, your build won't return an error if there is a missing substitution variable or a missing substitution. You cannot override the ALLOW_LOOSE option for builds invoked by triggers.

    If the ALLOW_LOOSE option is not specified, unmatched keys in your substitutions mapping or build request will result in error. For example, if your build request includes $_FOO and the substitutions mapping doesn't define _FOO, you will receive an error after running your build or invoking a trigger if your trigger includes substitution variables.

    The following substitution variables always contain a default empty-string value even if you don't set the ALLOW_LOOSE option:

    • $REPO_NAME
    • $REPO_FULL_NAME
    • $BRANCH_NAME
    • $TAG_NAME
    • $COMMIT_SHA
    • $SHORT_SHA

    When defining a substitution variable, you aren't limited to static strings. You also have access to the event payload that invoked your trigger. These are available as payload bindings. You can also apply bash parameter expansions on substitution variables and store the resulting string as a new substitution variable. To learn more, see Using payload bindings and bash parameter expansions in substitutions.

    Dynamic substitutions

    You can reference the value of another variable within a user-defined substitution by setting the dynamicSubstitutions option to true in your build config file. If your build is invoked by a trigger, the dynamicSubstitutions field is always set to true and does not need to be specified in your build config file. If your build is invoked manually, you must set the dynamicSubstitutions field to true for bash parameter expansions to be interpreted when running your build.

    The following build config file shows the substitution variable ${_IMAGE_NAME} referencing the variable, ${PROJECT_ID}. The dynamicSubstitutions field is set to true so the reference is applied when invoking a build manually:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', '${_IMAGE_NAME}', '.']
    substitutions:
        _IMAGE_NAME: '${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/test-image'
    options:
        dynamicSubstitutions: true
    

    JSON

    {
        "steps": [
          {
              "name": "gcr.io/cloud-builders/docker",
              "args": [
                "build",
                "-t",
                "${_IMAGE_NAME}",
                "."
              ]
          }
        ],
        "substitutions": {
          "_IMAGE_NAME": "${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPOSITORY}/test-image"
        },
        "options": {
          "dynamic_substitutions": true
        }
    }
    

    For more information, see Applying bash parameter expansions.

    Secret substitutions

    You can substitute secrets from Secret Manager in Cloud Build. To do so, include your substitution variable in the value of the versionName field in your build config file.

    The following example shows how to define a substitution for a secret version.

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      entrypoint: 'bash'
      args: ['-c', 'docker login --username=$$USERNAME --password=$$PASSWORD']
      secretEnv: ['USERNAME', 'PASSWORD']
    
    availableSecrets:
      secretManager:
      - versionName: projects/$PROJECT_ID/secrets/my-docker-password/versions/$_SECRET_VERSION
        env: 'PASSWORD'
      - versionName: projects/$PROJECT_ID/secrets/my-docker-username/versions/latest
        env: 'USERNAME'
    
    substitutions:
        _SECRET_VERSION: '1' #Default value for the secret version
    

    JSON

    {
      "steps": [
        {
          "name": "gcr.io/cloud-builders/docker",
          "entrypoint": "bash",
          "args": [
            "-c",
            "docker login --username=$$USERNAME --password=$$PASSWORD"
          ],
          "secretEnv": [
            "USERNAME",
            "PASSWORD"
          ]
        }
      ],
      "availableSecrets": {
        "secretManager": [
          {
            "versionName": "projects/$PROJECT_ID/secrets/my-docker-password/versions/$_SECRET_VERSION",
            "env": "PASSWORD"
          },
          {
            "versionName": "projects/$PROJECT_ID/secrets/my-docker-username/versions/latest",
            "env": "USERNAME"
          }
        ]
      },
      "substitutions": {
        "_SECRET_VERSION": "1"
      }
    }
    
    
    

    如需详细了解 Cloud Build 中的 Secret,请参阅 Cloud Build 文档中的使用 Secret Manager 中的 Secret

    将替代变量映射到环境变量

    脚本不直接支持替代变量,但支持环境变量。您可以将替代变量映射到环境变量,可以一次性自动映射所有替代变量,也可以通过自行定义每个环境变量来手动映射。

    自动映射替代变量

    • 在构建级层 。如需自动将所有替代变量映射到环境变量(这些变量将在整个构建过程中可用),请在构建级层将 automapSubstitutions 设置为 true 作为选项。例如,以下构建配置文件显示了用户定义的替代变量 $_USER 和默认替代变量 $PROJECT_ID 映射到环境变量:

      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"
        }
      }
      
    • 在步骤级层 。如需自动映射所有替代变量并使其在单个步骤中作为环境变量可用,请在该步骤中将 automapSubstitutions 字段设置为 true。在以下示例中,只有第二个验证步骤会正确显示替代变量,因为它是唯一启用了自动替代变量映射的步骤:

      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"
        }
      

      此外,您可以使替代变量在整个构建中作为环境变量可用,然后在某个步骤中忽略它们。在构建级层将 automapSubstitutions 设置为 true,然后在要忽略替代变量的步骤中将同一字段设置为 false。在以下示例中,即使在构建级层启用了映射替代变量,项目 ID 也不会在第二个验证步骤中打印,因为在该步骤中 automapSubstitutions 设置为 false

      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"
        }
      

    手动映射替代变量

    您可以手动将替代变量映射到环境变量。每个 环境变量都在步骤级层使用 the env field定义,变量的作用域仅限于定义它们的步骤 。此字段接受键和值的列表。

    以下示例展示了如何将替代变量 $PROJECT_ID 映射到环境变量 BAR

    YAML

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

    JSON

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

    后续步骤