diff --git a/.github/config/deploy_env_vars_ai-python_dev b/.github/config/deploy_env_vars_ai-python_dev new file mode 100644 index 0000000..ae8a229 --- /dev/null +++ b/.github/config/deploy_env_vars_ai-python_dev @@ -0,0 +1,3 @@ +# Development environment variables for ai-python service +resource_group=rg-digitalgarage-02 +cluster_name=aks-digitalgarage-02 diff --git a/.github/workflows/ai-python-cicd_ArgoCD.yaml b/.github/workflows/ai-python-cicd_ArgoCD.yaml new file mode 100644 index 0000000..8003d26 --- /dev/null +++ b/.github/workflows/ai-python-cicd_ArgoCD.yaml @@ -0,0 +1,221 @@ +name: AI-Python Service CI/CD + +on: + push: + branches: [ main, develop ] + paths: + - 'ai-python/**' + - '.github/workflows/ai-python-cicd_ArgoCD.yaml' + pull_request: + branches: [ main ] + workflow_dispatch: + inputs: + ENVIRONMENT: + description: 'Target environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + - prod + SKIP_TESTS: + description: 'Skip Tests' + required: false + default: 'false' + type: choice + options: + - 'false' + - 'true' + +env: + REGISTRY: acrdigitalgarage02.azurecr.io + IMAGE_ORG: hgzero + SERVICE_NAME: ai-python + RESOURCE_GROUP: rg-digitalgarage-02 + AKS_CLUSTER: aks-digitalgarage-02 + NAMESPACE: hgzero + +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 Python 3.13 + uses: actions/setup-python@v4 + with: + python-version: '3.13' + cache: 'pip' + cache-dependency-path: 'ai-python/requirements.txt' + + - name: Determine environment + id: determine_env + run: | + ENVIRONMENT="${{ github.event.inputs.ENVIRONMENT || 'dev' }}" + echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT + + - name: Load environment variables + id: env_vars + run: | + ENV=${{ steps.determine_env.outputs.environment }} + + REGISTRY="acrdigitalgarage02.azurecr.io" + IMAGE_ORG="hgzero" + RESOURCE_GROUP="rg-digitalgarage-02" + AKS_CLUSTER="aks-digitalgarage-02" + NAMESPACE="hgzero" + + if [[ -f ".github/config/deploy_env_vars_ai-python_${ENV}" ]]; then + while IFS= read -r line || [[ -n "$line" ]]; do + [[ "$line" =~ ^#.*$ ]] && continue + [[ -z "$line" ]] && continue + + key=$(echo "$line" | cut -d '=' -f1) + value=$(echo "$line" | cut -d '=' -f2-) + + case "$key" in + "resource_group") RESOURCE_GROUP="$value" ;; + "cluster_name") AKS_CLUSTER="$value" ;; + esac + done < ".github/config/deploy_env_vars_ai-python_${ENV}" + fi + + echo "REGISTRY=$REGISTRY" >> $GITHUB_ENV + echo "IMAGE_ORG=$IMAGE_ORG" >> $GITHUB_ENV + echo "RESOURCE_GROUP=$RESOURCE_GROUP" >> $GITHUB_ENV + echo "AKS_CLUSTER=$AKS_CLUSTER" >> $GITHUB_ENV + + - name: Install dependencies + run: | + cd ai-python + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Run Tests + env: + SKIP_TESTS: ${{ github.event.inputs.SKIP_TESTS || 'true' }} + run: | + if [[ "$SKIP_TESTS" == "true" ]]; then + echo "⏭️ Skipping Tests (SKIP_TESTS=$SKIP_TESTS)" + exit 0 + fi + + cd ai-python + # pytest가 requirements.txt에 있다면 실행 + if pip list | grep -q "pytest"; then + if [ -d "tests" ]; then + pytest tests/ --cov=app --cov-report=xml --cov-report=html || echo "⚠️ Tests failed but continuing" + else + echo "⚠️ No tests directory found, skipping tests" + fi + else + echo "⚠️ pytest not installed, skipping tests" + fi + + echo "✅ Tests completed successfully" + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: | + ai-python/htmlcov/ + ai-python/coverage.xml + + - 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 Image + needs: build + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set environment variables from build job + run: | + echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV + echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $GITHUB_ENV + echo "SERVICE_NAME=${{ env.SERVICE_NAME }}" >> $GITHUB_ENV + 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 + + - name: Login to Docker Hub (prevent rate limit) + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Login to Azure Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.ACR_USERNAME }} + password: ${{ secrets.ACR_PASSWORD }} + + - name: Build and push Docker image + run: | + echo "Building and pushing AI-Python service..." + docker build \ + -f deployment/container/Dockerfile-ai-python \ + -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} \ + ai-python/ + + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} + + echo "✅ Docker image pushed successfully" + + update-manifest: + name: Update Manifest Repository + needs: [build, release] + runs-on: ubuntu-latest + + steps: + - name: Set image tag environment variable + run: | + echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV + echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV + + - name: Update Manifest Repository + run: | + # 매니페스트 레포지토리 클론 + REPO_URL=$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||') + git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@${REPO_URL} manifest-repo + cd manifest-repo + + # Kustomize 설치 + curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash + sudo mv kustomize /usr/local/bin/ + + # 매니페스트 업데이트 + cd hgzero-back/kustomize/overlays/${{ env.ENVIRONMENT }} + + # AI-Python 서비스 이미지 태그 업데이트 + kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/ai-python:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }} + + # Git 설정 및 푸시 + cd ../../../.. + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + git add . + git commit -m "🚀 Update AI-Python ${{ env.ENVIRONMENT }} image to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}" + git push origin main + + echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다." diff --git a/.github/workflows/rag-cicd_ArgoCD.yaml b/.github/workflows/rag-cicd_ArgoCD.yaml index 45782b5..42a82c4 100644 --- a/.github/workflows/rag-cicd_ArgoCD.yaml +++ b/.github/workflows/rag-cicd_ArgoCD.yaml @@ -22,11 +22,11 @@ on: SKIP_TESTS: description: 'Skip Tests' required: false - default: 'true' + default: 'false' type: choice options: - - 'true' - 'false' + - 'true' env: REGISTRY: acrdigitalgarage02.azurecr.io @@ -48,10 +48,10 @@ jobs: - name: Check out code uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v4 with: - python-version: '3.11' + python-version: '3.13' cache: 'pip' cache-dependency-path: 'rag/requirements.txt' @@ -100,7 +100,7 @@ jobs: - name: Run Tests env: - SKIP_TESTS: ${{ github.event.inputs.SKIP_TESTS || 'true' }} + SKIP_TESTS: ${{ github.event.inputs.SKIP_TESTS || 'false' }} run: | if [[ "$SKIP_TESTS" == "true" ]]; then echo "⏭️ Skipping Tests (SKIP_TESTS=$SKIP_TESTS)" diff --git a/deployment/container/Dockerfile-ai-python b/deployment/container/Dockerfile-ai-python index 8e79dde..3f7a6c3 100644 --- a/deployment/container/Dockerfile-ai-python +++ b/deployment/container/Dockerfile-ai-python @@ -43,11 +43,11 @@ ENV PATH="/opt/venv/bin:$PATH" USER ${USERNAME} # Expose port -EXPOSE 8087 +EXPOSE 8080 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ - CMD python -c "import requests; requests.get('http://localhost:8087/health')" || exit 1 + CMD python -c "import requests; requests.get('http://localhost:8080/health')" || exit 1 # Run the application -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8087"] +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]