Skip to content

Commit b9d7681

Browse files
authored
[fix/OPS-317] CI/CD 파이프라인 이벤트 분리 (#66)
* fix : prod-server nginx 정보 출력 제거 * fix : prod-server CD 워크플로우 main에 push될 때 실행되도록 수정 * fix : test-server CI는 pr시 develop에 실행, CD는 push될 때 실행 * fix : test-server CI 워크플로우에서 CD 부분 제거
1 parent 8654507 commit b9d7681

File tree

4 files changed

+226
-252
lines changed

4 files changed

+226
-252
lines changed

.github/workflows/prod-server.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Spring CD (Production)
33

44
# main 브랜치 PR에서만 실행 (이미 빌드된 Docker 이미지 사용)
55
on:
6-
pull_request:
6+
push:
77
branches:
88
- main
99
paths:
@@ -18,7 +18,7 @@ jobs:
1818
# ==================================
1919
# CD: Deploy to Production Environment
2020
# ==================================
21-
cd-test:
21+
cd-prod:
2222
runs-on: ubuntu-latest
2323

2424
steps:
@@ -60,7 +60,6 @@ jobs:
6060
echo "📋 Checking current NPM configuration... 📋"
6161
CURRENT_CONFIG=$(curl -s -H "Authorization: Bearer $TOKEN" \
6262
"http://${NPM_HOST}/api/nginx/proxy-hosts/${PROXY_HOST_ID}")
63-
echo "Current Config: $CURRENT_CONFIG"
6463
6564
CURRENT_TARGET=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_host // .forward_host')
6665
CURRENT_PORT=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_port // .forward_port')
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: Spring CD (Test Server)
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
8+
jobs:
9+
cd-test:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Deploy to Test Environment
17+
uses: appleboy/[email protected]
18+
with:
19+
host: ${{ secrets.TEST_SERVER_HOST }}
20+
username: ec2-user
21+
key: ${{ secrets.SSH_PRIVATE_KEY }}
22+
script: |
23+
# GHCR 로그인
24+
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.repository_owner }}" --password-stdin
25+
docker pull ghcr.io/${{ github.repository }}/zoopzoop:latest
26+
27+
NPM_HOST="localhost:81"
28+
NPM_EMAIL="${{ secrets.NPM_ADMIN_EMAIL }}"
29+
NPM_PASSWORD="${{ secrets.NPM_ADMIN_PASSWORD }}"
30+
PROXY_HOST_ID="${{ secrets.NPM_PROXY_HOST_ID }}"
31+
32+
# NPM 토큰
33+
TOKEN=$(curl -s -X POST "http://${NPM_HOST}/api/tokens" \
34+
-H "Content-Type: application/json" \
35+
-d "{\"identity\":\"${NPM_EMAIL}\",\"secret\":\"${NPM_PASSWORD}\"}" | jq -r '.token')
36+
if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then
37+
echo "❌ Failed to get NPM API token"
38+
exit 1
39+
fi
40+
41+
CURRENT_CONFIG=$(curl -s -H "Authorization: Bearer $TOKEN" \
42+
"http://${NPM_HOST}/api/nginx/proxy-hosts/${PROXY_HOST_ID}")
43+
44+
CURRENT_TARGET=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_host // .forward_host')
45+
CURRENT_PORT=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_port // .forward_port')
46+
echo "Current NPM target: $CURRENT_TARGET:$CURRENT_PORT"
47+
48+
if [ "$(docker ps -q -f name=zoopzoop-blue)" ]; then
49+
NEW_CONTAINER=zoopzoop-green
50+
OLD_CONTAINER=zoopzoop-blue
51+
NEW_PORT=8082
52+
else
53+
NEW_CONTAINER=zoopzoop-blue
54+
OLD_CONTAINER=zoopzoop-green
55+
NEW_PORT=8081
56+
fi
57+
58+
docker run -d --restart unless-stopped \
59+
-p $NEW_PORT:8080 \
60+
--name $NEW_CONTAINER \
61+
--network common \
62+
-e SPRING_DATASOURCE_URL="${{secrets.TEST_DB_URL}}" \
63+
-e SPRING_DATASOURCE_USERNAME="${{secrets.TEST_DB_USERNAME}}" \
64+
-e SPRING_DATASOURCE_PASSWORD="${{secrets.TEST_DB_PASSWORD}}" \
65+
ghcr.io/${{ github.repository }}/zoopzoop:latest
66+
67+
# 헬스체크
68+
for i in {1..30}; do
69+
if curl -s http://localhost:$NEW_PORT/actuator/health | grep -q '"status":"UP"'; then
70+
echo "✅ New container is healthy!"
71+
break
72+
else
73+
echo "Waiting for new container to be healthy..."
74+
sleep 5
75+
fi
76+
if [ $i -eq 30 ]; then
77+
echo "❌ Health check failed. Rolling back..."
78+
docker stop $NEW_CONTAINER || true
79+
docker rm $NEW_CONTAINER || true
80+
exit 1
81+
fi
82+
done
83+
84+
# NPM 트래픽 스위칭
85+
DOMAIN_NAME=$(echo $CURRENT_CONFIG | jq -r '.domain_names[0]')
86+
CERT_ID=$(echo "$CURRENT_CONFIG" | jq -r '.certificate_id')
87+
88+
SWITCH_RESPONSE=$(curl -s -w "%{http_code}" -X PUT "http://${NPM_HOST}/api/nginx/proxy-hosts/${PROXY_HOST_ID}" \
89+
-H "Authorization: Bearer $TOKEN" \
90+
-H "Content-Type: application/json" \
91+
-d "{
92+
\"domain_names\": [\"$DOMAIN_NAME\"],
93+
\"forward_scheme\": \"http\",
94+
\"forward_host\": \"$NEW_CONTAINER\",
95+
\"forward_port\": 8080,
96+
\"caching_enabled\": false,
97+
\"block_exploits\": true,
98+
\"advanced_config\": \"\",
99+
\"locations\": [],
100+
\"certificate_id\": $CERT_ID,
101+
\"ssl_forced\": 1,
102+
\"hsts_enabled\": 1,
103+
\"hsts_subdomains\": 1
104+
}")
105+
106+
HTTP_CODE=${SWITCH_RESPONSE: -3}
107+
if [ "$HTTP_CODE" -ne 200 ] && [ "$HTTP_CODE" -ne 201 ]; then
108+
echo "❌ Traffic switching failed! HTTP Code: $HTTP_CODE"
109+
echo "Response: ${SWITCH_RESPONSE%???}"
110+
docker stop $NEW_CONTAINER || true
111+
docker rm $NEW_CONTAINER || true
112+
exit 1
113+
fi
114+
115+
docker stop $OLD_CONTAINER || true
116+
docker rm $OLD_CONTAINER || true
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# 워크플로우 이름
2+
name: Spring CI/CD Pipeline (Develop)
3+
4+
# develop 브랜치 PR에서만 실행
5+
on:
6+
pull_request:
7+
branches:
8+
- develop
9+
paths:
10+
- 'src/**'
11+
- 'build.gradle*'
12+
- 'settings.gradle*'
13+
- 'gradle/**'
14+
- 'Dockerfile'
15+
- '.github/workflows/**'
16+
17+
jobs:
18+
# ==================================
19+
# CI: Test and Build and Push Docker Image
20+
# ==================================
21+
ci:
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
# 1. 소스 코드 체크아웃
26+
- name: Checkout source code
27+
uses: actions/checkout@v4
28+
29+
# 2. JDK 21 설치
30+
- name: Set up JDK 21
31+
uses: actions/setup-java@v4
32+
with:
33+
java-version: '21'
34+
distribution: 'temurin'
35+
36+
# 3. Gradle 캐시 설정
37+
- name: Cache Gradle packages
38+
uses: actions/cache@v4
39+
with:
40+
path: |
41+
~/.gradle/caches
42+
~/.gradle/wrapper
43+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
44+
restore-keys: |
45+
${{ runner.os }}-gradle-
46+
47+
# 4. gradlew 실행 권한 부여
48+
- name: Grant execute permission for gradlew
49+
run: chmod +x ./gradlew
50+
51+
# 5. application-secrets.yml 생성
52+
- name: Generate application-secrets.yml
53+
run: |
54+
mkdir -p src/main/resources
55+
echo "${{ secrets.APPLICATION_SECRET_YML }}" > src/main/resources/application-secrets.yml
56+
echo "OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}" >> src/main/resources/application-secrets.yml
57+
58+
# 6. application-secrets-server.yml 생성
59+
- name: Generate application-secrets-server.yml
60+
run: |
61+
mkdir -p src/main/resources
62+
echo "${{ secrets.APPLICATION_SECRET_SERVER_YML }}" > src/main/resources/application-secrets-server.yml
63+
echo "OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}" >> src/main/resources/application-secrets-server.yml
64+
65+
# 7. Gradle 테스트 실행
66+
- name: Test with Gradle
67+
run: ./gradlew test
68+
69+
# 8. 테스트 결과 요약 출력
70+
- name: Show test results
71+
run: |
72+
echo "==== Test Results ===="
73+
if compgen -G "build/test-results/test/TEST-*.xml" > /dev/null; then
74+
total=$(grep '<testcase ' build/test-results/test/TEST-*.xml | wc -l)
75+
failed=$(grep -h '<failure' build/test-results/test/TEST-*.xml | wc -l)
76+
error=$(grep -h '<error' build/test-results/test/TEST-*.xml | wc -l)
77+
passed=$((total - failed - error))
78+
echo "Total tests: $total"
79+
echo "Passed tests: $passed"
80+
echo "Failed tests: $failed"
81+
echo "Errored tests: $error"
82+
else
83+
echo "No test results found."
84+
fi
85+
86+
# 9. Gradle 빌드 실행 (테스트 성공 시)
87+
- name: Build with Gradle
88+
run: ./gradlew build
89+
90+
# 10. GHCR 로그인
91+
- name: Log in to GHCR
92+
uses: docker/login-action@v2
93+
with:
94+
registry: ghcr.io
95+
username: ${{ github.repository_owner }}
96+
password: ${{ secrets.GITHUB_TOKEN }}
97+
98+
# 11. Docker 이미지 빌드 & 푸시
99+
- name: Build & Push Docker Image
100+
run: |
101+
IMAGE_NAME=ghcr.io/${{ github.repository }}/zoopzoop
102+
103+
docker build -t $IMAGE_NAME:${GITHUB_SHA} .
104+
docker tag $IMAGE_NAME:${GITHUB_SHA} $IMAGE_NAME:latest
105+
106+
docker push $IMAGE_NAME:${GITHUB_SHA}
107+
docker push $IMAGE_NAME:latest
108+

0 commit comments

Comments
 (0)