CI/CD 파이프라인
24.1. CircleCI 설정
24.1.1. .circleci/config.yml 전체 예시
yaml
version: 2.1
orbs:
node: circleci/node@6.3
maven: circleci/maven@1.4
executors:
java-executor:
docker:
- image: cimg/openjdk:21.0
working_directory: ~/project/backend
node-executor:
docker:
- image: cimg/node:22.0
working_directory: ~/project/frontend
jobs:
# ===== 백엔드 =====
backend-lint:
executor: java-executor
steps:
- checkout:
path: ~/project
- restore_cache:
keys:
- maven-{{ checksum "pom.xml" }}
- run:
name: 포맷 검증
command: mvn spotless:check
- save_cache:
key: maven-{{ checksum "pom.xml" }}
paths:
- ~/.m2
backend-test:
executor: java-executor
steps:
- checkout:
path: ~/project
- restore_cache:
keys:
- maven-{{ checksum "pom.xml" }}
- run:
name: 테스트 실행
command: mvn test
- run:
name: 커버리지 리포트
command: mvn jacoco:report
- store_test_results:
path: target/surefire-reports
- store_artifacts:
path: target/site/jacoco
backend-build:
executor: java-executor
steps:
- checkout:
path: ~/project
- restore_cache:
keys:
- maven-{{ checksum "pom.xml" }}
- run:
name: 빌드
command: mvn package -DskipTests
- persist_to_workspace:
root: ~/project
paths:
- backend/target/*.jar
backend-security-scan:
executor: java-executor
steps:
- checkout:
path: ~/project
- restore_cache:
keys:
- maven-{{ checksum "pom.xml" }}
- run:
name: OWASP 의존성 스캔
command: mvn dependency-check:check
- store_artifacts:
path: target/dependency-check-report.html
# ===== 프론트엔드 =====
frontend-lint:
executor: node-executor
steps:
- checkout:
path: ~/project
- run:
name: 의존성 설치
command: yarn install --frozen-lockfile
- run:
name: ESLint 검증
command: yarn lint
- run:
name: Prettier 검증
command: yarn format:check
frontend-build:
executor: node-executor
steps:
- checkout:
path: ~/project
- run:
name: 의존성 설치
command: yarn install --frozen-lockfile
- run:
name: 타입 체크
command: yarn type-check
- run:
name: 빌드
command: yarn build
- persist_to_workspace:
root: ~/project
paths:
- frontend/dist
# ===== 배포 =====
deploy:
docker:
- image: cimg/base:current
steps:
- attach_workspace:
at: ~/project
- run:
name: 배포
command: echo "배포 스크립트 실행"
workflows:
build-and-deploy:
jobs:
# 린트 (병렬)
- backend-lint
- frontend-lint
# 테스트 (린트 통과 후)
- backend-test:
requires:
- backend-lint
# 빌드 (린트 통과 후, 병렬)
- backend-build:
requires:
- backend-test
- frontend-build:
requires:
- frontend-lint
# 보안 스캔 (주 1회 또는 수동)
- backend-security-scan:
requires:
- backend-lint
filters:
branches:
only: main
# 배포 (main 브랜치만)
- deploy:
requires:
- backend-build
- frontend-build
filters:
branches:
only: main24.2. 파이프라인 단계
24.2.1. 실행 흐름
┌─────────────────────────────────────────────────┐
│ Push / PR │
└──────────────────────┬──────────────────────────┘
│
┌───────────┴───────────┐
▼ ▼
backend-lint frontend-lint
│ │
▼ │
backend-test │
│ │
▼ ▼
backend-build frontend-build
│ │
└───────────┬───────────┘
│
▼
deploy
(main only)24.2.2. 단계별 역할
| 단계 | 역할 | 실패 시 |
|---|---|---|
| 린트 | 코드 포맷, ESLint 규칙 검증 | PR 머지 차단 |
| 테스트 | 단위/통합 테스트 실행, 커버리지 측정 | PR 머지 차단 |
| 빌드 | 컴파일, 번들링 | PR 머지 차단 |
| 보안 스캔 | 의존성 취약점 검사 | 경고 리포트 생성 |
| 배포 | 빌드 산출물 배포 | 롤백 절차 수행 |
24.3. 환경별 배포 전략
24.3.1. 배포 조건
| 환경 | 트리거 | 자동/수동 |
|---|---|---|
| dev | main 머지 시 | 자동 |
| staging | main 머지 + 수동 승인 | 수동 |
| production | 릴리스 태그 (v*) 생성 시 | 수동 승인 후 자동 |
24.3.2. 롤백 절차
프로덕션 배포 후 문제 발생 시 다음 절차를 따릅니다.
- 문제 확인 및 영향 범위 파악
- 이전 버전 태그로 재배포
- 핫픽스 브랜치 생성 및 수정
- 긴급 PR 리뷰 → 머지 → 재배포
24.3.3. 필수 스크립트
프론트엔드 package.json에 다음 스크립트를 포함합니다.
json
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"type-check": "vue-tsc --noEmit"
}
}