Merge pull request #167 from Industry-Academic-SW-Capstone/chore/#163 #383
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| paths: | |
| - src/** | |
| - traefik/** | |
| - docker-compose.prod.yml | |
| - .github/workflows/** | |
| pull_request: | |
| branches: [ main, develop ] | |
| workflow_dispatch: | |
| jobs: | |
| # CI: 모든 브랜치에서 빌드 및 테스트 | |
| ci: | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: . | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Make gradlew executable | |
| run: chmod +x gradlew | |
| - name: Build application | |
| run: ./gradlew build -x test | |
| # CD: main 브랜치에서만 Docker 이미지 빌드 및 배포 | |
| cd: | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| needs: ci | |
| defaults: | |
| run: | |
| working-directory: . | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ secrets.DOCKER_USERNAME }}/stockit | |
| tags: | | |
| type=ref,event=branch | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Docker Hub 업로드 후 서버 배포 | |
| - name: List files before copy | |
| run: | | |
| ls -la | |
| ls -la traefik/ | |
| ls -la traefik/* | |
| - name: Test SSH connection | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USERNAME }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| script: | | |
| echo "SSH connection successful!" | |
| whoami | |
| pwd | |
| - name: Copy config files to server | |
| id: copy | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USERNAME }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| source: "./traefik/traefik.yml,./traefik/dynamic_conf.yml,./docker-compose.prod.yml" | |
| target: /home/ymkim2353/ | |
| debug: true | |
| - name: Deploy to server | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.SERVER_HOST }} | |
| username: ${{ secrets.SERVER_USERNAME }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| script: | | |
| # letsencrypt 디렉토리 생성 (최초 배포 시에만 필요) | |
| mkdir -p traefik/letsencrypt | |
| touch traefik/letsencrypt/acme.json 2>/dev/null || true | |
| chmod 600 traefik/letsencrypt/acme.json | |
| # Redis 로그 디렉토리 생성 및 권한 설정 | |
| mkdir -p logs/redis | |
| chmod 777 logs/redis | |
| # 환경변수 설정 | |
| export POSTGRES_DB=${{ secrets.POSTGRES_DB }} | |
| export POSTGRES_USER=${{ secrets.POSTGRES_USER }} | |
| export POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} | |
| export POSTGRES_URL=${{ secrets.POSTGRES_URL }} | |
| export SPRING_PROFILES_ACTIVE=dev | |
| export SPRING_REDIS_HOST=${{ secrets.SPRING_REDIS_HOST }} | |
| export SPRING_REDIS_PORT=${{ secrets.SPRING_REDIS_PORT }} | |
| export KIS_API_APPKEY=${{ secrets.KIS_API_APPKEY }} | |
| export KIS_API_APPSECRET=${{ secrets.KIS_API_APPSECRET }} | |
| export KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} | |
| export KAKAO_REDIRECT_URI=${{ secrets.KAKAO_REDIRECT_URI }} | |
| export KAKAO_REST_API_KEY=${{ secrets.KAKAO_REST_API_KEY }} | |
| export JWT_SECRET=${{ secrets.JWT_SECRET }} | |
| export FIREBASE_CREDENTIALS_BASE64=${{ secrets.FIREBASE_CREDENTIALS_BASE64 }} | |
| export PYTHON_ANALYSIS_URL=${{ secrets.PYTHON_ANALYSIS_URL }} | |
| export GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }} | |
| # Docker Compose 실행 | |
| docker compose -f docker-compose.prod.yml down | |
| docker compose -f docker-compose.prod.yml pull | |
| docker compose -f docker-compose.prod.yml up -d | |
| # 오래된 Docker 이미지 정리 | |
| docker image prune -af --filter "until=24h" || true | |
| docker system prune -f --volumes || true |