[Feat/19] 진행률 및 Redis pub/sub 연결 구현 #29
Workflow file for this run
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: Build and Deploy | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - master | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| workflow_dispatch: | |
| inputs: | |
| environment: | |
| description: 'Deployment environment' | |
| required: true | |
| default: 'production' | |
| type: choice | |
| options: | |
| - production | |
| env: | |
| AWS_REGION: ${{ secrets.AWS_REGION || 'ap-northeast-2' }} | |
| CODE_DEPLOY_APPLICATION_NAME: ${{ secrets.CODE_DEPLOY_APPLICATION_NAME }} | |
| CODE_DEPLOY_DEPLOYMENT_GROUP: ${{ secrets.CODE_DEPLOY_DEPLOYMENT_GROUP }} | |
| jobs: | |
| test: | |
| name: Run Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| cache: 'pip' | |
| - name: Verify Python version | |
| run: | | |
| python --version | |
| python -c "import sys; assert sys.version_info[:2] == (3, 10), f'Expected Python 3.10, got {sys.version}'" | |
| - name: Clean up disk space | |
| run: | | |
| # 디스크 공간 확인 | |
| df -h | |
| # pip 캐시 정리 | |
| pip cache purge || true | |
| # 기타 캐시 정리 | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /opt/ghc | |
| sudo rm -rf /usr/local/share/boost | |
| sudo rm -rf "$AGENT_TOOLSDIRECTORY" | |
| # 디스크 공간 재확인 | |
| df -h | |
| - name: Install numpy first (pre-built wheel) | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| python -m pip install --no-cache-dir --only-binary numpy "numpy>=1.26,<2.0" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --no-cache-dir --no-build-isolation -r echoshot_ai_server/requirements.txt | |
| - name: Install PyTorch (CPU for testing) | |
| run: | | |
| pip install --no-cache-dir torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1 | |
| # 테스트 비활성화화 | |
| # - name: Run tests | |
| # run: | | |
| # pytest echoshot_ai_server/ -v --tb=short || true | |
| # continue-on-error: true | |
| build-and-deploy: | |
| name: Build and Deploy | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} | |
| # 1) Docker Hub 로그인 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| # 2) 베이스 이미지 Pull (OpenCV CUDA 포함) | |
| - name: Pull base image | |
| run: | | |
| echo "베이스 이미지를 pull합니다..." | |
| docker pull ${{ secrets.DOCKERHUB_USERNAME }}/opencv-cuda-t4:4.10.0 || echo "베이스 이미지가 없습니다. 먼저 빌드해야 합니다." | |
| # 3) GPU 버전 Docker 이미지 빌드 (베이스 이미지 사용) | |
| - name: Build GPU Docker image | |
| run: | | |
| echo "GPU 버전 애플리케이션 이미지를 빌드합니다..." | |
| docker build \ | |
| --build-arg DOCKERHUB_USERNAME=${{ secrets.DOCKERHUB_USERNAME }} \ | |
| --build-arg OPENCV_VERSION=4.10.0 \ | |
| -t ${{ secrets.DOCKERHUB_USERNAME }}/echoshot-worker:gpu-fsrcnn-t4 \ | |
| -t ${{ secrets.DOCKERHUB_USERNAME }}/echoshot-worker:latest \ | |
| . | |
| # 4) Docker Hub로 푸시 | |
| - name: Push Docker images | |
| run: | | |
| echo "이미지를 Docker Hub에 푸시합니다..." | |
| docker push ${{ secrets.DOCKERHUB_USERNAME }}/echoshot-worker:gpu-fsrcnn-t4 | |
| docker push ${{ secrets.DOCKERHUB_USERNAME }}/echoshot-worker:latest | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Create deployment package | |
| run: | | |
| # 서브모듈 초기화 확인 | |
| if [ -d "EchoShotX-ai-private" ]; then | |
| echo "서브모듈이 확인되었습니다." | |
| ls -la EchoShotX-ai-private/ | |
| else | |
| echo "WARNING: 서브모듈이 없습니다." | |
| fi | |
| mkdir -p deploy-package | |
| cp -r echoshot_ai_server deploy-package/ | |
| cp -r scripts deploy-package/ | |
| cp -r EchoShotX-ai-private deploy-package/ # 서브모듈 포함 | |
| cp appspec.yml deploy-package/ | |
| cp Dockerfile deploy-package/ | |
| cp docker-compose.yml deploy-package/ # Docker Compose 파일 포함 | |
| cd deploy-package | |
| zip -r ../deploy-package.zip . | |
| cd .. | |
| - name: Upload to S3 | |
| run: | | |
| # S3 버킷 이름 설정 (Secret이 있으면 사용, 없으면 자동 생성) | |
| if [ -n "${{ secrets.CODEDEPLOY_S3_BUCKET }}" ]; then | |
| S3_BUCKET="${{ secrets.CODEDEPLOY_S3_BUCKET }}" | |
| else | |
| S3_BUCKET="codedeploy-echoshot-$(echo ${{ env.AWS_REGION }} | tr -d '-')" | |
| # S3 버킷이 없으면 생성 (선택적) | |
| aws s3 mb s3://$S3_BUCKET --region ${{ env.AWS_REGION }} || true | |
| fi | |
| S3_KEY="deployments/echoshot-worker/${{ github.sha }}.zip" | |
| # 배포 패키지 업로드 | |
| aws s3 cp deploy-package.zip s3://$S3_BUCKET/$S3_KEY | |
| echo "S3_BUCKET=$S3_BUCKET" >> $GITHUB_ENV | |
| echo "S3_KEY=$S3_KEY" >> $GITHUB_ENV | |
| - name: Create CodeDeploy deployment | |
| id: create-deployment | |
| run: | | |
| DEPLOYMENT_ID=$(aws deploy create-deployment \ | |
| --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \ | |
| --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP }} \ | |
| --s3-location bucket=${{ env.S3_BUCKET }},key=${{ env.S3_KEY }},bundleType=zip \ | |
| --query 'deploymentId' \ | |
| --output text) | |
| echo "deployment_id=$DEPLOYMENT_ID" >> $GITHUB_OUTPUT | |
| echo "Deployment created: $DEPLOYMENT_ID" | |
| - name: Wait for deployment | |
| run: | | |
| DEPLOYMENT_ID="${{ steps.create-deployment.outputs.deployment_id }}" | |
| MAX_WAIT=1800 # 30분 | |
| ELAPSED=0 | |
| INTERVAL=30 | |
| while [ $ELAPSED -lt $MAX_WAIT ]; do | |
| STATUS=$(aws deploy get-deployment \ | |
| --deployment-id $DEPLOYMENT_ID \ | |
| --query 'deploymentInfo.status' \ | |
| --output text) | |
| echo "Deployment status: $STATUS" | |
| if [ "$STATUS" = "Succeeded" ]; then | |
| echo "Deployment succeeded!" | |
| exit 0 | |
| elif [ "$STATUS" = "Failed" ] || [ "$STATUS" = "Stopped" ]; then | |
| echo "Deployment failed!" | |
| exit 1 | |
| fi | |
| sleep $INTERVAL | |
| ELAPSED=$((ELAPSED + INTERVAL)) | |
| done | |
| echo "Deployment timeout!" | |
| exit 1 | |