Update deploy.yml #7
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: BE CI/CD | |
| # 이 워크플로우가 언제 실행될지 정의합니다. | |
| on: | |
| push: | |
| branches: [ "main" ] # main 브랜치에 코드가 푸시(push)될 때 실행됩니다. | |
| # 실행될 작업(job)들을 정의합니다. | |
| jobs: | |
| build-and-deploy: | |
| # 작업이 실행될 가상 환경을 지정합니다. (Ubuntu 최신 버전) | |
| runs-on: ubuntu-latest | |
| # 작업의 단계(step)들을 정의합니다. | |
| steps: | |
| # 1. 소스 코드 체크아웃 | |
| # GitHub 저장소의 코드를 가상 환경으로 가져옵니다. | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| # 2. JDK 17 설치 | |
| # 빌드에 필요한 Java 환경을 설정합니다. | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'temurin' | |
| # 3. Gradle 실행 권한 부여 | |
| # gradlew 스크립트에 실행 권한을 줍니다. | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| # 4. Gradle로 빌드 | |
| # 코드를 컴파일하고 테스트를 실행한 뒤, 실행 가능한 JAR 파일을 생성합니다. | |
| - name: Build with Gradle | |
| run: ./gradlew build | |
| # 5. GCP 인증 | |
| # GitHub Secrets에 저장된 서비스 계정 키를 사용하여 GCP에 인증합니다. | |
| - name: Authenticate to Google Cloud | |
| uses: 'google-github-actions/auth@v2' | |
| with: | |
| credentials_json: '${{ secrets.GCP_SA_KEY }}' | |
| # 6. gcloud CLI 설정 | |
| - name: Set up Cloud SDK | |
| uses: 'google-github-actions/setup-gcloud@v2' | |
| # 7. SSH 연결 테스트 및 인스턴스 상태 확인 | |
| - name: Check VM status and connectivity | |
| run: | | |
| echo "Checking VM instance status..." | |
| gcloud compute instances describe ${{ secrets.GCP_INSTANCE_NAME }} \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --format="value(status,networkInterfaces[0].accessConfigs[0].natIP)" || { | |
| echo "Failed to describe instance. Please check instance name, project, and zone." | |
| exit 1 | |
| } | |
| echo "Testing SSH connectivity..." | |
| gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --command="echo 'SSH connection successful'" \ | |
| --ssh-flag="-o ConnectTimeout=10" || { | |
| echo "SSH connection failed. Trying with troubleshoot..." | |
| gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --troubleshoot | |
| exit 1 | |
| } | |
| # 8. 빌드된 JAR 파일을 GCP VM으로 전송 | |
| - name: Transfer JAR to GCP VM | |
| run: | | |
| # '-plain.jar'를 제외하고 실행 가능한 JAR 파일만 찾습니다. | |
| JAR_FILE=$(find build/libs/ -name "*.jar" ! -name "*-plain.jar" | head -n 1) | |
| if [ -z "$JAR_FILE" ]; then | |
| echo "No executable JAR file found!" | |
| exit 1 | |
| fi | |
| echo "Found JAR file: $JAR_FILE" | |
| # JAR 파일을 VM으로 전송 | |
| gcloud compute scp \ | |
| "$JAR_FILE" \ | |
| ${{ secrets.GCP_INSTANCE_NAME }}:~/ \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --scp-flag="-o ConnectTimeout=30" | |
| # 9. VM에 접속하여 애플리케이션 실행 (환경 변수 주입) | |
| - name: Deploy to GCP VM | |
| run: | | |
| # JAR 파일명 추출 | |
| JAR_FILE_NAME=$(basename $(find build/libs/ -name "*.jar" ! -name "*-plain.jar" | head -n 1)) | |
| echo "Deploying JAR file: $JAR_FILE_NAME" | |
| # 환경 변수들을 파일로 작성하여 전송 | |
| cat > .env << EOF | |
| export DB_URL='${{ secrets.DB_URL }}' | |
| export DB_USERNAME='${{ secrets.DB_USERNAME }}' | |
| export DB_PASSWORD='${{ secrets.DB_PASSWORD }}' | |
| export JWT_SECRET='${{ secrets.JWT_SECRET }}' | |
| export GOOGLE_EMAIL='${{ secrets.GOOGLE_EMAIL }}' | |
| export GOOGLE_EMAIL_KEY='${{ secrets.GOOGLE_EMAIL_KEY }}' | |
| export NAVER_CLIENT='${{ secrets.NAVER_CLIENT }}' | |
| export NAVER_SECRET='${{ secrets.NAVER_SECRET }}' | |
| export OPENAI_API_KEY='${{ secrets.OPENAI_API_KEY }}' | |
| EOF | |
| # 환경 변수 파일을 VM으로 전송 | |
| gcloud compute scp \ | |
| .env \ | |
| ${{ secrets.GCP_INSTANCE_NAME }}:~/ \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --scp-flag="-o ConnectTimeout=30" | |
| # 배포 스크립트 실행 | |
| gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ | |
| --project=${{ secrets.GCP_PROJECT_ID }} \ | |
| --zone=${{ secrets.GCP_ZONE }} \ | |
| --ssh-flag="-o ConnectTimeout=30" \ | |
| --command=" | |
| # 기존 프로세스 종료 | |
| echo 'Stopping existing application...' | |
| pkill -f '$JAR_FILE_NAME' || true | |
| sleep 5 | |
| # 환경 변수 로드 및 새 애플리케이션 시작 | |
| echo 'Starting new application...' | |
| source ~/.env | |
| nohup java -jar ~/$JAR_FILE_NAME > ~/app.log 2>&1 & | |
| # 프로세스 시작 확인 | |
| sleep 3 | |
| if pgrep -f '$JAR_FILE_NAME' > /dev/null; then | |
| echo 'Application started successfully' | |
| echo 'Process ID:' \$(pgrep -f '$JAR_FILE_NAME') | |
| else | |
| echo 'Failed to start application' | |
| echo 'Last 20 lines of log:' | |
| tail -20 ~/app.log || echo 'No log file found' | |
| exit 1 | |
| fi | |
| " |