适用于GitLab CI的多行YAML字符串(.gitlab-ci.yml)


83

我正在尝试编写一个gitlab-ci.yml使用多行字符串作为命令的文件。但是,似乎它没有被解析。我已经尝试了- |- >具有相同的结果。

stages:
  - mystage

Build:
  stage: mystage
  script:
    - |
        echo -e "
            echo 'hi';
            echo 'bye';
        "

尝试运行时,它仅显示echo -e '为要运行的脚本,而不显示整个多行字符串。这给我带来了问题。

写这样的东西的正确语法是什么?


这有一个问题:gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166我不清楚问题是什么,因为您的代码与那里提出的解决方案等效(足够)YAML 。您可以尝试追加\到行中,但是我不能说是否行得通。
乔丹(Jordan)

Answers:


35

TL; DR; 您想要使用多行YAML标量(出于可读性),该标量作为单行字符串加载,可以由Gitlab-CI作为命令发出。为此,请在YAML中使用普通的(不带引号)标量,该标量分布在多行中:

script:
- echo -e 
   "echo 'hi';
    echo 'bye';"

请注意,YAML对此类标量施加了一些限制。您当然需要知道的是,每行的缩进位置至少比echo -e其缩进一个位置(相对于其集合节点缩进两个位置,而缩进位置则完全不缩进),并且每行都被空格替换加载时(因此您需要注意放置换行符的位置)。


您的帖子中存在多种误解,导致您提出错误的问题。

没有多行YAML字符串之类的东西。YAML具有标量,其中一些标量可以由程序作为字符串加载,而其他标量可以作为整数,浮点数等加载。

您显然对作为字符串加载的标量节点感兴趣,因为可以将该字符串解释为命令行。但是您不希望有多行命令行(即带有嵌入式换行符),因为Gitlab CI不支持多行脚本(如@Jordan所示)。

为了提高可读性,您想使用YAML的标准功能将多行标量加载为单行字符串。

如果您不关心可读性,可以使用:

- echo -e "\n    echo 'hi';\n    echo 'bye';\n"

并且因为您的标量没有被引用(即,它以 echo),因此您无需在YAML中对反斜杠或引号进行任何特殊处理。

脚本的结果是相同的(打印一个空行,echo 'hi';在一行上缩进四个空格,echo 'bye';在一行上缩进四个空格,打印)。

如果要使用多行输入以提高可读性(它们作为单行加载),则实际上有两种选择:在YAML中使用多行平面标量或使用折叠标量。

多线普通标量

Plain表示标量不加引号,并且与YAML中的任何多行事物一样,multi-line意味着需要适当缩进以下几行,在这种情况下,应比初始行缩进更多

script:
- echo -e 
   "echo 'hi';
    echo 'bye';"

换行符被空格代替,所以不要这样做:

script:
- echo -e 
   "echo 'hi';
    echo '
   bye';"

因为您将在之前获得一个可见的空间bye

存在一些限制,例如您不能在这样的标量内使用冒号后跟空格(这会使它看起来像键值对)。

没有必要为了逃避简单的标量反斜杠,你无法逃避的一个普通的标量的任何字符,但当然也可以包括一个反斜杠,这将从YAML加载的字符串结束,并可以有意为执行的命令从那个字符串。

折叠标量

折叠标量与普通标量相似,因为在加载过程中,所有(单个)换行符都由空格代替:

script:
- >
  echo -e 
  "echo 'hi';
  echo 'bye';"

您需要缩进的实际命令信息至少与折叠的标量指示符(>)一样多。

与普通标量相反,诸如此类的东西:没有特殊含义。因此,如果普通标量因抛出YAML错误而失败,则类似的折叠标量极有可能不会。


我想将其写成多行,以保持清晰度和可维护性。虽然我的例子很简单,但是真正的脚本绝对不是。
samanime

我能理解 在GitLab CI处理您的可读YAML文件之前对其进行预处理是否可以?
Anthon

我考虑过了。这是一个额外的步骤,并且增加了一些复杂性,但可能值得。
samanime

我添加了一个可能的解决方案。
Anthon

3
好家伙。尽管从技术上讲是正确的,但是这个答案在冗长的程度上令人难以理解。大家不要写YAML解析器可能只是想PotatoFarmer高度upvoted和很多更简洁的答案,而不是。
Cecil Curry

111

我是来这里的,所以这是一个问题,但是下面的“多行”可读性命令对我有用:

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}

2
这有什么窍门?您是否将第二行缩进到与第一行相同的水平?
Victor Grazi

6
@ victor-grazi据我了解:在普通的YAML(普通流标量)中,转义符(例如newline \n)不执行任何操作,并且忽略了开头的空格-Gitlab YAML似乎以这种方式解析脚本块。关于缩进:YAML规范指出In YAML block styles, structure is determined by indentation,因此第二行的缩进量与YAML规范要求的缩进相同(相对于父缩进一个空格),为可读性又增加了一行(从技术上讲是多余的,但更漂亮)。
PotatoFarmer

奇迹般有效。也适用于新行中的所有参数
bodolsog

25

您可以通过yamlliteral_block和anchors功能使用任何多行脚本/命令。例:

.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
[...]

感谢您的分享-这项更高级的功能对于作业的可读性/能够在整个配方中重用代码块特别有用。
PotatoFarmer

5
这是一个很好的例子,但是如果您定义.rsync,它将更加清晰
Victor

13

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

4

这在Travis 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})也将被插值


0

此格式将起作用。在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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.