Skip to content

Update deploy.yml

Update deploy.yml #7

Workflow file for this run

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
"