As you know from writing scripts in .gitlab-ci.yml, the YAML syntax can be a bit restrictive, and escaping characters can make your eyes bleed.
I discovered a phenomenally useful feature in YAML syntax. Strings can be built with less escaping by starting the string with a >
or |
operator.
>
takes the lines that follow and joins them with spaces, while |
takes the lines that follow and joins them with newlines.This especially helps with any string where you have a bare :
so it’s understood as a colon instead of a new tag.
script: - echo http://yaml.thinks.this.is.a.key/bad/bad/bad
We used to hack this using single-quote '
escaping
script: - 'echo http://yaml.thinks.this.is.a.string/but.no.expansion/${variables}'
YAML has a nice construct for this using the |
script: - | echo http://yaml.thinks.this.is.a.string/isn't.this.easier?
So this is really lovely for making JSON using heredoc in YAML and shell.
Before:
- 'echo "{ \"name\": \"${CI_PROJECT_NAME}\", \"ref\": \"${CI_COMMIT_REF_NAME}\", \"pipe\": { \"id\": \"${CI_PIPELINE_ID}\", \"url\": \"${CI_PIPELINE_URL}\" }, \"build\": \"${CI_PIPELINE_IID}\", \"sha\": \"${CI_COMMIT_SHA}\" }" > ./build.json'
After:
- | cat > build.json <<HERE { "name": "${CI_PROJECT_NAME}", "ref": "${CI_COMMIT_REF_NAME}", "pipe": { "id": "${CI_PIPELINE_ID}", "url": "${CI_PIPELINE_URL}" }, "build": "${CI_PIPELINE_IID}", "sha": "${CI_COMMIT_SHA}" } HERE
That alone is worth the price of admission.
Note that the multiline operators remove the indent so you can use shell heredoc syntax successfully.
Here’s a good “calculator” to help visualize what |
and >
do: https://yaml-multiline.info/
which is explained well in https://lzone.de/cheat-sheet/YAML
thank you. this saved me a whole day of googling around