2017-03-02 35 views
7

我正在嘗試編寫一個gitlab-ci.yml文件,該文件使用多行字符串作爲命令。但是,它似乎沒有被解析。我試過- |- >,結果相同。用於GitLab CI的多行YAML字符串(.gitlab-ci.yml)

stages: 
    - mystage 

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

當它試圖運行,那隻能說明echo -e '作爲腳本來運行,而不是整個多行字符串。這對我造成了問題。

寫這樣的東西的正確語法是什麼?

+0

這是不正確的YAML,你可能在'Build'後錯過了冒號。你確定你想爲'echo -e'和'echo'hi''使用相同的單引號,而不是對其中的一個使用雙引號? – Anthon

+0

對不起,這些都是我的例子中的錯誤。我糾正了他們。我使用的真實版本適用於在線YAML到JSON解析器,但在GitLab CI上失敗。 – samanime

+0

有這個問題:https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166我不清楚問題是什麼,因爲你的代碼*應該*是相當的(足夠)YAML到那裏提出的解決方案。你可以嘗試追加'''''到你的行,但我不能說這是否會起作用。 –

回答

1

由於這個問題似乎涉及到multi-line scripts在Gitlab CI(如@Jordan表示)和你的「劇本」不支持的其實是一個簡單的命令,你應該重寫它是在同一行:

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

因爲你的標量沒有被引用(即它以echo開頭),所以你不需要在YAML中做任何特殊的反斜槓或引號。

腳本的結果是一樣的。如果你想使用多線(上縮進4個空格的行縮進4個空格的行打印一個空行,打印echo 'hi';,打印echo 'bye';

爲了便於閱讀,最好的選擇是預處理輸入。我建議使用Python和ruamel.yaml(免責聲明:我是作者),它允許您在保留特徵時引用引號和評論。

鑑於這種gitlab-ci.in.yml

stages: 
    - 'mystage' 

Build: 
    stage: mystage 
    # the following is rewritten 
    script: 
    - | 
     echo -e " 
      echo 'hi'; 
      echo 'bye'; 
     " 

和以下Python(第3版)程序:

from pathlib import Path 
import ruamel.yaml 


def flatten_multi_line(d): 
    if isinstance(d, list): 
     for idx, elem in enumerate(d): 
      if isinstance(elem, (list, dict)): 
       flatten_multi_line(elem) 
      elif isinstance(elem, ruamel.yaml.scalarstring.PreservedScalarString): 
       d[idx] = ruamel.yaml.scalarstring.DoubleQuotedScalarString(elem) 
    elif isinstance(d, dict): 
     for key in d: 
      if isinstance(d[key], (list, dict)): 
       flatten_multi_line(d[key]) 
      elif isinstance(d[key], ruamel.yaml.scalarstring.PreservedScalarString): 
       d[key] = ruamel.yaml.scalarstring.DoubleQuotedScalarString(elem) 


in_file = Path('gitlab-ci.in.yml') 
out_file = Path('gitlab-ci.yml') 

with in_file.open() as fp: 
    data = ruamel.yaml.round_trip_load(fp, preserve_quotes=True) 
flatten_multi_line(data) 
with out_file.open('w') as fp: 
    ruamel.yaml.round_trip_dump(data, fp) 

給出以下gitlab-ci.yml

stages: 
- 'mystage' 

Build: 
    stage: mystage 
    # the following is rewritten 
    script: 
    - "echo -e \"\n echo 'hi';\n echo 'bye';\n\"\n" 

(不flatten_multi_line()多線字符串將保存爲w ELL)。

從程序,你還可能引發新生成的YAML文件的處理(例如,使用subprocess.check_output(),確保使用str()如果你想投out_file作爲參數傳遞給check_output()

+0

爲了清晰和可維護性,我想將它寫成多行。雖然我的例子很瑣碎,但真正的腳本決不是。 – samanime

+0

我能理解。在GitLab CI正在處理可讀的YAML文件之前預處理它是否可以接受? – Anthon

+0

我已經考慮過了。這是一個額外的步驟,並增加了一點複雜性,但可能是值得的。 – samanime

11

我來到這裏搶先期待這將是一個問題,但下面的「多行」的可讀性命令爲我工作:

Gitlab亞軍:殼牌亞軍版本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} 

道歉,如果我誤解了問題或我遇到了一些邊緣案件的寬限期。

+0

這適用於我指定多行字符串 – dalore

2

您可以通過yaml literal_block和錨點功能使用任何多行腳本/命令。例如:

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

感謝您分享 - 此更高級的功能對於作業的可讀性/能夠在整個配方中重用代碼塊特別有用。 – PotatoFarmer