继承了 before_script,却少了一行
한국어 원문으로 표시합니다.
목표
include·extends·!reference·YAML 앵커·default·spec:inputs 로 설정의 중복을 걷어내고, 각각의 병합 규칙이 잡에 실제로 무엇을 남기는지 실행 로그와 합쳐진 설정으로 확인합니다.
왜 중요한가
파이프라인 파일이 커지면 공통 부분을 떼어 재사용하게 되는데, 재사용 장치마다 합치는 규칙이 다릅니다. 해시는 합쳐지고 배열은 바뀌며, 앵커는 파일 안에서만, default 는 아무도 정하지 않았을 때만 쓰입니다. 이 규칙을 모르면 '물려받았다고 믿은 준비 명령이 한 잡에서만 빠지는' 사고가 오류 없이 납니다. 입력을 받는 템플릿은 같은 잡을 환경마다 복사하지 않게 해 주지만, 허용 범위를 정해 두지 않으면 오타 난 환경 이름도 그대로 잡이 됩니다.
단계
/root/glci-reuse을 git 저장소로 만드세요./root/glci-reuse/ci/templates.yml에 숨김 잡.base(before_script 는echo base-setup한 줄, 변수LOG_LEVEL: info)를 두고,.gitlab-ci.yml은include: - local: ci/templates.yml로 그 파일을 가져온 뒤 stages[build, test]와 잡build(stage build,extends: .base, scriptecho "LOG=$LOG_LEVEL")를 둡니다.gitlab-ci-local --shell-isolation --no-artifacts-to-source로 실행해 build 로그에base-setup과LOG=info가 찍히는지 보세요.- 잡 둘을 더하세요.
test(stage test)는.base를 extends 하면서 변수를LOG_LEVEL: debug,PYTEST: "1"로 적고 scriptecho "LOG=$LOG_LEVEL PYTEST=$PYTEST"를 둡니다.lint(stage test)는.base를 extends 하면서 자기 before_script(echo lint-setup)와 scriptecho lint를 둡니다. 실행해 test 로그에base-setup과LOG=debug PYTEST=1이, lint 로그에는lint-setup만 있고base-setup은 없는지 확인하세요. - 잡
package(stage build)를 더하세요. extends 를 쓰지 않고 before_script 를!reference [.base, before_script]와echo package-setup두 항목으로 적어, 실행하면base-setup다음에package-setup이 찍혀야 합니다. script 는echo package입니다. /root/glci-reuse/broken-anchor.yml에 ci/templates.yml 을 include 하고, 이 파일에 정의되지 않은 앵커*base_vars를 variables 에<<: *base_vars로 쓰는 잡 build 를 두세요.gitlab-ci-local --file broken-anchor.yml --list의 출력을/root/glci-reuse/anchor-error.txt에 저장합니다. 그리고.gitlab-ci.yml에는 같은 파일 안에서 앵커&docs_vars(DOCS_OUT: public)를 정의해 잡docs(stage test)의 variables 에<<: *docs_vars와DOCS_FMT: html을 두고 scriptecho "$DOCS_OUT/$DOCS_FMT"로public/html이 찍히게 하세요..gitlab-ci.yml최상위에default:로 before_scriptecho default-setup을 두세요. 그리고 잡report(stage test, scriptecho report)는inherit: default: false로 기본값을 물려받지 않게 합니다. 실행해 docs 로그에는default-setup이, report 로그에는 아무 준비 줄도 없고, build·test 로그에는 여전히base-setup이 찍히는지 확인하세요./root/glci-reuse/ci/deploy.yml을spec:inputs헤더가 있는 템플릿으로 만드세요. 입력env는staging·production중 하나만 허용하고,replicas는 숫자이며 기본 1 입니다. 헤더 뒤(---)에는 잡deploy-$[[ inputs.env ]](stage deploy)가echo "deploy <env> replicas=<replicas>"를 실행합니다..gitlab-ci.yml은 stages 에 deploy 를 더하고 이 파일을 두 번 include 합니다 — staging(기본 replicas), production(replicas 3).gitlab-ci-local --preview의 출력을/root/glci-reuse/expanded.yml에 저장하세요. 이 파일에는 include·extends·!reference·앵커·default·inputs 가 모두 풀린 결과가 있어야 합니다. 채점기는 저장소 사본에서 같은 명령을 돌려 내용이 같은지와 몇 가지 값을 확인합니다.
참고
- 이 VM 에는 GitLab 서버와 러너가 없고, gitlab-ci-local 4.75.1 이 .gitlab-ci.yml 을 GitLab 과 같은 규칙으로 해석해 shell 로 잡을 실행합니다.
image:를 적으면 도커로 돌리려 하므로 쓰지 않습니다. 보호 변수·마스킹·CI_JOB_TOKEN·러너 태그·병합 요청 파이프라인 생성은 서버 기능이라 여기서 재현되지 않습니다. - 실행: 저장소 루트에서
gitlab-ci-local --shell-isolation --no-artifacts-to-source(잡마다 따로 된 작업 디렉터리, 산출물을 저장소에 되쓰지 않음), 잡 목록:gitlab-ci-local --list-csv-all, 해석된 설정:gitlab-ci-local --preview. gitlab-ci-local 은 git 이 추적하는 파일만 잡에 넘기므로 파일을 만들면git add하세요. 채점기는 저장소를 사본으로 떠 모든 파일을 커밋한 뒤 같은 도구로 다시 돌립니다. - 잡 로그 보기: 실행 출력에서
잡이름 > ...줄, 또는.gitlab-ci-local/output/<잡이름>.log. - 흔한 실수: 조각에서 before_script 를 받는다고 믿고 잡에 before_script 를 또 적어 조각의 명령이 사라지는 것.
- CI/CD YAML syntax reference · include · Optimize GitLab CI/CD configuration files(앵커·extends·!reference) · gitlab-ci-local
템플릿 파일을 include 하고 extends 로 물려받는다
/root/glci-reuse 을 git 저장소로 만드세요. /root/glci-reuse/ci/templates.yml 에 숨김 잡 .base(before_script 는 echo base-setup 한 줄, 변수 LOG_LEVEL: info)를 두고, .gitlab-ci.yml 은 include: - local: ci/templates.yml 로 그 파일을 가져온 뒤 stages [build, test] 와 잡 build(stage build, extends: .base, script echo "LOG=$LOG_LEVEL")를 둡니다. gitlab-ci-local --shell-isolation --no-artifacts-to-source 로 실행해 build 로그에 base-setup 과 LOG=info 가 찍히는지 보세요.
include 는 여러 파일을 하나의 설정으로 합친 뒤 해석합니다. 이름이 점으로 시작하는 잡은 목록에 오르지 않고 물려주는 조각으로만 쓰입니다. gitlab-ci-local 은 git 이 추적하는 파일만 보므로 새 파일은 git add 합니다.
해시는 합쳐지고 배열은 통째로 바뀐다
잡 둘을 더하세요. test(stage test)는 .base 를 extends 하면서 변수를 LOG_LEVEL: debug, PYTEST: "1" 로 적고 script echo "LOG=$LOG_LEVEL PYTEST=$PYTEST" 를 둡니다. lint(stage test)는 .base 를 extends 하면서 자기 before_script(echo lint-setup)와 script echo lint 를 둡니다. 실행해 test 로그에 base-setup 과 LOG=debug PYTEST=1 이, lint 로그에는 lint-setup 만 있고 base-setup 은 없는지 확인하세요.
extends 는 깊은 병합입니다. variables 같은 해시는 키 단위로 합쳐져 물려받은 키 위에 덮어쓰지만, before_script 같은 배열은 합쳐지지 않고 잡이 적은 것으로 통째로 바뀝니다.
배열을 합치고 싶을 때는 !reference
잡 package(stage build)를 더하세요. extends 를 쓰지 않고 before_script 를 !reference [.base, before_script] 와 echo package-setup 두 항목으로 적어, 실행하면 base-setup 다음에 package-setup 이 찍혀야 합니다. script 는 echo package 입니다.
!reference 는 다른 잡(숨김 잡 포함)의 특정 키 값을 그 자리에 끼워 넣는 태그입니다. include 한 파일의 조각도 가리킬 수 있어서, 배열이 통째로 바뀌는 extends 의 한계를 메웁니다.
앵커는 파일 경계를 넘지 못한다
/root/glci-reuse/broken-anchor.yml 에 ci/templates.yml 을 include 하고, 이 파일에 정의되지 않은 앵커 *base_vars 를 variables 에 <<: *base_vars 로 쓰는 잡 build 를 두세요. gitlab-ci-local --file broken-anchor.yml --list 의 출력을 /root/glci-reuse/anchor-error.txt 에 저장합니다. 그리고 .gitlab-ci.yml 에는 같은 파일 안에서 앵커 &docs_vars(DOCS_OUT: public)를 정의해 잡 docs(stage test)의 variables 에 <<: *docs_vars 와 DOCS_FMT: html 을 두고 script echo "$DOCS_OUT/$DOCS_FMT" 로 public/html 이 찍히게 하세요.
앵커와 별칭은 YAML 파서가 파일 하나를 읽을 때 처리합니다. include 는 그 뒤에 GitLab 이 합치는 단계라, 다른 파일의 앵커는 이미 사라진 뒤입니다. 파일을 넘는 재사용은 extends 나 !reference 로 합니다.
default 는 바닥값 — extends 와 inherit 에서 밀린다
.gitlab-ci.yml 최상위에 default: 로 before_script echo default-setup 을 두세요. 그리고 잡 report(stage test, script echo report)는 inherit: default: false 로 기본값을 물려받지 않게 합니다. 실행해 docs 로그에는 default-setup 이, report 로그에는 아무 준비 줄도 없고, build·test 로그에는 여전히 base-setup 이 찍히는지 확인하세요.
default 는 아무것도 정하지 않은 잡에 채워지는 전역 바닥값이라, extends 로 before_script 를 이미 받은 잡에서는 쓰이지 않습니다. inherit 는 기본값을 받을지 잡마다 끄는 스위치입니다.
입력을 받는 템플릿으로 환경별 잡을 찍어 낸다
/root/glci-reuse/ci/deploy.yml 을 spec:inputs 헤더가 있는 템플릿으로 만드세요. 입력 env 는 staging·production 중 하나만 허용하고, replicas 는 숫자이며 기본 1 입니다. 헤더 뒤(---)에는 잡 deploy-$[[ inputs.env ]](stage deploy)가 echo "deploy <env> replicas=<replicas>" 를 실행합니다. .gitlab-ci.yml 은 stages 에 deploy 를 더하고 이 파일을 두 번 include 합니다 — staging(기본 replicas), production(replicas 3).
spec 헤더는 include 할 때 넘길 수 있는 값의 형태와 허용 범위를 정합니다. 템플릿 안에서는 $[[ inputs.이름 ]] 으로 값을 씁니다. 허용 목록에 없는 값을 넘기면 파이프라인이 만들어지기 전에 거부됩니다.
GitLab 이 보게 될 합쳐진 설정을 뽑아 둔다
gitlab-ci-local --preview 의 출력을 /root/glci-reuse/expanded.yml 에 저장하세요. 이 파일에는 include·extends·!reference·앵커·default·inputs 가 모두 풀린 결과가 있어야 합니다. 채점기는 저장소 사본에서 같은 명령을 돌려 내용이 같은지와 몇 가지 값을 확인합니다.
설정이 여러 파일로 흩어질수록 '이 잡이 실제로 무엇을 실행하나' 를 파일만 보고 답하기 어렵습니다. 합쳐진 결과를 리뷰에 붙이면 병합 규칙을 머릿속으로 계산하지 않아도 됩니다. GitLab 화면의 파이프라인 편집기에도 같은 기능(전체 설정 보기)이 있습니다.