Codefresh打标Pipeline遇YAML校验循环错误,求社区排查逻辑
问题背景
配置了Codefresh Pipeline实现自动版本号升级与打标:仓库无标签时默认打0.0.0,PR描述含#major升级主版本、含#minor升级次版本,否则自动升级补丁版本。但Codefresh YAML校验器持续报错,错误信息如下:
LINE 15
"0" must be a string. Current value: [object Object]
Please make sure you have all the required fields and valid valuesLINE 28
"0" must be a string. Current value: [object Object]
Please make sure you have all the required fields and valid valuesLINE 70
"0" must be a string. Current value: [object Object]
Please make sure you have all the required fields and valid values
Pipeline代码如下:
version: "1.0" stages: - "clone" - "bump_version" - "push_tag" steps: clone_repo: title: "Cloning repository" type: "git-clone" repo: "${{CF_REPO_NAME}}" revision: "${{CF_BRANCH}}" stage: "clone" detect_last_tag: title: "Detecting last tag" type: "freestyle" image: "alpine/git" stage: "bump_version" commands: - | LAST_TAG=$(git describe --tags --abbrev=0 || echo '0.0.0') echo "LAST_TAG=\"$LAST_TAG\"" > /codefresh/volume/env_vars_to_export/env_vars volumes: - name: env_vars_to_export path: /codefresh/volume/env_vars_to_export determine_new_version: title: "Determining new version" type: "freestyle" image: "alpine/git" stage: "bump_version" commands: - | source /codefresh/volume/env_vars_to_export/env_vars echo "Last tag is $LAST_TAG" # Extract version components MAJOR=$(echo "$LAST_TAG" | cut -d. -f1) MINOR=$(echo "$LAST_TAG" | cut -d. -f2) PATCH=$(echo "$LAST_TAG" | cut -d. -f3) # Convert to strings explicitly MAJOR="${MAJOR}" MINOR="${MINOR}" PATCH="${PATCH}" echo "MAJOR: \"$MAJOR\", MINOR: \"$MINOR\", PATCH: \"$PATCH\"" # Determine the new version based on PR description if echo "$CF_PULL_REQUEST_DESCRIPTION" | grep -q "#major"; then MAJOR=$((MAJOR + 1)) MAJOR="${MAJOR}" MINOR="0" PATCH="0" elif echo "$CF_PULL_REQUEST_DESCRIPTION" | grep -q "#minor"; then MINOR=$((MINOR + 1)) MINOR="${MINOR}" PATCH="0" else PATCH=$((PATCH + 1)) PATCH="${PATCH}" fi NEW_TAG="${MAJOR}.${MINOR}.${PATCH}" echo "NEW_TAG=\"$NEW_TAG\"" > /codefresh/volume/env_vars_to_export/env_vars volumes: - name: env_vars_to_export path: /codefresh/volume/env_vars_to_export push_tag: title: "Pushing new tag" type: "freestyle" image: "alpine/git" stage: "push_tag" commands: - | source /codefresh/volume/env_vars_to_export/env_vars echo "Tagging with NEW_TAG: \"$NEW_TAG\"" git tag "$NEW_TAG" git push origin "$NEW_TAG" volumes: - name: env_vars_to_export path: /codefresh/volume/env_vars_to_export
问题原因
Codefresh的YAML解析器会自动解析双引号字符串中的表达式,把Shell算术运算语法$(( ))误判为Codefresh的插值语法,导致解析失败,返回[object Object]而非预期的字符串数字,触发校验错误。
解决方法
对Shell算术表达式中的$符号添加反斜杠转义,避免被Codefresh解析器误处理。修改后的determine_new_version步骤关键代码如下:
commands: - | source /codefresh/volume/env_vars_to_export/env_vars echo "Last tag is $LAST_TAG" # Extract version components MAJOR=$(echo "$LAST_TAG" | cut -d. -f1) MINOR=$(echo "$LAST_TAG" | cut -d. -f2) PATCH=$(echo "$LAST_TAG" | cut -d. -f3) # Convert to strings explicitly MAJOR="${MAJOR}" MINOR="${MINOR}" PATCH="${PATCH}" echo "MAJOR: \"$MAJOR\", MINOR: \"$MINOR\", PATCH: \"$PATCH\"" # Determine the new version based on PR description if echo "$CF_PULL_REQUEST_DESCRIPTION" | grep -q "#major"; then MAJOR=\$((MAJOR + 1)) MAJOR="${MAJOR}" MINOR="0" PATCH="0" elif echo "$CF_PULL_REQUEST_DESCRIPTION" | grep -q "#minor"; then MINOR=\$((MINOR + 1)) MINOR="${MINOR}" PATCH="0" else PATCH=\$((PATCH + 1)) PATCH="${PATCH}" fi NEW_TAG="${MAJOR}.${MINOR}.${PATCH}" echo "NEW_TAG=\"$NEW_TAG\"" > /codefresh/volume/env_vars_to_export/env_vars
转义后的\$(( ))会被Codefresh原封不动传递给Shell执行,Shell会自动去掉反斜杠并执行算术运算,同时YAML校验器不会再报错。
内容的提问来源于stack exchange,提问作者R. Barrett

