GitLab CI (.gitlab-ci.yml) 的多行 YAML 字符串
Multiline YAML string for GitLab CI (.gitlab-ci.yml)
我正在尝试编写一个使用多行字符串作为命令的 gitlab-ci.yml
文件。但是,它似乎没有被解析。我已经尝试了 - |
和 - >
,结果相同。
stages:
- mystage
Build:
stage: mystage
script:
- |
echo -e "
echo 'hi';
echo 'bye';
"
当它尝试 运行 时,它只显示 echo -e '
作为 运行 的脚本,而不是整个多行字符串。这给我带来了问题。
写这样的东西的正确语法是什么?
TL;DR;您想要使用多行 YAML 标量(为了可读性),它作为单行字符串加载,可以由 Gitlab-CI 作为命令发出。为此,请在 YAML 中使用普通(不带引号)标量,该标量分布在多行中:
script:
- echo -e
"echo 'hi';
echo 'bye';"
请注意,YAML 对此类标量施加了一些限制。您当然需要知道的是,后面的每一行至少比 echo -e
多缩进一个位置(相对于其集合节点缩进两个位置,根本不缩进),并且每个换行符加载时被 space 替换(因此您需要注意换行符的放置位置)。
您的 post 中存在多种误解,导致您问错了问题。
不存在多行 YAML 字符串。 YAML 有标量,其中一些标量可以由程序作为字符串加载,而其他一些将作为整数、浮点数等加载。
您显然对作为字符串加载的标量节点感兴趣,因为该字符串随后可以解释为命令行。但是您不希望拥有多行命令行(即嵌入换行符),因为 Gitlab CI 不支持 multi-line scripts(如 @Jordan 所示)。
为了便于阅读,您希望使用 YAML 的标准功能将多行标量加载为单行字符串。
如果您不关心可读性,您可以使用:
- echo -e "\n echo 'hi';\n echo 'bye';\n"
并且由于您的标量未被引用(即它以 echo
开头),您不需要在 YAML 中为反斜杠或引号做任何特殊的事情。
脚本的结果是一样的(打印空行,打印echo 'hi';
一行缩进四space,打印echo 'bye';
一行缩进四spaces.)
如果您想使用多行输入以提高可读性,将其作为单行加载,基本上有两种选择:使用多行平面标量或在 YAML 中使用折叠标量。
多线普通标量
Plain 表示标量不带引号,与 YAML 中的任何多行内容一样,多行表示后续行需要适当缩进,在这种情况下比初始行更远
script:
- echo -e
"echo 'hi';
echo 'bye';"
换行符被替换为 spaces 所以不要这样做:
script:
- echo -e
"echo 'hi';
echo '
bye';"
因为您会在 bye
.
之前看到一个可见的 space
有一些限制,比如在这样的标量中不能有冒号后跟 space(这会使它看起来像键值对)。
没有必要在普通标量中转义反斜杠,因为您无法在普通标量中转义任何字符,但是您当然可以包含一个反斜杠,它最终会出现在从 YAML 和 can 对从该字符串执行的命令有意义。
折叠标量
折叠标量类似于普通标量,因为所有(单个)换行符在加载期间都被 space 替换:
script:
- >
echo -e
"echo 'hi';
echo 'bye';"
您需要将实际命令信息缩进至少与折叠标量指示符 (>
) 一样多。
与普通标量相反,:
之类的东西没有特殊含义。因此,如果普通标量因抛出 YAML 错误而失败,类似的折叠标量很可能不会。
我先发制人地来到这里,以为这会是个问题,但以下 "multi-line" 可读性命令对我有用:
Gitlab Runner: Shell Runner版本1.11.0
/ Gitlab 版本: 8.17.2
myjob:
stage: deploy
script:
# Single line command
- az component update --add sql
# Multi-line command
- az sql server create -n ${variable} -g ${variable} -l ${variable}
--administrator-login ${variable} --administrator-login-password ${variable}
您可以通过 yaml literal_block 和锚点功能使用任何多行 scripts/commands。示例:
.build: &build |
echo -e "\n$hl Building $green$build_path/$build_assets_dir/*.js $nl\n"
echo -e "javascript-obfuscator $build_path/$build_assets_dir/*.js"
[...]
build:master:
stage: build
script:
- *rsync
- *build
[...]
wp config create 命令非常挑剔...来自 .gitlab-ci...
build:
stage: build
script:
- echo "Building the app"
- |
wp config create --dbname=$vardb --dbhost=$varhost --dbuser=$varusr --dbpass=$varpas --extra-php <<PHP
define( 'WP_DEBUG', false );
define( 'FS_METHOD', 'direct' );
define( 'WP_POST_REVISIONS', 5 );
define( 'AUTOSAVE_INTERVAL', 600 );
PHP
- scp ./wp-config.php continued...
allow_failure: true
这对我在特拉维斯有用 CI
before_install:
- set -e
- |
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd\">
<servers>
<server>
<id>github</id>
<username>${GITHUB_USERNAME}</username>
<password>${GITHUB_PASSWORD}</password>
</server>
</servers>
</settings>
" > ${HOME}/.m2/settings.xml
这里两个环境变量(${GITHUB_USERNAME}
和${GITHUB_PASSWORD}
)也会被插值
这种格式可以。在 YAML 中使用普通(不带引号)标量。例如用于初始化 terraform 后端的脚本
before_script:
- cd ${TF_ROOT}
- terraform init -backend-config="address=${GITLAB_TF_ADDRESS}"
-backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock"
-backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock"
-backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_ACCESS_TOKEN}"
-backend-config="lock_method=POST" -backend-config="unlock_method=DELETE"
-backend-config="retry_wait_min=5"
我正在尝试编写一个使用多行字符串作为命令的 gitlab-ci.yml
文件。但是,它似乎没有被解析。我已经尝试了 - |
和 - >
,结果相同。
stages:
- mystage
Build:
stage: mystage
script:
- |
echo -e "
echo 'hi';
echo 'bye';
"
当它尝试 运行 时,它只显示 echo -e '
作为 运行 的脚本,而不是整个多行字符串。这给我带来了问题。
写这样的东西的正确语法是什么?
TL;DR;您想要使用多行 YAML 标量(为了可读性),它作为单行字符串加载,可以由 Gitlab-CI 作为命令发出。为此,请在 YAML 中使用普通(不带引号)标量,该标量分布在多行中:
script:
- echo -e
"echo 'hi';
echo 'bye';"
请注意,YAML 对此类标量施加了一些限制。您当然需要知道的是,后面的每一行至少比 echo -e
多缩进一个位置(相对于其集合节点缩进两个位置,根本不缩进),并且每个换行符加载时被 space 替换(因此您需要注意换行符的放置位置)。
您的 post 中存在多种误解,导致您问错了问题。
不存在多行 YAML 字符串。 YAML 有标量,其中一些标量可以由程序作为字符串加载,而其他一些将作为整数、浮点数等加载。
您显然对作为字符串加载的标量节点感兴趣,因为该字符串随后可以解释为命令行。但是您不希望拥有多行命令行(即嵌入换行符),因为 Gitlab CI 不支持 multi-line scripts(如 @Jordan 所示)。
为了便于阅读,您希望使用 YAML 的标准功能将多行标量加载为单行字符串。
如果您不关心可读性,您可以使用:
- echo -e "\n echo 'hi';\n echo 'bye';\n"
并且由于您的标量未被引用(即它以 echo
开头),您不需要在 YAML 中为反斜杠或引号做任何特殊的事情。
脚本的结果是一样的(打印空行,打印echo 'hi';
一行缩进四space,打印echo 'bye';
一行缩进四spaces.)
如果您想使用多行输入以提高可读性,将其作为单行加载,基本上有两种选择:使用多行平面标量或在 YAML 中使用折叠标量。
多线普通标量
Plain 表示标量不带引号,与 YAML 中的任何多行内容一样,多行表示后续行需要适当缩进,在这种情况下比初始行更远
script:
- echo -e
"echo 'hi';
echo 'bye';"
换行符被替换为 spaces 所以不要这样做:
script:
- echo -e
"echo 'hi';
echo '
bye';"
因为您会在 bye
.
有一些限制,比如在这样的标量中不能有冒号后跟 space(这会使它看起来像键值对)。
没有必要在普通标量中转义反斜杠,因为您无法在普通标量中转义任何字符,但是您当然可以包含一个反斜杠,它最终会出现在从 YAML 和 can 对从该字符串执行的命令有意义。
折叠标量
折叠标量类似于普通标量,因为所有(单个)换行符在加载期间都被 space 替换:
script:
- >
echo -e
"echo 'hi';
echo 'bye';"
您需要将实际命令信息缩进至少与折叠标量指示符 (>
) 一样多。
与普通标量相反,:
之类的东西没有特殊含义。因此,如果普通标量因抛出 YAML 错误而失败,类似的折叠标量很可能不会。
我先发制人地来到这里,以为这会是个问题,但以下 "multi-line" 可读性命令对我有用:
Gitlab Runner: Shell Runner版本1.11.0 / Gitlab 版本: 8.17.2
myjob:
stage: deploy
script:
# Single line command
- az component update --add sql
# Multi-line command
- az sql server create -n ${variable} -g ${variable} -l ${variable}
--administrator-login ${variable} --administrator-login-password ${variable}
您可以通过 yaml literal_block 和锚点功能使用任何多行 scripts/commands。示例:
.build: &build |
echo -e "\n$hl Building $green$build_path/$build_assets_dir/*.js $nl\n"
echo -e "javascript-obfuscator $build_path/$build_assets_dir/*.js"
[...]
build:master:
stage: build
script:
- *rsync
- *build
[...]
wp config create 命令非常挑剔...来自 .gitlab-ci...
build:
stage: build
script:
- echo "Building the app"
- |
wp config create --dbname=$vardb --dbhost=$varhost --dbuser=$varusr --dbpass=$varpas --extra-php <<PHP
define( 'WP_DEBUG', false );
define( 'FS_METHOD', 'direct' );
define( 'WP_POST_REVISIONS', 5 );
define( 'AUTOSAVE_INTERVAL', 600 );
PHP
- scp ./wp-config.php continued...
allow_failure: true
这对我在特拉维斯有用 CI
before_install:
- set -e
- |
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd\">
<servers>
<server>
<id>github</id>
<username>${GITHUB_USERNAME}</username>
<password>${GITHUB_PASSWORD}</password>
</server>
</servers>
</settings>
" > ${HOME}/.m2/settings.xml
这里两个环境变量(${GITHUB_USERNAME}
和${GITHUB_PASSWORD}
)也会被插值
这种格式可以。在 YAML 中使用普通(不带引号)标量。例如用于初始化 terraform 后端的脚本
before_script:
- cd ${TF_ROOT}
- terraform init -backend-config="address=${GITLAB_TF_ADDRESS}"
-backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock"
-backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock"
-backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_ACCESS_TOKEN}"
-backend-config="lock_method=POST" -backend-config="unlock_method=DELETE"
-backend-config="retry_wait_min=5"