Refactor : Change all String columns to TEXT type (#46) #47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD to NKS (IAM) | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| tags: | |
| - "v*" | |
| env: | |
| REGISTRY: docker.io | |
| REGISTRY_NAMESPACE: 3759357 | |
| NAMESPACE: babo | |
| REGION: KR | |
| SERVICES: "auth,gateway,review,tour,util" | |
| jobs: | |
| build: | |
| name: Build & Push (${{ matrix.service }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| service: [auth, gateway, review, tour, util] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| driver: docker-container | |
| install: true | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| cache: gradle | |
| - name: Build jar for ${{ matrix.service }} | |
| run: | | |
| chmod +x ./gradlew | |
| ./gradlew :${{ matrix.service }}:bootJar --no-daemon -x test | |
| ls -al ${{ matrix.service }}/build/libs || true | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.REGISTRY_USERNAME }} | |
| password: ${{ secrets.REGISTRY_TOKEN }} | |
| - name: Build & Push ${{ matrix.service }} | |
| if: ${{ hashFiles(format('docker/Dockerfile.{0}', matrix.service)) != '' }} | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: docker/Dockerfile.${{ matrix.service }} | |
| push: true | |
| tags: | | |
| ${{ env.REGISTRY_NAMESPACE }}/${{ matrix.service }}:latest | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| deploy: | |
| name: Deploy to NKS (babo namespace) | |
| runs-on: ubuntu-latest | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| service: [auth, gateway, review, tour, util] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install kubectl | |
| uses: azure/setup-kubectl@v4 | |
| - name: Install ncp-iam-authenticator | |
| run: | | |
| curl -fsSL -o ncp-iam-authenticator \ | |
| https://github.com/NaverCloudPlatform/ncp-iam-authenticator/releases/latest/download/ncp-iam-authenticator_linux_amd64 | |
| chmod +x ncp-iam-authenticator | |
| sudo mv ncp-iam-authenticator /usr/local/bin/ncp-iam-authenticator | |
| - name: Generate/Update kubeconfig via IAM | |
| env: | |
| NCLOUD_ACCESS_KEY: ${{ secrets.NCP_ACCESS_KEY }} | |
| NCLOUD_SECRET_KEY: ${{ secrets.NCP_SECRET_KEY }} | |
| NCLOUD_API_GW: https://ncloud.apigw.ntruss.com | |
| run: | | |
| mkdir -p $HOME/.kube | |
| ncp-iam-authenticator update-kubeconfig \ | |
| --region "${{ env.REGION }}" \ | |
| --clusterUuid "${{ secrets.CLUSTER_UUID }}" \ | |
| --overwrite \ | |
| --kubeconfig "$HOME/.kube/config" | |
| chmod 600 $HOME/.kube/config | |
| - name: Export NCP creds to job env | |
| run: | | |
| echo "NCLOUD_ACCESS_KEY=${{ secrets.NCP_ACCESS_KEY }}" >> $GITHUB_ENV | |
| echo "NCLOUD_SECRET_KEY=${{ secrets.NCP_SECRET_KEY }}" >> $GITHUB_ENV | |
| echo "NCLOUD_API_GW=https://ncloud.apigw.ntruss.com" >> $GITHUB_ENV | |
| - name: Create ~/.ncloud/configure | |
| run: | | |
| mkdir -p $HOME/.ncloud | |
| cat > $HOME/.ncloud/configure <<'EOF' | |
| [DEFAULT] | |
| ncloud_access_key_id = ${NCLOUD_ACCESS_KEY} | |
| ncloud_secret_access_key = ${NCLOUD_SECRET_KEY} | |
| ncloud_api_url = https://ncloud.apigw.ntruss.com | |
| EOF | |
| chmod 600 $HOME/.ncloud/configure | |
| - name: Deploy ${{ matrix.service }} to ${{ env.NAMESPACE }} | |
| env: | |
| NS: ${{ env.NAMESPACE }} | |
| REGNS: ${{ env.REGISTRY_NAMESPACE }} | |
| run: | | |
| set -e | |
| SVC="${{ matrix.service }}" | |
| # 1) 매니페스트 자동 탐색 | |
| MANIFEST="$(ls -1 \ | |
| k8s/${SVC}.yaml \ | |
| k8s/${SVC}-deployment.yaml \ | |
| k8s/${SVC}.yml 2>/dev/null | head -n1 || true)" | |
| if [ -z "$MANIFEST" ]; then | |
| echo "⚠️ No manifest for '$SVC'. Skip." | |
| exit 0 | |
| fi | |
| echo "=== Applying $MANIFEST to namespace: $NS ===" | |
| set +e | |
| kubectl apply -f "$MANIFEST" -n "$NS" --v=3 | |
| APPLY_RC=$? | |
| set -e | |
| # 2) immutable selector 자동 처리 | |
| if [ $APPLY_RC -ne 0 ]; then | |
| echo "apply failed (rc=$APPLY_RC). checking immutable..." | |
| if kubectl apply -f "$MANIFEST" -n "$NS" 2>&1 | grep -qi "field is immutable"; then | |
| echo "🔁 Recreate deployment/$SVC" | |
| kubectl delete deploy/$SVC -n "$NS" --wait=true || true | |
| kubectl apply -f "$MANIFEST" -n "$NS" | |
| else | |
| exit $APPLY_RC | |
| fi | |
| fi | |
| # 3) 컨테이너 이름 감지 + 이미지 최신화 | |
| CNAME="$(kubectl get deploy/$SVC -n "$NS" -o jsonpath='{.spec.template.spec.containers[0].name}')" | |
| IMAGE="${REGNS}/${SVC}:latest" | |
| echo "=== Setting image: $CNAME -> $IMAGE ===" | |
| kubectl set image deploy/${SVC} ${CNAME}=${IMAGE} -n "$NS" | |
| # 4) 강제 스펙 변경으로 롤아웃 트리거 | |
| kubectl annotate deploy/${SVC} ci-run=${{ github.sha }} -n "$NS" --overwrite | |
| kubectl rollout restart deploy/${SVC} -n "$NS" | |
| kubectl rollout status deploy/${SVC} -n "$NS" --timeout=180s | |
| # 5) 검증 + 자가치유(필요 시) | |
| echo "--- VERIFY IMAGE/PODS/ENDPOINTS ---" | |
| echo "[deploy image]" | |
| kubectl get deploy/$SVC -n "$NS" -o jsonpath='{.spec.template.spec.containers[*].image}{"\n"}' | |
| echo "[pods -> imageID]" | |
| kubectl get pods -n "$NS" -l app=$SVC -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.status.containerStatuses[0].image}{" ("}{.status.containerStatuses[0].imageID}{")\n"}{end}' || true | |
| echo "[endpoints]" | |
| kubectl get endpoints $SVC -n "$NS" -o wide || true | |
| ACTUAL="$(kubectl get pods -n "$NS" -l app=$SVC -o jsonpath='{.items[0].status.containerStatuses[0].image}' 2>/dev/null || true)" | |
| if [ -n "$ACTUAL" ] && [ "$ACTUAL" != "$IMAGE" ]; then | |
| echo "❌ Pod still using '$ACTUAL' (want '$IMAGE'). Forcing replace..." | |
| kubectl delete pod -n "$NS" -l app=$SVC --wait=true | |
| kubectl rollout status deploy/${SVC} -n "$NS" --timeout=180s | |
| echo "[pods after replace]" | |
| kubectl get pods -n "$NS" -l app=$SVC -o jsonpath='{range .items[*]}{.metadata.name}{" -> "}{.status.containerStatuses[0].image}{" ("}{.status.containerStatuses[0].imageID}{")\n"}{end}' || true | |
| fi | |
| echo "=== Deployed ${SVC} → ${IMAGE} ===" |