Jenkins Groovy脚本中Helm字符串版本值传递问题
问题
在Jenkins流水线中运行如下Groovy脚本:
def test() { def RV1 = '\"' + "$RELEASE_VERSION" + '\"' echo RV1 sh """ helm upgrade --install -f container-root/helm/values-dev-caas.yaml --set image.registry=docker-reg --set-string image.version=""" + RV1 + """ test_app container-root/helm --namespace test --debug """ }
Jenkins日志生成的实际命令为:
helm upgrade --install -f container-root/helm/values-dev-caas.yaml --set image.registry=docker-reg --set-string image.version=202305251424 test-app container-root/helm --namespace test --debug
触发错误:
Error: UPGRADE FAILED: unable to decode "": json: cannot unmarshal number into Go struct field ObjectMeta.metadata.labels of type string
echo RV1的输出为"202305251424",但实际执行时image.version的双引号丢失,导致Helm把版本号当成数字解析,而部署模板中该字段需要字符串类型。
尝试修改RV1的定义:
def RV1 = '\'' + '\"' + "$RELEASE_VERSION" + '\"' + '\''
此时echo RV1输出为'"202305251510"',生成的命令变为:
helm upgrade --install -f container-root/helm/values-dev-caas.yaml --set image.registry=docker-reg --set-string 'image.version="202305251510"' test_app container-root/helm --namespace test --debug
又触发新错误:
Error: UPGRADE FAILED: YAML parse error on helm/templates/deployment.yaml: error converting YAML to JSON: yaml: line 72: did not find expected key
需要解决:如何在Groovy的sh步骤中为image.version值保留双引号,或者让Helm将版本值识别为字符串而非数字?
解决方案
方法1:正确转义双引号,直接构造带引号的版本变量
在Groovy中用\"转义双引号,构造带引号的版本字符串,再传入sh块:
def test() { def quotedVersion = "\"${RELEASE_VERSION}\"" echo quotedVersion sh """ helm upgrade --install -f container-root/helm/values-dev-caas.yaml \ --set image.registry=docker-reg \ --set-string image.version=${quotedVersion} \ test_app container-root/helm --namespace test --debug """ }
生成的命令会保留双引号:image.version="202305251424",Helm会将其识别为字符串。
方法2:利用Helm --set的单引号强制字符串语法
Helm支持用单引号包裹值来强制识别为字符串,直接在sh块中用单引号包裹版本号:
def test() { sh """ helm upgrade --install -f container-root/helm/values-dev-caas.yaml \ --set image.registry=docker-reg \ --set-string image.version='${RELEASE_VERSION}' \ test_app container-root/helm --namespace test --debug """ }
单引号会被传递给Helm,确保版本号被解析为字符串,避免数字类型问题。
方法3:通过环境变量传递版本号
将版本号存入环境变量,在sh块中引用时用\$避免Groovy提前插值,保留双引号:
def test() { withEnv(["RELEASE_VERSION=${RELEASE_VERSION}"]) { sh """ helm upgrade --install -f container-root/helm/values-dev-caas.yaml \ --set image.registry=docker-reg \ --set-string image.version="\$RELEASE_VERSION" \ test_app container-root/helm --namespace test --debug """ } }
内容的提问来源于stack exchange,提问作者szend
相关产品推荐
相关产品推荐

