|
7 | 7 | jobs: |
8 | 8 | build-and-deploy: |
9 | 9 | runs-on: ubuntu-latest |
| 10 | + |
10 | 11 | steps: |
| 12 | + # ... 1~5단계는 동일 ... |
11 | 13 | - name: Checkout |
12 | 14 | uses: actions/checkout@v4 |
13 | | - |
14 | 15 | - name: Set up JDK 17 |
15 | 16 | uses: actions/setup-java@v4 |
16 | 17 | with: |
17 | 18 | java-version: '17' |
18 | 19 | distribution: 'temurin' |
19 | | - |
20 | 20 | - name: Grant execute permission for gradlew |
21 | 21 | run: chmod +x gradlew |
22 | | - |
23 | 22 | - name: Build with Gradle |
24 | 23 | run: ./gradlew build |
25 | | - |
26 | 24 | - name: Authenticate to Google Cloud |
27 | 25 | uses: 'google-github-actions/auth@v2' |
28 | 26 | with: |
29 | 27 | credentials_json: '${{ secrets.GCP_SA_KEY }}' |
30 | 28 |
|
31 | | - - name: Set up Cloud SDK |
32 | | - uses: 'google-github-actions/setup-gcloud@v2' |
33 | | - |
34 | | - - name: Check VM status and connectivity |
| 29 | + # 6. 배포 스크립트 파일 생성 (System Properties 사용 방식으로 변경) |
| 30 | + - name: Create Deploy Script |
35 | 31 | run: | |
36 | | - echo "Checking VM instance status..." |
37 | | - gcloud compute instances describe ${{ secrets.GCP_INSTANCE_NAME }} \ |
38 | | - --project=${{ secrets.GCP_PROJECT_ID }} \ |
39 | | - --zone=${{ secrets.GCP_ZONE }} \ |
40 | | - --format="value(status,networkInterfaces[0].accessConfigs[0].natIP)" || { |
41 | | - echo "Failed to describe instance. Please check instance name, project, and zone." |
42 | | - exit 1 |
43 | | - } |
44 | | -
|
45 | | - echo "Testing SSH connectivity..." |
46 | | - gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ |
47 | | - --project=${{ secrets.GCP_PROJECT_ID }} \ |
48 | | - --zone=${{ secrets.GCP_ZONE }} \ |
49 | | - --command="echo 'SSH connection successful'" \ |
50 | | - --ssh-flag="-o ConnectTimeout=10" || { |
51 | | - echo "SSH connection failed. Running troubleshoot..." |
52 | | - gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ |
53 | | - --project=${{ secrets.GCP_PROJECT_ID }} \ |
54 | | - --zone=${{ secrets.GCP_ZONE }} \ |
55 | | - --troubleshoot |
56 | | - exit 1 |
57 | | - } |
58 | | -
|
59 | | - - name: Create deploy script and transfer JAR |
60 | | - run: | |
61 | | - JAR_FILE=$(find build/libs/ -name "*.jar" ! -name "*-plain.jar" | head -n 1) |
62 | | - if [ -z "$JAR_FILE" ]; then |
63 | | - echo "No executable JAR file found!" |
64 | | - exit 1 |
65 | | - fi |
66 | | -
|
67 | | - JAR_FILENAME=$(basename "$JAR_FILE") |
68 | | - echo "Found JAR file: $JAR_FILE" |
69 | | -
|
70 | | - cat > deploy.sh << 'EOF' |
| 32 | + JAR_FILE_NAME=$(basename $(find build/libs/ -name "*.jar" ! -name "*-plain.jar")) |
| 33 | + |
| 34 | + # java -D 옵션을 사용하여 설정값을 직접 전달하는 스크립트를 생성합니다. |
| 35 | + cat > ./deploy.sh << EOF |
71 | 36 | #!/bin/bash |
72 | | - set -e |
73 | | -
|
74 | | - JAR_NAME="__JAR_NAME__" |
75 | | -
|
| 37 | + |
| 38 | + # 기존 프로세스 종료 |
76 | 39 | echo "Stopping existing application..." |
77 | | - pkill -f "$JAR_NAME" || true |
78 | | - sleep 3 |
79 | | -
|
80 | | - echo "Remote java -version before installation attempt:" |
81 | | - java -version || true |
82 | | -
|
83 | | - echo "Checking java major version..." |
84 | | - if command -v java >/dev/null 2>&1; then |
85 | | - JAVA_MAJOR=$(java -version 2>&1 | awk -F'".' '/version/ { if ($2=="1") print $3; else print $2; exit }') || true |
86 | | - echo "Detected Java major version: $JAVA_MAJOR" |
| 40 | + pkill -f '$JAR_FILE_NAME' || true |
| 41 | + sleep 5 |
| 42 | + |
| 43 | + # 새 애플리케이션 시작 (java -D 옵션으로 모든 Secret 전달) |
| 44 | + echo "Starting new application..." |
| 45 | + nohup /opt/oracle/product/21c/dbhomeXE/jdk/bin/java \ |
| 46 | + -Dspring.datasource.url='${{ secrets.DB_URL }}' \ |
| 47 | + -Dspring.datasource.username='${{ secrets.DB_USERNAME }}' \ |
| 48 | + -Dspring.datasource.password='${{ secrets.DB_PASSWORD }}' \ |
| 49 | + -Dapp.jwt.secret='${{ secrets.JWT_SECRET }}' \ |
| 50 | + -Dspring.ai.openai.api-key='${{ secrets.OPENAI_API_KEY }}' \ |
| 51 | + -Dspring.mail.username='${{ secrets.GOOGLE_EMAIL }}' \ |
| 52 | + -Dspring.mail.password='${{ secrets.GOOGLE_EMAIL_KEY }}' \ |
| 53 | + -Dcloud.naver.clova.client='${{ secrets.NAVER_CLIENT }}' \ |
| 54 | + -Dcloud.naver.clova.secret='${{ secrets.NAVER_SECRET }}' \ |
| 55 | + -Demail.from='${{ secrets.GOOGLE_EMAIL }}' \ |
| 56 | + -jar ~/$JAR_FILE_NAME > ~/app.log 2>&1 & |
| 57 | + |
| 58 | + # 프로세스 시작 확인 |
| 59 | + echo "Waiting for application to start..." |
| 60 | + sleep 15 |
| 61 | + if pgrep -f '$JAR_FILE_NAME' > /dev/null; then |
| 62 | + echo "Application process is running." |
| 63 | + echo "Process ID: \$(pgrep -f '$JAR_FILE_NAME')" |
| 64 | + echo "--- Last 50 lines of app.log ---" |
| 65 | + tail -50 ~/app.log |
87 | 66 | else |
88 | | - JAVA_MAJOR=0 |
89 | | - echo "java not found on system" |
90 | | - fi |
91 | | -
|
92 | | - if [ "$JAVA_MAJOR" -lt 17 ]; then |
93 | | - echo "Java 17+ required. Trying apt, then yum..." |
94 | | -
|
95 | | - if command -v apt-get >/dev/null 2>&1; then |
96 | | - echo "Detected apt-get. Trying apt install openjdk-17..." |
97 | | - if sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jre-headless; then |
98 | | - echo "openjdk-17 installed via apt" |
99 | | - else |
100 | | - echo "apt install failed" |
101 | | - fi |
102 | | - fi |
103 | | -
|
104 | | - if command -v yum >/dev/null 2>&1; then |
105 | | - echo "Detected yum. Trying yum install java-17-openjdk..." |
106 | | - if sudo yum install -y java-17-openjdk-headless || sudo yum install -y java-17-openjdk; then |
107 | | - echo "openjdk-17 installed via yum" |
108 | | - else |
109 | | - echo "yum install failed" |
110 | | - fi |
111 | | - fi |
112 | | -
|
113 | | - echo "Java version after install attempts:" |
114 | | - java -version || true |
115 | | -
|
116 | | - if command -v java >/dev/null 2>&1; then |
117 | | - JAVA_MAJOR=$(java -version 2>&1 | awk -F'".' '/version/ { if ($2=="1") print $3; else print $2; exit }') || true |
118 | | - else |
119 | | - JAVA_MAJOR=0 |
120 | | - fi |
121 | | -
|
122 | | - if [ "$JAVA_MAJOR" -lt 17 ]; then |
123 | | - echo "Automatic installation did not produce Java 17+. Please install Java 17+ on the VM manually." |
124 | | - exit 1 |
125 | | - fi |
126 | | - fi |
127 | | -
|
128 | | - echo "Starting new application with Java version:" |
129 | | - java -version || true |
130 | | -
|
131 | | - nohup java -jar ~/$JAR_NAME > ~/app.log 2>&1 & |
132 | | -
|
133 | | - sleep 3 |
134 | | - if pgrep -f "$JAR_NAME" > /dev/null; then |
135 | | - echo "Application started successfully" |
136 | | - exit 0 |
137 | | - else |
138 | | - echo "Failed to start application" |
139 | | - tail -20 ~/app.log || true |
| 67 | + echo "Failed to start application. Check app.log for details." |
| 68 | + echo "--- Last 50 lines of app.log ---" |
| 69 | + tail -50 ~/app.log |
140 | 70 | exit 1 |
141 | 71 | fi |
142 | 72 | EOF |
143 | 73 |
|
144 | | - # inject actual jar name into deploy.sh |
145 | | - sed -i "s|__JAR_NAME__|$JAR_FILENAME|g" deploy.sh |
146 | | -
|
147 | | - chmod +x deploy.sh |
148 | | -
|
149 | | - # create environment file with secrets |
150 | | - cat > deploy.env << EOF |
151 | | - DB_URL='${{ secrets.DB_URL }}' |
152 | | - DB_USERNAME='${{ secrets.DB_USERNAME }}' |
153 | | - DB_PASSWORD='${{ secrets.DB_PASSWORD }}' |
154 | | - JWT_SECRET='${{ secrets.JWT_SECRET }}' |
155 | | - GOOGLE_EMAIL='${{ secrets.GOOGLE_EMAIL }}' |
156 | | - GOOGLE_EMAIL_KEY='${{ secrets.GOOGLE_EMAIL_KEY }}' |
157 | | - NAVER_CLIENT='${{ secrets.NAVER_CLIENT }}' |
158 | | - NAVER_SECRET='${{ secrets.NAVER_SECRET }}' |
159 | | - OPENAI_API_KEY='${{ secrets.OPENAI_API_KEY }}' |
160 | | - EOF |
161 | | -
|
162 | | - # Transfer files to VM |
163 | | - gcloud compute scp "$JAR_FILE" deploy.sh deploy.env ${{ secrets.GCP_INSTANCE_NAME }}:~/ \ |
164 | | - --project=${{ secrets.GCP_PROJECT_ID }} --zone=${{ secrets.GCP_ZONE }} --scp-flag="-o ConnectTimeout=30" |
| 74 | + # 7. JAR 파일 및 배포 스크립트 전송 |
| 75 | + - name: Transfer Files to GCP VM |
| 76 | + run: | |
| 77 | + JAR_FILE=$(find build/libs/ -name "*.jar" ! -name "*-plain.jar") |
| 78 | + gcloud compute scp \ |
| 79 | + "$JAR_FILE" \ |
| 80 | + ./deploy.sh \ |
| 81 | + ${{ secrets.GCP_INSTANCE_NAME }}:~/ \ |
| 82 | + --project=${{ secrets.GCP_PROJECT_ID }} \ |
| 83 | + --zone=${{ secrets.GCP_ZONE }} |
165 | 84 |
|
166 | | - - name: Run deploy script on VM |
| 85 | + # 8. VM에서 배포 스크립트 실행 |
| 86 | + - name: Execute Deploy Script on VM |
167 | 87 | run: | |
168 | 88 | gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \ |
169 | 89 | --project=${{ secrets.GCP_PROJECT_ID }} \ |
170 | 90 | --zone=${{ secrets.GCP_ZONE }} \ |
171 | | - --ssh-flag="-o ConnectTimeout=30" \ |
172 | | - --command="bash ~/deploy.sh" |
173 | | -
|
174 | | - - name: Cleanup local temp files |
175 | | - if: always() |
176 | | - run: | |
177 | | - rm -f deploy.sh deploy.env |
| 91 | + --command="chmod +x ~/deploy.sh && ~/deploy.sh" |
0 commit comments