1. 내가 직접 하던 일(CI 없을 때)
1. 코드 작성
2. git push
3. 로컬에서 npm run lint
4. 로컬에서 npm run build
5. 문제 없다고 판단되면 merge
6. 서버 접속해서 직접 배포
2. CI를 쓰면 뭐가 달라질까?
- CI는 이 코드가 merge 되어도 괜찮은지 자동으로 검사하는 역할
- lint / test / build를 자동으로 실행
- 하나라도 실패하면 merge 불가
- 사람이 빼먹을 수 없음
- merge 가능 여부만!!!! 판단
3. push만 했는데 자동으로 실행되는 이유
- .gitlab-ci.yml 파일에 실행 규칙이 정의돼 있기 때문
lint:
script:
- npm run lint
rules:
- if: $CI_COMMIT_BRANCH
- 코드의 뜻
- 브랜치에 push가 발생하면 npm run lint를 자동으로 실행해라
CD는?
- CI를 통과한 코드를 실제 서버에 배포하는 단계
- 수동 배포여도 CD임
CI: 합쳐도 되는지 검사
CD: 서버에 올려주는 과정
배포 명령을 사람이 직접 서버에서 치느냐, CI/CD 파이프라인이 대신 치느냐
- CI에서 버튼 눌러 배포 -> CD
- CI 통과 후 자동 배포 -> CD
- 사람은 시작만 하고, 실제 배포 작업은 파이프라인이 하면 CD!!!
- 배포 명령을 CI/CD 파이프라인이 실행하느냐가 중요
전체 흐름
1. git push
2. CI 자동 실행
- lint
- test
- build
3. CI 결과로 merge 가능 여부 결정
4. 사람이 merge 버튼 클릭
5. (선택)
- CD 자동 배포
- 또는 배포 버튼 클릭 (manual)
.gitlab-ci.yml 예시
# 1️⃣ 파이프라인 단계 정의 (실행 순서)
stages:
- lint
- test
- build
- deploy
# 2️⃣ 기본 실행 환경
default:
image: node:20-alpine
before_script:
- node -v
- npm -v
- npm ci
# 3️⃣ CI - 코드 검사 (lint)
lint:
stage: lint
script:
- npm run lint
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH
# 4️⃣ CI - 테스트
test:
stage: test
script:
- npm run test --if-present
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH
# 5️⃣ CI - 빌드 검증
build:
stage: build
script:
- npm run build
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH
# 6️⃣ CD - 배포 (main 브랜치만)
deploy:
stage: deploy
script:
- echo "🚀 deploy to server"
# 예: ssh 서버접속, pm2 reload 등
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual