1414
1515jobs :
1616 tests :
17- runs-on : ubuntu-latest
17+ strategy :
18+ fail-fast : false
19+ matrix :
20+ os : [ ubuntu-latest ]
21+ include :
22+ - os : ubuntu-latest
23+ gradle_cmd : " ./gradlew"
24+ report_path : " backend/build/reports/tests"
25+ domain_tasks : " testUser testExchange testTrade_log testWallet testCoin"
26+
27+ runs-on : ${{ matrix.os }}
1828 env :
19- # 테스트 환경 설정
2029 SPRING_PROFILES_ACTIVE : test-ci
21- # JWT 설정 (보안상 중요하므로 환경변수 처리)
22- CUSTOM_JWT_SECRET_KEY : test-secret-key-for-ci-testing-only-minimum-32-characters-required
23- CUSTOM_JWT_ACCESS_TOKEN_EXPIRATION_SECONDS : 3600
2430
31+ # ✅ Redis 서비스 추가
2532 services :
2633 redis :
2734 image : redis:7-alpine
@@ -32,59 +39,72 @@ jobs:
3239 --health-interval 10s
3340 --health-timeout 5s
3441 --health-retries 5
42+ env :
43+ REDIS_PASSWORD : " "
3544
3645 steps :
3746 - uses : actions/checkout@v4
38-
3947 - name : Set up JDK 21
4048 uses : actions/setup-java@v4
4149 with :
4250 java-version : ' 21'
4351 distribution : ' temurin'
4452 cache : gradle
4553
54+ # ✅ gradlew 실행 권한 부여
4655 - name : Grant execute permission for gradlew
4756 run : chmod +x backend/gradlew
4857
58+ # ✅ Redis 연결 테스트
4959 - name : Test Redis connection
5060 run : |
5161 echo "Testing Redis connection..."
5262 timeout 10s bash -c 'until printf "" 2>>/dev/null >>/dev/tcp/localhost/6379; do sleep 1; done'
5363 echo "Redis is ready!"
5464
55- - name : Run tests
56- run : ./gradlew clean test
65+ # ✅ application-test.yml에서 사용하는 모든 환경변수를 .env 파일에 생성
66+ - name : Create test .env file
67+ working-directory : backend
68+ run : |
69+ cat > .env << 'EOF'
70+ # Datasource 설정 (application-test.yml에서 참조)
71+ TEST_DATASOURCE_URL=jdbc:h2:mem:db_test;MODE=MySQL
72+ TEST_DATASOURCE_USERNAME=sa
73+ TEST_DATASOURCE_PASSWORD=
74+ TEST_DATASOURCE_DRIVER=org.h2.Driver
75+
76+ # JPA 설정 (application-test.yml에서 참조)
77+ TEST_JPA_HIBERNATE_DDL_AUTO=create-drop
78+
79+ # Redis 설정 (application-test.yml에서 참조, GitHub Actions 서비스 사용)
80+ TEST_REDIS_HOST=localhost
81+ TEST_REDIS_PORT=6379
82+ TEST_REDIS_PASSWORD=
83+
84+ # CI/CD 환경에서는 Embedded Redis 끄기
85+ SPRING_DATA_REDIS_EMBEDDED=false
86+
87+ # JWT 설정 (application-test.yml에서 참조)
88+ CUSTOM_JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}
89+ CUSTOM_JWT_ACCESS_TOKEN_EXPIRATION_SECONDS=3600
90+ EOF
91+
92+ - name : Run unit, and domain tests
93+ run : ${{ matrix.gradle_cmd }} clean test
5794 working-directory : backend
5895
5996 - name : Upload Test Reports
6097 if : always()
6198 uses : actions/upload-artifact@v4
6299 with :
63- name : test-reports
64- path : backend/build/reports/tests
100+ name : test-reports-${{ matrix.os }}
101+ path : ${{ matrix.report_path }}
65102 retention-days : 7
66103
67104 build-artifacts :
68105 needs : tests
69106 runs-on : ubuntu-latest
70- if : github.ref == 'refs/heads/main'
71- env :
72- # 빌드용 최소 환경변수 (컴파일 시 @Value 바인딩용)
73- SPRING_PROFILES_ACTIVE : prod
74- CUSTOM_JWT_SECRET_KEY : build-secret-key-for-compilation-only-minimum-32-characters-required
75- CUSTOM_JWT_ACCESS_TOKEN_EXPIRATION_SECONDS : 3600
76- # 빌드 시 필요한 더미 값들
77- 78- send_email_password : build-password
79- send_email_address :
[email protected] 80- PROD_DATASOURCE_URL : jdbc:mysql://localhost:3306/dummy
81- PROD_DATASOURCE_DRIVER : com.mysql.cj.jdbc.Driver
82- PROD_DATASOURCE_USERNAME : dummy
83- PROD_DATASOURCE_PASSWORD : dummy
84- PROD_JPA_HIBERNATE_DDL_AUTO : validate
85- PROD_REDIS_HOST : localhost
86- PROD_REDIS_PORT : 6379
87- PROD_REDIS_PASSWORD : dummy
107+ if : github.ref == 'refs/heads/main' # ✅ main 브랜치일 때만 실행
88108
89109 steps :
90110 - uses : actions/checkout@v4
@@ -95,9 +115,20 @@ jobs:
95115 java-version : 21
96116 cache : gradle
97117
118+ # ✅ gradlew 실행 권한 부여
98119 - name : Grant execute permission for gradlew
99120 run : chmod +x backend/gradlew
100121
122+ # ✅ 빌드용 .env 파일 생성 (Configuration Properties 바인딩용 최소 환경변수만)
123+ - name : Create build .env file
124+ working-directory : backend
125+ run : |
126+ cat > .env << 'EOF'
127+ # JWT Configuration Properties 바인딩용 (빌드 시 필요)
128+ CUSTOM_JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}
129+ CUSTOM_JWT_ACCESS_TOKEN_EXPIRATION_SECONDS=3600
130+ EOF
131+
101132 - name : Gradle bootJar
102133 working-directory : backend
103134 run : ./gradlew --no-daemon clean bootJar -x test
@@ -117,7 +148,7 @@ jobs:
117148 docker-build :
118149 needs : build-artifacts
119150 runs-on : ubuntu-latest
120- if : github.ref == 'refs/heads/main'
151+ if : github.ref == 'refs/heads/main' # ✅ main 브랜치일 때만 실행
121152 env :
122153 REGISTRY : ghcr.io
123154
@@ -142,7 +173,7 @@ jobs:
142173 username : ${{ github.actor }}
143174 password : ${{ secrets.GITHUB_TOKEN }}
144175
145- - name : Build & push backend
176+ - name : Build & push backend (runtime-only)
146177 uses : docker/build-push-action@v6
147178 with :
148179 context : backend
@@ -153,11 +184,10 @@ jobs:
153184 ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/balaw:latest
154185 cache-from : type=gha
155186 cache-to : type=gha,mode=max
156-
157187 deploy :
158188 needs : docker-build
159189 runs-on : ubuntu-latest
160- if : github.ref == 'refs/heads/main'
190+ if : github.ref == 'refs/heads/main' # ✅ main 브랜치일 때만 실행
161191 env :
162192 DOCKER_IMAGE_NAME : balaw
163193 REGISTRY : ghcr.io
@@ -167,6 +197,19 @@ jobs:
167197 run : |
168198 echo "IMAGE_PREFIX=$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
169199
200+ - name : Create prod .env file
201+ run : |
202+ cat > .env << 'EOF'
203+ SPRING_PROFILES_ACTIVE=prod
204+ PROD_DATASOURCE_URL=jdbc:mysql://mysql_1:3306/${{ secrets.DB_NAME }}
205+ PROD_DATASOURCE_USERNAME=${{ secrets.DB_USER }}
206+ PROD_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }}
207+
208+ PROD_REDIS_HOST=redis_1
209+ PROD_REDIS_PORT=6379
210+ PROD_REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}
211+ EOF
212+
170213 - name : AWS SSM Send-Command
171214 uses : peterkimzz/aws-ssm-send-command@master
172215 id : ssm
@@ -178,34 +221,27 @@ jobs:
178221 working-directory : /
179222 comment : Deploy
180223 command : |
181- # EC2에서 실제 운영 환경변수로 prod.env 파일 생성
224+ # EC2 내부에서 prod.env 파일 생성
182225 cat > /home/ec2-user/prod.env << 'EOF'
183226 SPRING_PROFILES_ACTIVE=prod
184-
185- # JWT 설정 (GitHub Secrets에서 가져옴)
227+
186228 CUSTOM_JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}
187229 CUSTOM_JWT_ACCESS_TOKEN_EXPIRATION_SECONDS=3600
188230
189- # 데이터베이스 설정 (GitHub Secrets에서 가져옴)
190231 PROD_DATASOURCE_URL=jdbc:mysql://mysql_1:3306/${{ secrets.DB_NAME }}?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul
191232 PROD_DATASOURCE_DRIVER=com.mysql.cj.jdbc.Driver
192233 PROD_DATASOURCE_USERNAME=root
193234 PROD_DATASOURCE_PASSWORD=${{ secrets.DB_PASSWORD }}
194- PROD_JPA_HIBERNATE_DDL_AUTO=validate
195235
196- # Redis 설정 (GitHub Secrets에서 가져옴)
197236 PROD_REDIS_HOST=redis_1
198237 PROD_REDIS_PORT=6379
199238 PROD_REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}
200-
201- # 이메일 설정 (GitHub Secrets에서 가져옴)
202- email_address=${{ secrets.EMAIL_ADDRESS }}
203- send_email_password=${{ secrets.EMAIL_PASSWORD }}
204- send_email_address=${{ secrets.SEND_EMAIL_ADDRESS }}
205239 EOF
206240
207- # GHCR 로그인 및 컨테이너 배포
241+ # EC2에서 GHCR 로그인
208242 echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
243+
244+ # 최신 이미지 pull & 컨테이너 실행
209245 docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/${{ env.DOCKER_IMAGE_NAME }}:latest
210246 docker stop app1 2>/dev/null || true
211247 docker rm app1 2>/dev/null || true
@@ -215,6 +251,6 @@ jobs:
215251 -p 8080:8080 \
216252 ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/${{ env.DOCKER_IMAGE_NAME }}:latest
217253
218- # 정리
254+ # dangling image 정리 + .env 삭제
219255 docker rmi $(docker images -f "dangling=true" -q) || true
220256 rm -f /home/ec2-user/prod.env
0 commit comments