☁️ 2단계 : CI 파이프라인 구축 설계 - 100-hours-a-week/7-team-ddb-wiki GitHub Wiki
1. 개요 (Overview)
현재 서비스가 빠르게 확장됨에 따라 여러 개발자가 동시에 기능을 개발하고 커밋하는 상황이 늘어나고 있다.
기존에는 수동으로 빌드와 테스트를 수행한 뒤 배포 전 오류를 확인했으나, 시간이 지체되고 사람이 직접 확인하다 보니 통합 오류를 놓치기 쉬운 문제가 있었다.
본 단계에서는 Jenkins를 기반으로 한 CI(지속적 통합) 파이프라인을 설계하여, 코드 커밋 시 자동으로 빌드와 테스트를 수행하고, 테스트 결과를 Discord로 알림으로 공유함으로써 개발 생산성과 품질을 높이는 데 초점을 맞추고자 한다.
2. 도입 배경 및 필요성
항목 | 설명 |
---|---|
수동 빌드·테스트 부담 | 기존 수작업 빌드로 개발자의 시간이 낭비되고, 오류 발견 시점이 늦어지는 문제가 있다. |
협업 시 통합 오류 증가 | 여러 개발자가 동시에 작업할 경우 버전 충돌이나 빌드 실패 등의 문제를 빠르게 파악하기 어렵다. |
지속적 검증 요구 | 서비스가 점차 복잡해지고, 짧은 주기로 기능 업데이트해야 하는 상황에서 자동화된 빌드 및 테스트는 필수적이다. |
조기 피드백 | 커밋 이후 즉시 테스트가 실행되고 결과가 공유되면, QA 및 수정 사이클을 크게 단축할 수 있어 서비스 품질 향상으로 이어진다. |
3. 목표 & 적용 범위
- 목표
- Pull Request/Commit 발생 시 자동 빌드 → 테스트 → 결과 보고 흐름을 자동화
- 빌드 실패 및 테스트 실패를 팀 전원이 빠르게 인지하도록 알림 시스템(Discord) 연동
- 빌드·테스트 시간을 30% 이상 단축하여, 릴리즈 사이클을 가속화
- 적용 범위
- 개발/운영 브랜치에 대한 CI 파이프라인 적용
- Jenkins 서버 운영 & 관리 (플러그인, WebHook 등)
- Discord를 통한 빌드·테스트 결과 공유
4. 설계 상세
4.1 CI 파이프라인
Jenkins
-
온프레미스 설치 가능성과 자유로운 제어
Jenkins는 온프레미스 도구이므로 GCP VM 인스턴스 등에 직접 설치해 사용할 수 있다. 반면 GitHub Actions나 GitLab CI는 SaaS 기반이라 외부 네트워크 접근 및 보안 정책 제어에 한계가 있다. 따라서 Jenkins는 기업 환경이나 보안 요구가 높은 프로젝트에서 네트워크, 접근 권한, 실행 환경을 모두 직접 통제할 수 있다는 점에서 유리하다.
-
플러그인 생태계의 폭넓은 확장성
Jenkins는 수천 개 이상의 플러그인을 통해 Lint, 테스트 커버리지(Jacoco, Cobertura), 정적 분석(SonarQube), 빌드 도구(Gradle, npm, Maven) 등을 완전히 통합할 수 있다. 반면 GitHub Actions나 GitLab CI는 자체 Action/Runner의 제약이 있으며 외부 도구 연동 시 설정이 복잡하거나 비용이 추가된다.
-
로컬 테스트 및 디버깅 편의성
Jenkins는 자체 VM에서 로컬 환경을 미러링해 동일한 CI 환경에서 테스트 및 디버깅을 수행할 수 있다. 반면 GitHub Actions, GitLab CI는 클라우드 상에서만 실행되므로, 동일 환경 디버깅을 위해서는 별도 CI Runner 구성이나 로컬 액션 테스트 도구를 추가로 사용해야 한다.
-
향후 CD까지 확장 용이
Jenkins는 CI뿐 아니라 CD로 확장하기 위한 구성도 잘 갖춰져 있어, 배포 단계 조건 제어, 승인 흐름, Blue‑Green 전략 등을 유연하게 구성할 수 있다. SaaS 기반 CI 도구는 GitOps 또는 클라우드 배포 서비스에 의존해야 해 커스터마이징 자유도가 제한된다.
Discord
-
실시간 CI/CD 알림 허브
Jenkins Webhook과 연동해 빌드·테스트 성공/실패 결과가 채팅방에 즉시 게시된다. 개발자는 IDE를 벗어나지 않고도 파이프라인 상태를 파악할 수 있어 장애 대응 속도가 크게 향상된다.
-
프로젝트·채널별 Webhook 분리 관리
Discord는 Webhook URL을 무제한으로 생성할 수 있어, 서비스·환경(Dev/Prod)·팀별로 알림 채널을 세분화할 수 있다. 잡마다 알림 대상을 정확히 지정해 “필요한 사람”에게만 노이즈 없이 정보를 전달한다.
-
알림 기반 협업 가속
PR 머지·배포 승인·테스트 실패 등 주요 이벤트가 자동으로 공유되므로, 팀원이 같은 맥락을 실시간으로 공유하고 빠르게 의사결정을 내릴 수 있다. 결과적으로 개발 주기가 단축되고 코드 품질 확보가 용이해진다.
-
저비용·범용성
Discord는 기본 기능이 무료이며, 데스크톱·모바일·웹 클라이언트를 지원해 접속 환경 제약이 없다. 별도의 SaaS 연동 비용이나 라이선스 없이 손쉽게 CI 알림 허브를 구축할 수 있다는 점에서 스타트업·소규모 팀에 특히 적합하다.
4.2 CI 파이프라인 상세
파이프라인 절차 상세
단계 | 작업 내용 | 주요 도구 | 담당자/역할 | 산출물 |
---|---|---|---|---|
1 | 코드 커밋 & PR 생성 개발자가 GitHub에 변경 사항 푸시 | Git, GitHub | 개발자 | 소스 코드 (PR) |
2 | 빌드 트리거 & 코드 체크아웃 Jenkins가 Commit/PR 이벤트 감지 최신 소스를 체크아웃 | Jenkins, Git Plugin | Jenkins | 빌드 준비 (소스 코드) |
3 | 빌드 & 컴파일 의존성 다운로드, Gradle/Maven 또는 npm 등으로 빌드 수행 | Jenkins | Jenkins | 빌드 산출물 (jar/war 등) |
4 | 테스트 실행 Unit 테스트, 통합 테스트 실행 결과 리포트 생성 | Jenkins, Test Runner | Jenkins | 테스트 결과 리포트 |
5 | 알림 전송 빌드/테스트 결과(성공/실패)를 Discord로 전송 | Discord WebHook | Jenkins | 메시지 알림 |
4.3 설정 · 스크립트 명세
BE
/*------------------------------------------------------------------
Jenkins Declarative Pipeline – Backend
· Gradle로 JAR 빌드 → 테스트 → Discord 알림
------------------------------------------------------------------*/
pipeline {
/*--------------- 어떤 노드에서도 실행 ---------------*/
agent any
/*--------------- JDK 21(TEMURIN) 사용 ---------------*/
tools {
jdk 'temurin-21'
}
/*--------------- 단계 정의 ---------------*/
stages {
/* 1. Git 소스 체크아웃 */
stage('Checkout') {
steps {
/* 파라미터로 넘어온 브랜치를 그대로 사용 */
git branch: env.BRANCH_NAME,
url: 'https://github.com/100-hours-a-week/7-team-ddb-be.git'
}
}
/* 2. Gradle 빌드 (테스트 제외) */
stage('Build') {
steps {
script {
sh 'chmod +x gradlew' // gradlew 실행권한 부여
sh './gradlew clean build -x test' // JAR 빌드
}
}
}
/* 3. Gradle 단위 테스트 */
stage('Test') {
steps {
script {
sh './gradlew test' // JUnit 등 테스트 실행
}
}
}
}
/*--------------- 빌드 결과 Discord 전송 ---------------*/
post {
/* 파이프라인 성공 시 */
success {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 성공",
webhookURL: "$DISCORD"
}
}
/* 파이프라인 실패 시 */
failure {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 실패",
webhookURL: "$DISCORD"
}
}
}
}
FE
/*------------------------------------------------------------------
Jenkins Declarative Pipeline – Frontend
· npm CI → 빌드 → 테스트 → Discord 알림
------------------------------------------------------------------*/
pipeline {
agent any // 모든 가용 노드에서 실행
/* Node 21 버전 사용 (Global Tool Config) */
tools {
nodejs 'node-21'
}
stages {
/* 1. Git 체크아웃 */
stage('Checkout') {
steps {
git branch: env.BRANCH_NAME,
url: 'https://github.com/100-hours-a-week/7-team-ddb-fe.git'
}
}
/* 2. 의존성 설치 (package‑lock.json 기반) */
stage('Install Deps') {
steps { sh 'npm ci' }
}
/* 3. 정적 빌드 (Next.js 등) */
stage('Build') {
steps { sh 'npm run build' }
}
/* 4. 테스트 (스크립트가 있을 때만 실행) */
stage('Test') {
steps { sh 'npm test --if-present' }
}
}
/* 빌드 결과 Discord 전송 */
post {
success {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 성공",
webhookURL: "$DISCORD"
}
}
failure {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 실패",
webhookURL: "$DISCORD"
}
}
}
}
AI
/*------------------------------------------------------------------
Jenkins Declarative Pipeline – AI
· Python venv → 의존성 설치 → pytest → Discord 알림
------------------------------------------------------------------*/
pipeline {
agent any // 어디서나 실행
/* Python 3.11 버전 사용 */
tools {
python 'python3.11'
}
stages {
/* 1. Git 체크아웃 */
stage('Checkout') {
steps {
git branch: env.BRANCH_NAME,
url: 'https://github.com/100-hours-a-week/7-team-ddb-ai.git'
}
}
/* 2. 가상환경 생성 및 패키지 설치 */
stage('Setup venv') {
steps {
sh '''
python -m venv venv # 가상환경 생성
. venv/bin/activate # venv 활성화
pip install --upgrade pip # pip 최신화
pip install -r requirements.txt # 의존성 설치
'''
}
}
/* 3. pytest 실행 */
stage('Test') {
steps {
sh '''
. venv/bin/activate
pip install pytest
pytest # 단위 테스트
'''
}
}
}
/* Discord 알림 (성공/실패) */
post {
success {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 성공",
webhookURL: "$DISCORD"
}
}
failure {
withCredentials([string(credentialsId: 'Discord-Webhook',
variable: 'DISCORD')]) {
discordSend description: """
제목 : ${currentBuild.displayName}
결과 : ${currentBuild.result}
실행 시간 : ${currentBuild.duration / 1000}s
""",
link: env.BUILD_URL,
result: currentBuild.currentResult,
title: "${env.JOB_NAME} : ${currentBuild.displayName} 실패",
webhookURL: "$DISCORD"
}
}
}
}
4.4 WebHook 설정
- Jenkins 설치 & 기본 플러그인
- Git Plugin, Pipeline Plugin, Discord Notification Plugin 등
- Credential & 환경 변수 설정
- Git 접근 토큰, Discord WebHook URL
- 빌드 도구(예: Gradle, npm) PATH 등
- GitHub → Jenkins
- Repository Settings에서 WebHook 등록, 커밋/PR 발생 시 Jenkins 파이프라인 트리거
- Jenkins → Discord
- Jenkinsfile 내에서
discordSend
함수를 통해 결과 전송
- Jenkinsfile 내에서
5. 한계 및 리스크
항목 | 설명 |
---|---|
Jenkins 서버 의존도 | Jenkins 자체 장애가 발생할 경우 빌드와 테스트를 수행할 수 없으므로 HA 구성 또는 백업용 컨트롤러 도입 검토가 필요하다. |
테스트 커버리지 부족 | CI 자동화가 구축되어 있어도 테스트 코드가 미비하면 통합 오류나 버그를 놓칠 위험이 여전히 존재한다. |
플러그인 호환성 | Jenkins에 다양한 플러그인을 설치할 경우, 버전 간 충돌이나 설정 오류가 발생할 수 있다. |
6. 기대 효과 & 적용 후 평가
항목 | 설명 |
---|---|
지속적 통합 & 빠른 피드백 | 커밋 직후 빌드·테스트가 실행되어 오류를 조기에 발견, 수정할 수 있다. |
팀 협업 강화 | Discord 알림으로 팀 전원이 빌드 및 테스트 결과를 실시간으로 공유하고 문제 발생 시 신속 대응한다. |
배포 안정성 향상 | 빌드 단계에서 미리 결함을 제거하고, 1단계의 수작업 배포 전에 품질 검증이 가능하다. |
실제 운영 후 모니터링
- 빌드 성공률, 빌드 소요 시간, 테스트 성공률 등을 정기적으로 확인한다.
- 오류 로그 축적 후, 반복되는 문제나 취약한 부분(테스트 범위 부족 등)을 개선한다.
7. 결론 및 향후 계획
결론
- Jenkins 기반 CI 파이프라인 도입으로 개발 자동화를 실현하고, Discord 알림으로 팀 협업 효율을 높인다.
- 이는 코드 품질과 배포 안정성 향상에 직접 기여할 것으로 기대된다.
향후 계획
- 테스트 스펙 보강: 단위 테스트 외에 통합 테스트, 성능 테스트 추가 등 커버리지를 확대한다.
- CD(지속적 배포) 도입 연계: 3단계에서 배포/운영 환경에 자동으로 배포하는 CD 파이프라인을 구축한다.
- Jenkins 서버 고가용성(HA) 구성 또는 다른 CI 도구와 연동 가능성 검토한다.