shellgoogle-cloud-platformparameterspipelinesubstitution

GCP CloudBuild substitution fails in pipeline


According to the GCP CloudBuild documentation one can use shell parameter expansion in pipeline substitutions.

I want to define a tag name for docker images based on the names of our git branches. Those names must contain only lowercase characters and no slashes. So I want to use parameter expansion for this:

substitutions:
    _BRANCH_NAME_LOWERCASED: ${BRANCH_NAME,,} # to lowercase
    _BRANCH_NAME_FLATTENED: ${_BRANCH_NAME_LOWERCASED////-} # replace "/" with "-"
    _DOCKER_IMAGE_TAG: ${SHORT_SHA:-$_BRANCH_NAME_FLATTENED}

This fails in the second step however:

[_BRANCH_NAME_FLATTENED -> ${_BRANCH_NAME_LOWERCASED////-}]: bad substitution

So apparently the first expansion works, the second fails. Which suggests that expansion seems to be available only in parts.

Which is surprising, since this works on CLI:

$ SHORT_SHA=
$ BRANCH_NAME=BRANCH-80/some-fancy-feature
$
$ _BRANCH_NAME_LOWERCASED=${BRANCH_NAME,,}
$ _BRANCH_NAME_FLATTENED=${_BRANCH_NAME_LOWERCASED////-}
$ _DOCKER_IMAGE_TAG=${SHORT_SHA:-$_BRANCH_NAME_FLATTENED}
$
$ echo $_DOCKER_IMAGE_TAG
branch-80-some-fancy-feature

Two questions:

  1. Do I miss something here or is substitution really implemented only "partially"?
  2. Anyone got an idea for me how else to achieve such tag name?

UPDATE:

A colleague suggested to "escape" the slash inside the second expansion rule, the slash that actually should get replaced. I see neither a reason for that, nor any hint towards that in any documentation, nor did tests into the direction succeed.

However it turns out that this pattern does not throw above error, so the expansion rule appears to get applied:

 _BRANCH_NAME_FLATTENED: ${_BRANCH_NAME_LOWERCASED//\\//-}

Once more: This does not work! But it is interesting, that no error is raised with that command. It simply does not have any effect, which makes sense since I would assume it tries to replace occurrances of a literal "/" in the subject, which simply does not exist.


Solution

  • You need to escape the slash (\/ because the substitution is using / as its delimiter.

    Example: cloudbuild.yaml:

    steps:
    - name: bash
      args:
      - -c
      - |
        echo ${BRANCH_NAME}
        echo ${_BRANCH_NAME_LOWERCASED}
        echo ${_BRANCH_NAME_FLATTENED}
    
    substitutions:
      _BRANCH_NAME_LOWERCASED: ${BRANCH_NAME,,}
      _BRANCH_NAME_FLATTENED: ${_BRANCH_NAME_LOWERCASED//\//-}
    
    options:
      dynamicSubstitutions: true
    

    And:

    gcloud builds submit \
    --config=cloudbuild.yaml \
    --project=${PROJECT} \
    --substitutions=BRANCH_NAME="FOO/BAR"
    
    FOO/BAR
    foo/bar
    foo-bar