diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index 5afe25f..36d8db2 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -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용 주석 추가 \ No newline at end of file + docker build -t issue-dive-app . \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e2626bc..3b2ffe7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,21 @@ -# 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. 실행 스테이지 @@ -31,9 +23,8 @@ 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"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index ebd8998..14f5af4 100644 --- a/build.gradle +++ b/build.gradle @@ -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 } \ No newline at end of file