Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 11 additions & 87 deletions .github/workflows/ci-docker.yml
Original file line number Diff line number Diff line change
@@ -1,100 +1,24 @@
# 워크플로우의 이름
name: IssueDive Docker CI
name: IssueDive Docker CI New

# 워크플로우가 언제 실행될지 정의
on:
push:
branches: [ "dev" ] # dev 브랜치에 push될 때 실행
pull_request_target: # Fork에서 보낸 PR도 공용 저장소의 Secrets에 접근할 수 있게 pull_request_target으로 변경함
branches: [ "dev" ] # dev 브랜치로 Pull Request가 생성될 때 실행
branches: [ "dev" ]
pull_request:
branches: [ "dev" ]

# 실행될 작업(Job)들을 정의
jobs:
build-and-test: # 작업의 ID
name: Build and Test # 작업의 이름 (GitHub Actions UI에 표시됨)
runs-on: ubuntu-latest # 작업을 실행할 가상 머신 환경 (Ubuntu 최신 버전)

# 0. DB 서비스를 여기에 정의합니다.
# 이 작업(Job)이 실행되는 동안 MySQL 컨테이너를 함께 실행합니다.
services:
mysql:
image: mysql:8
# GitHub Secrets를 사용하여 DB를 설정합니다.
env:
MYSQL_ROOT_PASSWORD: ${{ secrets.DB_PASSWORD }}
MYSQL_DATABASE: issue_dive
ports:
- 3306:3306 # Runner의 3306 포트와 컨테이너의 3306 포트를 연결
options: >-
--health-cmd "mysqladmin ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5

# 작업의 단계(Step)들을 정의
build-and-test:
name: Build and Test
runs-on: ubuntu-latest
steps:
# 1. 소스 코드 체크아웃
# GitHub Actions Runner가 우리 저장소의 코드에 접근할 수 있도록 내려받는 단계
- name: Checkout source code
uses: actions/checkout@v4

# 2. Docker Buildx 설정
# Docker 빌드 성능을 향상시키고 다양한 빌드 기능을 활성화하는 단계
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# 'pull_request_target'을 사용할 때는 어떤 코드를 체크아웃할지 명시해야 합니다.
with:
ref: ${{ github.event.pull_request.head.sha }}

# 3. Docker 이미지 빌드
# Dockerfile을 기반으로 애플리케이션을 빌드하여 Docker 이미지를 생성.
# 이 단계에서 Gradle 빌드가 컨테이너 안에서 먼저 실행됨.
- name: Build Docker image
# GitHub Secrets를 환경 변수로 설정하고,
# docker build 명령어에 --build-arg로 전달합니다.
env:
DB_URL: ${{ secrets.DB_URL }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
- name: Build and Test with Docker
# Docker 빌드 과정에서 Gradle 테스트가 실행됩니다.
# 테스트가 실패하면 빌드도 실패하므로 CI가 중단됩니다.
run: |
docker build -t issue-dive-app \
--build-arg DB_URL="$DB_URL" \
--build-arg DB_USER="$DB_USER" \
--build-arg DB_PASSWORD="$DB_PASSWORD" \
.
# 4. Docker 컨테이너 안에서 테스트 실행
- name: Run tests inside Docker container
# GitHub Secrets를 다시 한번 환경 변수로 가져옵니다.
env:
# Spring Boot는 이 환경 변수들을 자동으로 인식하여 DB 설정으로 사용합니다.
# URL - localhost: GitHub Actions가 services에 설정된 MySQL 컨테이너를 localhost로 연결
SPRING_DATASOURCE_URL: jdbc:mysql://localhost:3306/issue_dive?useSSL=false
SPRING_DATASOURCE_USERNAME: ${{ secrets.DB_USER }}
SPRING_DATASOURCE_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
docker run --rm \
--network host \
-e SPRING_DATASOURCE_URL=$SPRING_DATASOURCE_URL \
-e SPRING_DATASOURCE_USERNAME=$SPRING_DATASOURCE_USERNAME \
-e SPRING_DATASOURCE_PASSWORD=$SPRING_DATASOURCE_PASSWORD \
issue-dive-app ./gradlew test

# --- 이전 방식 (더 이상 필요 없음) ---
# 이제 모든 빌드와 테스트가 Docker 컨테이너 안에서 이루어지므로,
# GitHub Actions Runner에 직접 Java를 설치하거나 gradlew에 실행 권한을 줄 필요가 없습니다.
# # 2. JDK 17 설치
# - name: Set up JDK 17
# uses: actions/setup-java@v4
# with:
# java-version: '17'
# distribution: 'temurin'

# # 3. gradlew 파일에 실행 권한 부여
# - name: Grant execute permission for gradlew
# run: chmod +x ./gradlew

# # 4. Gradle로 빌드 및 테스트 실행
# - name: Build with Gradle
# run: ./gradlew build --no-daemon

# re-run test용 주석 추가
docker build -t issue-dive-app .
33 changes: 12 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
# 1. 빌드 스테이지
FROM gradle:8.14.3-jdk17 AS builder
# 1. 빌드 및 테스트 스테이지
FROM gradle:8.8.0-jdk17 AS builder

WORKDIR /app

# build-arg를 받기 위한 ARG 선언을 추가합니다.
ARG DB_URL
ARG DB_USER
ARG DB_PASSWORD

# gradle.properties 파일을 동적으로 생성합니다.
RUN echo "dbUrl=${DB_URL}" >> gradle.properties
RUN echo "dbUser=${DB_USER}" >> gradle.properties
RUN echo "dbPassword=${DB_PASSWORD}" >> gradle.properties


# Gradle 캐시 최적화를 위해 build.gradle과 settings.gradle 먼저 복사
# Gradle 캐시 최적화를 위해 의존성 관련 파일 먼저 복사
COPY build.gradle settings.gradle gradlew ./
COPY gradle ./gradle

# 의존성 다운로드
# 의존성 다운로드 (네트워크를 사용하는 단계이므로 먼저 실행)
RUN ./gradlew --no-daemon dependencies

# 나머지 소스 복사 및 빌드
# 전체 소스 복사
COPY src ./src
RUN ./gradlew assemble --no-daemon -Dspring.profiles.active=test

# assemble 대신 build 명령어를 사용해 테스트까지 함께 실행합니다.
# Spring Boot의 테스트 프로필을 활성화하여 H2 DB를 사용하도록 합니다.
RUN ./gradlew build --no-daemon -Dspring.profiles.active=test


# 2. 실행 스테이지
FROM openjdk:17-jdk-slim

WORKDIR /app

# 빌드 산출물을 복사
# 빌드 산출물(테스트가 통과된)을 복사
COPY --from=builder /app/build/libs/*.jar app.jar

# 컨테이너 실행 시
ENTRYPOINT ["java", "-jar", "app.jar"]

# 컨테이너 실행
ENTRYPOINT ["java", "-jar", "app.jar"]
11 changes: 8 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,13 @@ tasks.named('test') {

// Flyway 설정
flyway {
url = dbUrl
user = dbUser
password = dbPassword
// CI 환경 등에서 dbUrl 프로퍼티가 없을 수 있으므로,
// 해당 프로퍼티가 존재할 때만 url, user, password를 설정합니다.
if (project.hasProperty('dbUrl')) {
url = dbUrl
user = dbUser
password = dbPassword
}
// cleanDisabled는 DB 연결 정보와 무관하므로 바깥에 두어도 안전합니다.
cleanDisabled = false
}
Loading