스크립트 및 작업 로그 문제 해결
스크립트 및 작업 로그 문제 해결
.gitlab-ci.yml에서 작업(script)을 짜다 보면 문법 오류, 명령이 실패했는데 작업이 성공으로 처리되는 문제, 출력이 이상하게 표시되는 문제 등을 자주 만나요. 이 문서는 GitLab CI/CD의 스크립트와 작업 로그에서 흔히 발생하는 문제들을 하나씩 살펴보고, 왜 그런 현상이 생기는지와 어떻게 고치는지를 옆에서 설명해 주는 방식으로 정리했어요.
특히 YAML 파서가 :(콜론)을 어떻게 해석하는지, 셸이 명령의 종료 코드를 어떻게 넘기는지 같은 미묘한 동작이 대부분의 원인이라는 점을 기억하면 좋아요.
출처: 문서
본문
:을 사용하는 스크립트에서 Syntax is incorrect 오류
스크립트에 콜론(:)을 사용하면 GitLab이 다음과 같은 오류를 출력할 수 있어요.
Syntax is incorrectscript config should be a string or a nested array of strings up to 10 levels deep
예를 들어 cURL 명령의 일부로 "PRIVATE-TOKEN: ${PRIVATE_TOKEN}"을 사용한다고 해볼게요.
pages-job:
stage: deploy
script:
- curl --header 'PRIVATE-TOKEN: ${PRIVATE_TOKEN}' "https://gitlab.example.com/api/v4/projects"
environment: production
YAML 파서는 :이 YAML 키워드를 정의한다고 생각해서 Syntax is incorrect 오류를 출력해요.
콜론을 포함하는 명령을 쓰려면 전체 명령을 작은따옴표로 감싸야 해요. 기존의 작은따옴표(')를 큰따옴표(")로 바꿔야 할 수도 있어요.
pages-job:
stage: deploy
script:
- 'curl --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" "https://gitlab.example.com/api/v4/projects"'
environment: production
스크립트에서 &&를 사용할 때 작업이 실패하지 않는 경우
단일 스크립트 줄에서 &&로 두 명령을 결합하면, 그중 하나의 명령이 실패했더라도 작업이 성공으로 반환될 수 있어요. 예를 들어 볼게요.
job-does-not-fail:
script:
- invalid-command xyz && invalid-command abc
- echo $?
- echo "The job should have failed already, but this is executed unexpectedly."
&& 연산자는 두 명령이 모두 실패했더라도 종료 코드 0을 반환하므로, 작업이 계속 실행돼요. 어느 하나라도 실패하면 스크립트가 종료되도록 강제하려면, 전체 줄을 괄호로 감싸세요.
job-fails:
script:
- (invalid-command xyz && invalid-command abc)
- echo "The job failed already, and this is not executed."
접힌 YAML 멀티라인 블록 스칼라로 인해 멀티라인 명령이 보존되지 않는 경우
- > 접힌(folded) YAML 멀티라인 블록 스칼라를 사용해 긴 명령을 나눌 때, 추가 들여쓰기 때문에 줄들이 개별 명령으로 처리될 수 있어요.
예를 들어 볼게요.
script:
- >
RESULT=$(curl --silent
--header
"Authorization: Bearer ***"
"${CI_API_V4_URL}/job"
)
이 경우 들여쓰기 때문에 줄바꿈이 보존되어 실패하게 돼요.
$ RESULT=$(curl --silent # collapsed multi-line command
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
/bin/bash: line 149: --header: command not found
/bin/bash: line 150: https://gitlab.example.com/api/v4/job: No such file or directory
다음 중 하나의 방법으로 해결할 수 있어요.
- 추가 들여쓰기를 제거하세요.
script: - > RESULT=$(curl --silent --header "Authorization: Bearer ***" "${CI_API_V4_URL}/job" ) - 스크립트를 수정해 추가 줄바꿈을 처리하세요. 예를 들어 셸 줄 이어쓰기(shell line continuation)를 사용할 수 있어요.
script: - > RESULT=$(curl --silent \ --header \ "Authorization: Bearer ***" \ "${CI_API_V4_URL}/job")
작업 로그 출력이 예상대로 포맷되지 않거나 예상치 못한 문자가 포함된 경우
TERM 환경 변수에 의존해 색상이나 포맷을 적용하는 도구를 쓸 때, 작업 로그의 포맷이 잘못 표시되는 경우가 있어요. 예를 들어 mypy 명령 같은 경우죠.
GitLab Runner는 컨테이너의 셸을 비대화형(non-interactive) 모드로 실행하기 때문에, 셸의 TERM 환경 변수가 dumb으로 설정돼요. 이 도구들의 포맷을 고치려면 다음을 할 수 있어요.
- 명령을 실행하기 전에 셸 환경에
TERM=ansi를 설정하는 스크립트 줄을 추가하세요. - 값이
ansi인TERMCI/CD 변수를 추가하세요.
더 알아보기
작업 스크립트를 설계할 때 명령의 종료 코드와 셸 동작을 제대로 이해하는 게 중요해요. 관련해서는 .gitlab-ci.yml의 script 키워드와 CI/CD 변수 문서를 함께 보면, 더 복잡한 스크립트도 안정적으로 작성할 수 있답니다.