YAML 九成报错都是缩进:CI/CD 配置避坑清单
上周组里一个新人把 GitHub Actions 工作流推上去,CI 直接红了一片。本地 act 跑得好好的,到他这儿的 runner 死活认不出来。我让他把 .github/workflows/deploy.yml 发我,肉眼看过去一切正常。直到我把光标挪到 steps: 那一行往后,才看见下面 - name: Check out 前面的空格少了一个。就一个。
YAML 不靠括号也不靠分号,层级完全靠缩进表达。这设计读起来舒服,写起来坑多。配置文件解析失败,原因九成不在业务逻辑,在缩进和类型转换。下面这四个是我这些年排过最多的。
第一个坑:用了 Tab 缩进
YAML 规范明确禁止 Tab 做缩进,只能用空格。但绝大多数编辑器按一下 Tab 键默认插入制表符,于是你在 VS Code 里敲得飞起,提交后 CI 解析直接挂。
# 错:services 下面用了 Tab
services:
web:
image: nginx
# 对:全部用空格
services:
web:
image: nginx
预防办法是在编辑器里开启「Tab 转空格」。VS Code 设置项 editor.insertSpaces: true、editor.tabSize: 2,Sublime、JetBrains 系列都有同样的选项。团队里最好把这条写进 .editorconfig,仓库根目录一份,所有人 clone 下来就对:
[*.{yml,yaml}]
indent_style = space
indent_size = 2
第二个坑:同级元素缩进不一致
这个坑最阴。同一个列表或同一层 map,差一个空格就报错,肉眼还看不出来。
# 错:第二个 service 少缩进了一个空格
services:
api:
image: my-api
worker: # 这行少了一个空格
image: my-worker
# 对:同级元素对齐
services:
api:
image: my-api
worker:
image: my-worker
上次排查过一起 GitLab CI 故障,build 和 test 两个 job,一个缩进 2 空格、一个缩进 3 空格。本地 GitLab Runner 没报错(解析器宽容度高一点),推到托管版直接报 mapping values are not allowed here。一通 diff 比对才发现差了一个空格。从那以后我团队立的规矩:YAML 必须过格式化工具,CI 里挂一道校验。
Kubernetes 的 manifest 也一样。spec.containers 下面每个容器对齐,ports 下面每个端口对齐,差一空格 kubectl apply 就失败。
第三个坑:冒号后没有空格
这条是新手坑,但踩过的都知道有多浪费时间。
# 错:冒号后紧贴 value
image:nginx:1.25
# 对:冒号后面留一个空格
image: nginx:1.25
YAML 里 key: value 是固定语法,冒号后面必须有一个空格。没空格会被当成一个整体字符串。注意值里如果本身带冒号(比如镜像 tag nginx:1.25),那个冒号后面要不要空格取决于它是不是「key: value」结构里的那个冒号。不确定的时候,整个值加引号最稳:image: "nginx:1.25"。
第四个坑:yes/no/on/off 被解析成布尔
这条不是缩进问题,但跟配置文件排错高度相关,必须单独说。
YAML 1.1 规范规定了一组布尔值的别名:yes、no、on、off、true、false(大小写不敏感)。你以为写的是字符串,解析器拿到的却是布尔。Docker Compose、GitHub Actions、Kubernetes(API server 用 YAML 1.1 时代的解析器)里都能复现。
典型踩坑:Kubernetes 里 ConfigMap 想存一个 PostgreSQL 的参数 sslmode: no,apply 进去发现值变成了 false,应用拿到的不是 no 是 false,连不上数据库还查不出来原因。
# 错:no 被解析成布尔 false
config:
sslmode: no
enable_feature: yes
region: on
# 对:加引号明确为字符串
config:
sslmode: "no"
enable_feature: "yes"
region: "on"
同样的还有数字。version: 123 会被解析成整数 123,如果你需要字符串 "123",加引号。版本号、以 0 开头的编号(比如 012 可能被当成八进制)尤其要注意。还有 null、~ 都会被解析成空值。
排查这类问题的办法:把 YAML 转成 JSON 看一眼,类型一目了然。
实操:用工具替你做眼力活
排查 YAML 问题时与其肉眼对空格,不如直接丢进 UPTools YAML 格式化工具。它能把错乱的缩进重新对齐,顺带做语法校验,第一次出错的行号会标出来;还能一键把 YAML 转成 JSON,yes/no 被转成 true/false 的瞬间你就知道踩了隐式类型的坑。所有解析在浏览器本地完成,配置文件不外传。
另外建议在 CI 里加一道 yamllint 或 prettier --parser yaml,提交时就拦掉绝大多数缩进和格式问题,不用等流水线红了才回头查。
三句话总结
YAML 禁 Tab,编辑器开「Tab 转空格」,仓库里放一份 .editorconfig。同级元素缩进必须一致,冒号后必须留空格,过不去的坎先丢进格式化工具看行号。yes/no/on/off/123 会被隐式转成布尔或数字,含这类值时一律加引号,转 JSON 看类型是最快的验证方式。
相关文章