GitLab CI/CD · 실행 모델 — 순서·조건·전달 · 실습
nightly 태그를 붙였더니 릴리스가 나갔다
목표
브랜치·태그·파일 존재·원격과의 변경에 따라 잡이 목록에 들어가고 빠지는 것을 상황을 바꿔 가며 확인하고, 규칙의 순서와 규칙이 정하는 변수로 배포 정책을 설정에 새깁니다.
왜 중요한가
rules 는 잡이 시작할 때 묻는 조건이 아니라 파이프라인이 만들어질 때 목록을 정하는 규칙입니다. 첫 매치만 적용되므로 항목의 순서가 곧 정책이고, 순서를 잘못 두면 오류 없이 배포가 사라지거나 엉뚱한 태그에 릴리스가 나갑니다. changes 는 무엇과 비교하느냐에 따라 결과가 바뀌고, 조건과 값(배포 대상)을 떨어뜨려 두면 둘이 어긋나는 날이 옵니다. 이런 차이는 설정을 읽는 것만으로는 잘 보이지 않아서 상황을 바꿔 실행해 봐야 합니다.
단계
1. /root/glci-rules 을 git 저장소로 만들고 .gitignore 에 .gitlab-ci-local/ 를 두세요. .gitlab-ci.yml 에 stages [build, deploy], 조건 없는 잡 unit(build, echo "unit log=$LOG_LEVEL"), 그리고 $CI_COMMIT_BRANCH == "main" 일 때만 만들어지는 deploy-staging(deploy, echo staging)을 두고 main 브랜치에 커밋하세요. 채점기는 사본에서 feature/login 브랜치로 옮겨 deploy-staging 이 목록에서 사라지는지 봅니다.
2. 잡 release-notes(deploy, echo notes)를 $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/ 일 때만 만들어지게 더하고 커밋하세요. gitlab-ci-local 은 git 태그를 읽지 않으므로 --variable CI_COMMIT_TAG=v1.2.0 으로 태그 파이프라인을 흉내 냅니다. v1.2.0 이면 목록에 있고, nightly 나 태그 없음이면 없어야 합니다.
3. 잡 publish(deploy, echo publish)의 rules 를 세 항목으로 두세요: 태그가 있으면 when: on_success, main 브랜치면 when: manual 과 allow_failure: false, 그 밖에는 when: never. 커밋합니다. 목록에서 main 이면 manual(allowFailure false), 태그 변수가 있으면 on_success, feature 브랜치면 없어야 합니다.
4. 잡 docker-build(build, echo docker)를 rules: - exists: [Dockerfile] 로 더하고 커밋하세요. 이 저장소에는 아직 Dockerfile 을 만들지 않습니다. 채점기는 사본에 Dockerfile 을 넣었을 때만 잡이 생기는지 봅니다.
5. /root/glci-rules-origin.git 에 bare 저장소를 만들어 origin 으로 등록하고 main 을 push 한 뒤 git remote set-head origin main 을 실행하세요. 그다음 잡 docs-build(build, echo docs)를 rules: - changes: ["docs/**/*"] 로 더해 커밋하고 다시 push 합니다. 채점기는 사본에서 docs 아래를 고친 브랜치와 다른 파일만 고친 브랜치를 만들어, 앞의 경우에만 docs-build 가 생기는지 봅니다.
6. 잡 deploy(deploy, echo "target=$DEPLOY_TARGET")를 더하세요. rules 는 태그면 variables: {DEPLOY_TARGET: production}, main 이면 variables: {DEPLOY_TARGET: staging} 입니다. 커밋하고 push 합니다. main 에서 실행하면 target=staging, 태그 변수를 주면 target=production 이 찍혀야 합니다.
7. .gitlab-ci.yml 맨 위에 workflow: rules: 를 두세요. main 이면 variables: {LOG_LEVEL: warn}, 그 밖에는(when: always) variables: {LOG_LEVEL: debug} 입니다. 커밋하고 push 합니다. main 에서 unit 로그는 unit log=warn, feature 브랜치에서는 unit log=debug 여야 합니다.
참고
- 이 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 의 차이(실측): git 태그를 CI_COMMIT_TAG 로 읽지 않아
--variable CI_COMMIT_TAG=...로 흉내 냅니다. rules:changes 는 origin 의 기본 브랜치와 비교하고 compare_to 는 무시합니다. workflow:rules 로 파이프라인을 만들지 않는 동작과 manual 잡이 뒤 스테이지를 막는 동작은 재현하지 않습니다. - 브랜치를 바꿔 볼 때는 사본이나 새 브랜치에서 하고, 채점 전에는 main 으로 돌아와 커밋해 두세요.
- [Specify when jobs run with rules](https://docs.gitlab.com/ci/jobs/job_rules/) · [workflow](https://docs.gitlab.com/ci/yaml/workflow/) · [Predefined CI/CD variables](https://docs.gitlab.com/ci/variables/predefined_variables/) · [CI/CD YAML syntax reference](https://docs.gitlab.com/ci/yaml/)
단계 7개
- main 에서만 스테이징 배포를 만든다
- 태그 이름의 모양까지 보고 릴리스 노트를 만든다
- 첫 매치만 적용된다 — 순서가 곧 정책이다
- Dockerfile 이 있는 저장소에서만 이미지를 굽는다
- 문서가 바뀐 브랜치에서만 문서를 빌드한다
- 어느 규칙에 걸렸는지가 배포 대상을 정한다
- 파이프라인 전체의 값은 workflow 에서 정한다