替換變數值

在建構設定檔中使用 substitutions 可在建構時間替換特定變數。

對於值在建構之前仍未知的變數,或者以不同變數值重複使用現有建構要求而言,substitutions 很實用。

Cloud Build 提供內建 substitutions,您也可以定義自己的 substitutions。在建構的 stepsimages 中使用 substitutions,可在建構時解析其值。

本頁面說明如何使用預設替代變數,或定義您自己的substitutions

使用預設 substitutions

Cloud Build 為所有建構作業提供下列預設替代變數:

  • $PROJECT_ID:雲端專案的 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:建構執行期間使用的建構設定檔路徑;否則,如果建構是在觸發條件中內嵌設定,或使用 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:提取要求編號

如果預設 substitution 無法使用 (例如不適用於無原始碼建構,或使用儲存空間原始碼的建構),系統會將出現的遺失變數取代為空字串。

使用 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 substitution:

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 substitution 將映像檔推送至 Artifact Registry:

在這個例子中:

  • 建構要求有一個建構步驟,使用 gcr.io/cloud-builders 中的 docker 建構步驟來建構 Docker 映像檔。
    • 步驟中的 args 欄位會指定要傳送至 docker 指令的引數,在這個範例中會叫用 build -t gcr.io/my-project/cb-demo-img . (將 $PROJECT_ID 替代為您的專案 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"
  ]
}

使用使用者定義的 substitutions

您也可以定義自己的 substitutions。使用者定義的 substitutions 必須符合下列規則:

  • 取代項的開頭必須為底線 (_),且只能使用大寫字母和數字 (遵循規則運算式 _[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 的值。不過,${} 不用空格就可以成功 substitution,進而允許使用像是 ${_FOO}BAR 這樣的 substitutions。
    • $$ 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 中的密鑰,請參閱 Cloud Build 說明文件中的「使用 Secret Manager 中的密鑰」。

    將替代項目對應至環境變數

    指令碼不直接支援替代,但支援環境變數。您可以將替代項目對應至環境變數,方法是自動一次完成所有對應,或是手動定義每個環境變數。

    自動對應替代字元

    • 在建構層級。如要自動將所有替代項目對應至環境變數,並在整個建構過程中提供這些變數,請在建構層級將 automapSubstitutions 設為 true 選項。舉例來說,下列建構設定檔顯示對應至環境變數的使用者定義 substitution $_USER 和預設 substitution $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"
        }
      

    手動對應替代變數

    您可以手動將替代項目對應至環境變數。每個環境變數都是在步驟層級使用env 欄位定義,且變數的範圍僅限於定義變數的步驟。這個欄位會採用鍵和值的清單。

    以下範例說明如何將替代項目 $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"
        }
      ]
    }
    

    後續步驟