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