החלפת ערכי משתנים

משתמשים ב-substitutions בקובץ התצורה של ה-build כדי להחליף משתנים ספציפיים בזמן ה-build.

החלפות שימושיות למשתנים שהערך שלהם לא ידוע עד משך זמן של תהליך build, או לשימוש חוזר בבקשת בנייה קיימת עם ערכים שונים של משתנים.

‫Cloud Build מספק תחליפים מובנים, או שאתם יכולים להגדיר תחליפים משלכם. משתמשים ב-substitutions ב-steps וב-images של ה-build כדי לפתור את הערכים שלהם בזמן ה-build.

בדף הזה מוסבר איך להשתמש בהחלפות ברירת מחדל או להגדיר החלפות משלכםsubstitutions.

שימוש בהחלפות ברירת המחדל

‫Cloud Build מספק את החלפות ברירת המחדל הבאות לכל הבנייה:

  • $PROJECT_ID: מזהה הפרויקט בענן
  • $BUILD_ID: המזהה של הגרסה
  • $PROJECT_NUMBER: מספר הפרויקט
  • $LOCATION: האזור שמשויך ל-build

‫Cloud Build מספק את החלפות ברירת המחדל הבאות עבור בנייה שהופעלה על ידי טריגרים:

  • $TRIGGER_NAME: השם שמשויך לטריגר
  • $COMMIT_SHA: מזהה הקומיט שמשויך ל-build
  • $REVISION_ID: מזהה הקומיט שמשויך ל-build
  • $SHORT_SHA : שבעת התווים הראשונים של COMMIT_SHA
  • $REPO_NAME: השם של המאגר
  • $REPO_FULL_NAME: השם המלא של המאגר, כולל המשתמש או הארגון
  • $BRANCH_NAME: השם של הענף
  • $TAG_NAME: השם של התג
  • $REF_NAME: השם של הענף או התג
  • $TRIGGER_BUILD_CONFIG_PATH: הנתיב לקובץ הגדרות ה-build שבו נעשה שימוש במהלך ההפעלה של ה-build. אחרת, מחרוזת ריקה אם ה-build מוגדר בשורה בטריגר או אם נעשה בו שימוש ב-Dockerfile או ב-Buildpack.
  • $SERVICE_ACCOUNT_EMAIL: כתובת האימייל של חשבון השירות שבו אתם משתמשים לבנייה. זהו חשבון שירות שמוגדר כברירת מחדל או חשבון שירות שצוין על ידי המשתמש.
  • $SERVICE_ACCOUNT: שם המשאב של חשבון השירות, בפורמט projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL

‫Cloud Build מספק את ההחלפות הבאות שספציפיות ל-GitHub וזמינות לטריגרים של בקשות משיכה:

  • $_HEAD_BRANCH : ענף head של ה-pull request
  • $_BASE_BRANCH : ענף הבסיס של ה-pull request
  • $_HEAD_REPO_URL : כתובת ה-URL של מאגר הראשי של בקשת משיכה
  • $_PR_NUMBER : מספר ה-pull request

אם אין תחליף שמוגדר כברירת מחדל (למשל, בבנייה ללא מקור או בבנייה שמשתמשת במקור אחסון), המערכת מחליפה את המופעים של המשתנה החסר במחרוזת ריקה.

כשמתחילים בנייה באמצעות 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"
  ]
}

בדוגמה הבאה מוצגת בקשת build באמצעות שלב ה-build‏ docker ליצירת קובץ אימג', ואז העברת קובץ האימג' ל-Artifact Registry באמצעות החלפת ברירת המחדל $PROJECT_ID:

בדוגמה הזו:

  • בקשת ה-build כוללת שלב build אחד, שמשתמש בשלב ה-build‏ docker ב-gcr.io/cloud-builders כדי ליצור את קובץ האימג' של Docker.
    • השדה args בשלב מציין את הארגומנטים שיועברו לפקודה docker. במקרה הזה, הפקודה build -t gcr.io/my-project/cb-demo-img . תופעל (אחרי שהערך $PROJECT_ID יוחלף במזהה הפרויקט).
  • השדה images מכיל את שם התמונה. אם הבנייה תצליח, התמונה שנוצרה תועבר אל Artifact Registry. אם התמונה לא נוצרת בהצלחה על ידי ה-build, ה-build ייכשל.

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 בייט, ואורך ערך הפרמטר מוגבל ל-4,000 בייט.
  • אפשר לציין משתנים באחת משתי דרכים: $_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 Manager במסמכי התיעוד של Cloud Build.

    מיפוי של תחליפים למשתני סביבה

    סקריפטים לא תומכים ישירות בהחלפות, אבל הם תומכים במשתני סביבה. אפשר למפות החלפות למשתני סביבה, באופן אוטומטי בבת אחת או באופן ידני על ידי הגדרה של כל משתנה סביבה.

    מיפוי אוטומטי של החלפות

    • ברמת ה-build. כדי למפות באופן אוטומטי את כל ההחלפות למשתני סביבה שיהיו זמינים לאורך כל תהליך ה-build, מגדירים את automapSubstitutions ל-true כאפשרות ברמת ה-build. לדוגמה, בקובץ הגדרות הבנייה הבא מוצג המיפוי של ההחלפה שהוגדרה על ידי המשתמש $_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 ברמת ה-build, ואז מגדירים את אותו השדה ל-false בשלב שבו רוצים להתעלם מההחלפות. בדוגמה הבאה, למרות שהחלפת מיפויים מופעלת ברמת ה-build, מזהה הפרויקט לא יודפס בשלב השני, כי 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"
        }
      ]
    }
    

    המאמרים הבאים