From ea53bd13a8f531b2a7be29363073471523714704 Mon Sep 17 00:00:00 2001 From: Hyowon Yang Date: Thu, 30 Oct 2025 10:08:48 +0900 Subject: [PATCH] =?UTF-8?q?analytics=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EC=83=98=ED=94=8C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20ID=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이벤트 ID를 evt_2025012301 형식에서 1, 2, 3으로 변경 - 다른 마이크로서비스와의 연동을 위한 단순 ID 체계 적용 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/backend-cicd.yaml | 207 ++++++++++++++++++ .../analytics/config/SampleDataLoader.java | 12 +- 2 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/backend-cicd.yaml diff --git a/.github/workflows/backend-cicd.yaml b/.github/workflows/backend-cicd.yaml new file mode 100644 index 0000000..4a88b37 --- /dev/null +++ b/.github/workflows/backend-cicd.yaml @@ -0,0 +1,207 @@ +name: Backend CI/CD Pipeline + +on: + # push: + # branches: + # - develop + # - main + # paths: + # - '*-service/**' + # - '.github/workflows/backend-cicd.yaml' + # - '.github/kustomize/**' + pull_request: + branches: + - develop + - main + paths: + - '*-service/**' + workflow_dispatch: + inputs: + environment: + description: 'Target environment' + required: true + type: choice + options: + - dev + - staging + - prod + service: + description: 'Service to deploy (all for all services)' + required: true + default: 'all' + +env: + ACR_NAME: acrdigitalgarage01 + RESOURCE_GROUP: rg-digitalgarage-01 + AKS_CLUSTER: aks-digitalgarage-01 + NAMESPACE: kt-event-marketing + JDK_VERSION: '21' + +jobs: + detect-changes: + name: Detect Changed Services + runs-on: ubuntu-latest + outputs: + services: ${{ steps.detect.outputs.services }} + environment: ${{ steps.env.outputs.environment }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine environment + id: env + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_OUTPUT + elif [ "${{ github.ref }}" = "refs/heads/main" ]; then + echo "environment=prod" >> $GITHUB_OUTPUT + elif [ "${{ github.ref }}" = "refs/heads/develop" ]; then + echo "environment=dev" >> $GITHUB_OUTPUT + else + echo "environment=dev" >> $GITHUB_OUTPUT + fi + + - name: Detect changed services + id: detect + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.service }}" != "all" ]; then + echo "services=[\"${{ github.event.inputs.service }}\"]" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.service }}" = "all" ]; then + echo "services=[\"user-service\",\"event-service\",\"ai-service\",\"content-service\",\"distribution-service\",\"participation-service\",\"analytics-service\"]" >> $GITHUB_OUTPUT + else + CHANGED_SERVICES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | \ + grep -E '^(user|event|ai|content|distribution|participation|analytics)-service/' | \ + cut -d'/' -f1 | sort -u | \ + jq -R -s -c 'split("\n") | map(select(length > 0))') + + if [ "$CHANGED_SERVICES" = "[]" ] || [ -z "$CHANGED_SERVICES" ]; then + echo "services=[\"user-service\",\"event-service\",\"ai-service\",\"content-service\",\"distribution-service\",\"participation-service\",\"analytics-service\"]" >> $GITHUB_OUTPUT + else + echo "services=$CHANGED_SERVICES" >> $GITHUB_OUTPUT + fi + fi + + build-and-push: + name: Build and Push - ${{ matrix.service }} + needs: detect-changes + runs-on: ubuntu-latest + strategy: + matrix: + service: ${{ fromJson(needs.detect-changes.outputs.services) }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK ${{ env.JDK_VERSION }} + uses: actions/setup-java@v4 + with: + java-version: ${{ env.JDK_VERSION }} + distribution: 'temurin' + cache: 'gradle' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew ${{ matrix.service }}:build -x test + + # - name: Run tests + # run: ./gradlew ${{ matrix.service }}:test + + - name: Build JAR + run: ./gradlew ${{ matrix.service }}:bootJar + + - name: Log in to Azure Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.ACR_NAME }}.azurecr.io + username: ${{ secrets.ACR_USERNAME }} + password: ${{ secrets.ACR_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./${{ matrix.service }} + file: ./${{ matrix.service }}/Dockerfile + push: true + tags: | + ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:${{ needs.detect-changes.outputs.environment }} + ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:${{ github.sha }} + ${{ env.ACR_NAME }}.azurecr.io/kt-event-marketing/${{ matrix.service }}:latest + + deploy: + name: Deploy to AKS - ${{ needs.detect-changes.outputs.environment }} + needs: [detect-changes, build-and-push] + runs-on: ubuntu-latest + environment: ${{ needs.detect-changes.outputs.environment }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Azure login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Get AKS credentials + run: | + az aks get-credentials \ + --resource-group ${{ env.RESOURCE_GROUP }} \ + --name ${{ env.AKS_CLUSTER }} \ + --overwrite-existing + + - name: Setup Kustomize + uses: imranismail/setup-kustomize@v2 + + - name: Deploy with Kustomize + run: | + cd .github/kustomize/overlays/${{ needs.detect-changes.outputs.environment }} + kustomize edit set image \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/ai-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/distribution-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:${{ needs.detect-changes.outputs.environment }} \ + acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:${{ needs.detect-changes.outputs.environment }} + + kustomize build . | kubectl apply -f - + + - name: Wait for deployment rollout + run: | + for service in $(echo '${{ needs.detect-changes.outputs.services }}' | jq -r '.[]'); do + echo "Waiting for ${service} deployment..." + kubectl rollout status deployment/${service} -n ${{ env.NAMESPACE }} --timeout=5m + done + + - name: Verify deployment + run: | + echo "=== Pods Status ===" + kubectl get pods -n ${{ env.NAMESPACE }} -l app.kubernetes.io/part-of=kt-event-marketing + + echo "=== Services ===" + kubectl get svc -n ${{ env.NAMESPACE }} + + echo "=== Ingress ===" + kubectl get ingress -n ${{ env.NAMESPACE }} + + notify: + name: Notify Deployment Result + needs: [detect-changes, deploy] + runs-on: ubuntu-latest + if: always() + steps: + - name: Deployment Success + if: needs.deploy.result == 'success' + run: | + echo "✅ Deployment to ${{ needs.detect-changes.outputs.environment }} succeeded!" + echo "Services: ${{ needs.detect-changes.outputs.services }}" + + - name: Deployment Failure + if: needs.deploy.result == 'failure' + run: | + echo "❌ Deployment to ${{ needs.detect-changes.outputs.environment }} failed!" + echo "Services: ${{ needs.detect-changes.outputs.services }}" + exit 1 diff --git a/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java b/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java index 527e840..fed7c93 100644 --- a/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java +++ b/analytics-service/src/main/java/com/kt/event/analytics/config/SampleDataLoader.java @@ -166,7 +166,7 @@ public class SampleDataLoader implements ApplicationRunner { private void publishEventCreatedEvents() throws Exception { // 이벤트 1: 신년맞이 할인 이벤트 (진행중, 높은 성과) EventCreatedEvent event1 = EventCreatedEvent.builder() - .eventId("evt_2025012301") + .eventId("1") .eventTitle("신년맞이 20% 할인 이벤트") .storeId("store_001") .totalInvestment(new BigDecimal("5000000")) @@ -176,7 +176,7 @@ public class SampleDataLoader implements ApplicationRunner { // 이벤트 2: 설날 특가 이벤트 (진행중, 중간 성과) EventCreatedEvent event2 = EventCreatedEvent.builder() - .eventId("evt_2025020101") + .eventId("2") .eventTitle("설날 특가 선물세트 이벤트") .storeId("store_001") .totalInvestment(new BigDecimal("3500000")) @@ -186,7 +186,7 @@ public class SampleDataLoader implements ApplicationRunner { // 이벤트 3: 겨울 신메뉴 런칭 이벤트 (종료, 저조한 성과) EventCreatedEvent event3 = EventCreatedEvent.builder() - .eventId("evt_2025011501") + .eventId("3") .eventTitle("겨울 신메뉴 런칭 이벤트") .storeId("store_001") .totalInvestment(new BigDecimal("2000000")) @@ -201,7 +201,7 @@ public class SampleDataLoader implements ApplicationRunner { * DistributionCompleted 이벤트 발행 (설계서 기준 - 이벤트당 1번 발행, 여러 채널 배열) */ private void publishDistributionCompletedEvents() throws Exception { - String[] eventIds = {"evt_2025012301", "evt_2025020101", "evt_2025011501"}; + String[] eventIds = {"1", "2", "3"}; int[][] expectedViews = { {5000, 10000, 3000, 2000}, // 이벤트1: 우리동네TV, 지니TV, 링고비즈, SNS {3500, 7000, 2000, 1500}, // 이벤트2 @@ -263,7 +263,7 @@ public class SampleDataLoader implements ApplicationRunner { * ParticipantRegistered 이벤트 발행 */ private void publishParticipantRegisteredEvents() throws Exception { - String[] eventIds = {"evt_2025012301", "evt_2025020101", "evt_2025011501"}; + String[] eventIds = {"1", "2", "3"}; int[] totalParticipants = {100, 50, 30}; // MVP 테스트용 샘플 데이터 (총 180명) String[] channels = {"우리동네TV", "지니TV", "링고비즈", "SNS"}; @@ -306,7 +306,7 @@ public class SampleDataLoader implements ApplicationRunner { private void createTimelineData() { log.info("📊 TimelineData 생성 시작..."); - String[] eventIds = {"evt_2025012301", "evt_2025020101", "evt_2025011501"}; + String[] eventIds = {"1", "2", "3"}; // 각 이벤트별 기준 참여자 수 (이벤트 성과에 따라 다름) int[] baseParticipants = {20, 12, 5}; // 이벤트1(높음), 이벤트2(중간), 이벤트3(낮음)