mirror of
https://github.com/cna-bootcamp/phonebill.git
synced 2025-12-06 08:06:24 +00:00
- ArgoCD 워크플로우 파일 삭제 (backend-cicd_ArgoCD.yaml) - Kustomize base/overlays 설정 업데이트 - GitHub Actions 백엔드 CI/CD 파이프라인 개선 - 각 서비스 deployment 및 secret 설정 수정 - Docker 이미지 풀 시크릿을 플레이스홀더로 변경 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
263 lines
10 KiB
YAML
263 lines
10 KiB
YAML
name: Backend Services CI/CD (Generic K8s)
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, develop ]
|
|
paths:
|
|
- 'api-gateway/**'
|
|
- 'user-service/**'
|
|
- 'bill-service/**'
|
|
- 'product-service/**'
|
|
- 'kos-mock/**'
|
|
- 'common/**'
|
|
- '.github/**'
|
|
pull_request:
|
|
branches: [ main ]
|
|
|
|
env:
|
|
# ============================================
|
|
# 변경: Azure ACR → Docker Hub
|
|
# ============================================
|
|
REGISTRY: docker.io
|
|
IMAGE_ORG: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
NAMESPACE: phonebill
|
|
|
|
# SSH 터널링용
|
|
MINIKUBE_IP: "192.168.49.2"
|
|
|
|
jobs:
|
|
build:
|
|
name: Build and Test
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
image_tag: ${{ steps.set_outputs.outputs.image_tag }}
|
|
environment: ${{ steps.set_outputs.outputs.environment }}
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up JDK 21
|
|
uses: actions/setup-java@v3
|
|
with:
|
|
java-version: '21'
|
|
distribution: 'temurin'
|
|
cache: 'gradle'
|
|
|
|
- name: Determine environment
|
|
id: determine_env
|
|
run: |
|
|
# workflow_dispatch 입력값 우선, 없으면 vars 사용
|
|
ENVIRONMENT="${{ vars.ENVIRONMENT || 'dev' }}"
|
|
echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT
|
|
|
|
- name: Grant execute permission for gradlew
|
|
run: chmod +x gradlew
|
|
|
|
- name: Build with Gradle
|
|
run: |
|
|
./gradlew build -x test
|
|
|
|
- name: SonarQube Analysis & Quality Gate
|
|
if: ${{ vars.SKIP_SONARQUBE != 'true' }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
|
run: |
|
|
# Define services array
|
|
services=(api-gateway user-service bill-service product-service kos-mock)
|
|
|
|
# Run tests, coverage reports, and SonarQube analysis for each service
|
|
for service in "${services[@]}"; do
|
|
./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \
|
|
-Dsonar.projectKey=phonebill-$service-${{ steps.determine_env.outputs.environment }} \
|
|
-Dsonar.projectName=phonebill-$service-${{ steps.determine_env.outputs.environment }} \
|
|
-Dsonar.host.url=$SONAR_HOST_URL \
|
|
-Dsonar.token=$SONAR_TOKEN \
|
|
-Dsonar.java.binaries=build/classes/java/main \
|
|
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \
|
|
-Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/**
|
|
done
|
|
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: app-builds
|
|
path: |
|
|
api-gateway/build/libs/*.jar
|
|
user-service/build/libs/*.jar
|
|
bill-service/build/libs/*.jar
|
|
product-service/build/libs/*.jar
|
|
kos-mock/build/libs/*.jar
|
|
|
|
- name: Set outputs
|
|
id: set_outputs
|
|
run: |
|
|
IMAGE_TAG=$(date +%Y%m%d%H%M%S)
|
|
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
|
echo "environment=${{ steps.determine_env.outputs.environment }}" >> $GITHUB_OUTPUT
|
|
|
|
release:
|
|
name: Build and Push Docker Images
|
|
needs: build
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: app-builds
|
|
|
|
- name: Set environment variables from build job
|
|
run: |
|
|
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
|
|
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
# ============================================
|
|
# 변경: Docker Hub 로그인만 사용
|
|
# ============================================
|
|
- name: Login to Docker Hub
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
|
|
|
- name: Build and push Docker images for all services
|
|
run: |
|
|
# Define services array
|
|
services=(api-gateway user-service bill-service product-service kos-mock)
|
|
|
|
# Build and push each service image
|
|
for service in "${services[@]}"; do
|
|
echo "Building and pushing $service..."
|
|
docker build \
|
|
--build-arg BUILD_LIB_DIR="$service/build/libs" \
|
|
--build-arg ARTIFACTORY_FILE="$service.jar" \
|
|
-f deployment/container/Dockerfile-backend \
|
|
-t ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} \
|
|
-t ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/$service:${{ needs.build.outputs.environment }}-latest .
|
|
|
|
docker push ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
|
|
docker push ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/$service:${{ needs.build.outputs.environment }}-latest
|
|
done
|
|
|
|
deploy:
|
|
name: Deploy to Kubernetes
|
|
needs: [build, release]
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set environment variables
|
|
run: |
|
|
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
|
|
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
|
|
|
|
# ============================================
|
|
# 변경: Azure CLI/Login 제거 → SSH 터널링
|
|
# ============================================
|
|
- name: Setup SSH key
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.VM_SSH_KEY }}" > ~/.ssh/vm_key
|
|
chmod 600 ~/.ssh/vm_key
|
|
ssh-keyscan -H ${{ secrets.VM_IP }} >> ~/.ssh/known_hosts 2>/dev/null || true
|
|
|
|
- name: Create SSH tunnel to Minikube
|
|
run: |
|
|
ssh -i ~/.ssh/vm_key \
|
|
-o StrictHostKeyChecking=no \
|
|
-o ServerAliveInterval=60 \
|
|
-L 8443:${{ env.MINIKUBE_IP }}:8443 \
|
|
${{ secrets.VM_USER }}@${{ secrets.VM_IP }} -N &
|
|
|
|
sleep 5
|
|
echo "✅ SSH tunnel established"
|
|
|
|
# ============================================
|
|
# 변경: az aks get-credentials → KUBECONFIG Secret
|
|
# ============================================
|
|
- name: Setup kubectl
|
|
uses: azure/setup-kubectl@v3
|
|
|
|
- name: Configure kubectl via KUBECONFIG
|
|
run: |
|
|
mkdir -p $HOME/.kube
|
|
echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config
|
|
chmod 600 $HOME/.kube/config
|
|
|
|
# server 주소를 localhost:8443으로 변경 (SSH 터널 통해 접근)
|
|
sed -i 's|server:.*|server: https://127.0.0.1:8443|g' $HOME/.kube/config
|
|
|
|
- name: Verify cluster connection
|
|
run: |
|
|
kubectl cluster-info
|
|
kubectl get nodes
|
|
|
|
- name: Create namespace
|
|
run: |
|
|
kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
# ============================================
|
|
# 추가: Docker Hub pull secret 생성
|
|
# ============================================
|
|
- name: Create image pull secret
|
|
run: |
|
|
kubectl create secret docker-registry dockerhub-secret \
|
|
--docker-server=docker.io \
|
|
--docker-username=${{ secrets.DOCKERHUB_USERNAME }} \
|
|
--docker-password=${{ secrets.DOCKERHUB_PASSWORD }} \
|
|
--namespace=${{ env.NAMESPACE }} \
|
|
--dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
- name: Install Kustomize
|
|
run: |
|
|
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
|
sudo mv kustomize /usr/local/bin/
|
|
|
|
- name: Update Kustomize images and deploy
|
|
run: |
|
|
cd .github/kustomize/overlays/${{ env.ENVIRONMENT }}
|
|
|
|
# ============================================
|
|
# 변경: 이미지 경로를 Docker Hub로
|
|
# ============================================
|
|
kustomize edit set image ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/api-gateway:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
|
kustomize edit set image ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/user-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
|
kustomize edit set image ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/bill-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
|
kustomize edit set image ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/product-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
|
kustomize edit set image ${{ env.REGISTRY }}/${{ secrets.DOCKERHUB_USERNAME }}/kos-mock:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
|
|
|
kubectl apply -k .
|
|
|
|
- name: Wait for deployments to be ready
|
|
run: |
|
|
echo "Waiting for deployments to be ready..."
|
|
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/api-gateway --timeout=300s
|
|
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/user-service --timeout=300s
|
|
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/bill-service --timeout=300s
|
|
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/product-service --timeout=300s
|
|
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/kos-mock --timeout=300s
|
|
|
|
- name: Show deployment status
|
|
run: |
|
|
kubectl -n ${{ env.NAMESPACE }} get pods -o wide
|
|
kubectl -n ${{ env.NAMESPACE }} get svc
|
|
|
|
# ============================================
|
|
# 추가: SSH 터널 정리
|
|
# ============================================
|
|
- name: Cleanup SSH tunnel
|
|
if: always()
|
|
run: |
|
|
pkill -f "ssh.*8443" || true
|