2017-03-02 3 views
7

명령에 여러 줄 문자열을 사용하는 gitlab-ci.yml 파일을 작성하려고합니다. 그러나 파싱되지 않는 것 같습니다. - |- >을 모두 시도해 본 결과가 같습니다. GitLab CI (.gitlab-ci.yml)에 대한 다중 YAML 문자열

stages: 
    - mystage 

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

그것을 실행하려고

, 그것은 단지 실행할 스크립트, 그리고 전체 다중 문자열로 echo -e ' 보여줍니다. 이것은 나를 위해 문제를 일으킨다.

다음과 같이 작성하는 올바른 구문은 무엇입니까?

:
+0

잘못된 YAML입니다. '빌드'이후에 콜론이 누락 된 것 같습니다. '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

문제가 Gitlab CI (@Jordan가 표시)하고 "스크립트"에서 지원되지 않는 multi-line scripts 관련이있을 것으로 보인다 때문에

실제로 하나의 명령이다, 당신은 단지 한 줄에 그것을 다시한다
- echo -e "\n echo 'hi';\n echo 'bye';\n" 

스칼라가 인용되어 있지 않으므로 (예 : echo으로 시작) 백 슬래시 또는 따옴표에 대해 YAML에서 특별한 작업을 수행 할 필요가 없습니다.

스크립트의 결과는 (사 개 공간을 들여 줄에 네 개의 공간을 들여 줄에 인쇄 echo 'bye';을 인쇄 echo 'hi';을 빈 줄을 인쇄 할 수 있습니다.)

를 사용하면 멀티 라인을 사용하려는 경우 동일 입력이 가독성을 위해 가장 좋은 옵션은 입력을 사전 처리하는 것입니다. 파이썬과 ruamel.yaml (면책 조항 : 나는 저자)을 사용하는 것이 좋습니다. 이렇게하면 인용 부호 나 주석과 같은 기능을 그대로 유지할 수 있습니다.

gitlab-ci.in.yml 감안할 때 :

stages: 
    - 'mystage' 

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

다음과 같은 파이썬 (버전 3) 프로그램 :

stages: 
- 'mystage' 

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

합니다 (flatten_multi_line() 멀티를하지 않고 :

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 다음 제공 줄 문자열은 w로 보존됩니다. 엘). 당신은 또한 새로 생성 된 YAML 파일의 처리를 실행할 수있는 프로그램에서

+0

명확하고 유지 보수가 용이하도록 여러 줄로 써야겠다. 나의 예가 사소한 동안, 진짜 스크립트는 확실히 아니다. – samanime

+0

나는 그것을 이해할 수있다. GitLab CI로 처리되기 전에 읽을 수있는 YAML 파일을 사전 처리 할 수 ​​있습니까? – Anthon

+0

나는 그것을 고려했다. 그것은 추가 단계이며 약간의 복잡성을 가중 시키지만 그만한 가치가있을 수 있습니다. – samanime

11

내가 여기 온 선제 적 기대 (예 : subprocess.check_output()를 사용하여, 당신이 그것을 원하는 경우 check_output()에 인수로 str()를 사용 out_file 캐스팅해야합니다) 이 문제가 있지만 다음 "멀티 라인"이 될 것입니다 가독성에 대한 명령은 나를 위해 노력하고 있습니다 :

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