diff --git a/.github/.DS_Store b/.github/.DS_Store new file mode 100644 index 0000000..0ff23cb Binary files /dev/null and b/.github/.DS_Store differ diff --git a/.github/workflows/.DS_Store b/.github/workflows/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.github/workflows/.DS_Store differ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 495c210..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,159 +0,0 @@ -name: CI/CD Pipeline - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - GCP_REGION: ${{ secrets.GCP_REGION }} - PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} - GKE_CLUSTER: ${{ secrets.GKE_CLUSTER }} - GKE_ZONE: ${{ secrets.GKE_ZONE }} - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - service: - - telegram_bot_service - - translation_service - - transport_service - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.9' - - - name: Install dependencies - working-directory: ${{ matrix.service }} - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pytest pytest-cov pylint - - - name: Run linter - working-directory: ${{ matrix.service }} - run: | - pylint **/*.py || true # Не прерывать workflow при линтинге - - - name: Run tests - working-directory: ${{ matrix.service }} - run: | - pytest --cov=./ --cov-report=xml - - - name: Upload coverage - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} - file: ${{ matrix.service }}/coverage.xml - flags: ${{ matrix.service }} - - build-and-deploy: - needs: test - runs-on: ubuntu-latest - strategy: - matrix: - service: - - telegram-bot-service - - translation-service - - transport-service - steps: - - uses: actions/checkout@v4 - - - name: Google Auth - id: auth - uses: google-github-actions/auth@v2 - with: - credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2 - - - name: Configure Docker - run: | - gcloud auth configure-docker ${{ env.GCP_REGION }}-docker.pkg.dev - - - name: Build and Push Docker Image - env: - SERVICE_NAME: ${{ matrix.service }} - TELEGRAM_REPO_NAME: telegram-bot - TRANSLATION_REPO_NAME: translation-service - TRANSPORT_REPO_NAME: transport-service - run: | - # Определяем директорию проекта - case "${{ matrix.service }}" in - "telegram-bot-service") - SERVICE_DIR="telegram_bot_service" - REPO_NAME=$TELEGRAM_REPO_NAME - ;; - "translation-service") - SERVICE_DIR="translation_service" - REPO_NAME=$TRANSLATION_REPO_NAME - ;; - "transport-service") - SERVICE_DIR="transport_service" - REPO_NAME=$TRANSPORT_REPO_NAME - ;; - *) - echo "Unknown service: ${{ matrix.service }}" - exit 1 - ;; - esac - - docker build -t ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/$REPO_NAME/${{ matrix.service }}:${{ github.sha }} ./$SERVICE_DIR - docker push ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/$REPO_NAME/${{ matrix.service }}:${{ github.sha }} - - - name: Install gke-gcloud-auth-plugin - run: | - sudo apt-get update - sudo apt-get install -y apt-transport-https ca-certificates gnupg - echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - - sudo apt-get update && sudo apt-get install -y google-cloud-sdk-gke-gcloud-auth-plugin - - - name: Deploy to GKE - env: - SERVICE_NAME: ${{ matrix.service }} - run: | - gcloud container clusters get-credentials ${{ env.GKE_CLUSTER }} --region ${{ env.GKE_ZONE }} - - # Динамическая подстановка переменных в манифест - sed -i "s/\${PROJECT_ID}/${{ env.PROJECT_ID }}/g" k8s/${{ matrix.service }}/deployment.yaml - sed -i "s/\${GITHUB_SHA}/${{ github.sha }}/g" k8s/${{ matrix.service }}/deployment.yaml - - kubectl apply -f k8s/${{ matrix.service }}/ - - security-scan: - needs: build-and-deploy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - scan-type: 'fs' - ignore-unfixed: true - format: 'sarif' - output: 'trivy-results.sarif' - severity: 'CRITICAL,HIGH' - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: 'trivy-results.sarif' - - notify: - if: failure() - needs: [test, build-and-deploy, security-scan] - runs-on: ubuntu-latest - steps: - - name: Notify Failure - run: | - echo "CI/CD Pipeline failed. Check GitHub Actions for details." - # Можно добавить отправку email или webhook \ No newline at end of file diff --git a/.github/workflows/create-artifact-repositories.yml b/.github/workflows/create-artifact-repositories.yml deleted file mode 100644 index a0d8abb..0000000 --- a/.github/workflows/create-artifact-repositories.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Create Artifact Repositories - -on: - workflow_dispatch: - inputs: - region: - description: 'GCP Region' - required: true - default: 'europe-west12' - project_id: - description: 'GCP Project ID' - required: true - -jobs: - create-repositories: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Google Auth - id: auth - uses: google-github-actions/auth@v2 - with: - credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v2 - - - name: Create Artifact Repositories - env: - GCP_REGION: ${{ inputs.region || secrets.GCP_REGION }} - GCP_PROJECT_ID: ${{ inputs.project_id || secrets.GCP_PROJECT_ID }} - run: | - # Список репозиториев - REPOSITORIES=( - "telegram-bot-service" - "translation-service" - "transport-service" - "database-service" - "monitoring-service" - ) - - # Создание репозиториев с расширенной конфигурацией - for repo in "${REPOSITORIES[@]}"; do - echo "Creating repository: $repo" - gcloud artifacts repositories create "$repo" \ - --repository-format=docker \ - --location="$GCP_REGION" \ - --project="$GCP_PROJECT_ID" \ - --description="Docker repository for $repo" \ - --labels=service="$repo",managed-by="github-actions" - done - - - name: Configure Docker Auth - env: - GCP_REGION: ${{ inputs.region || secrets.GCP_REGION }} - run: | - gcloud auth configure-docker "$GCP_REGION-docker.pkg.dev" - - - name: Verify Repositories - env: - GCP_REGION: ${{ inputs.region || secrets.GCP_REGION }} - GCP_PROJECT_ID: ${{ inputs.project_id || secrets.GCP_PROJECT_ID }} - run: | - gcloud artifacts repositories list \ - --location="$GCP_REGION" \ - --project="$GCP_PROJECT_ID" - - - name: Set IAM Permissions - env: - GCP_REGION: ${{ inputs.region || secrets.GCP_REGION }} - GCP_PROJECT_ID: ${{ inputs.project_id || secrets.GCP_PROJECT_ID }} - run: | - # Получаем email сервисного аккаунта GitHub Actions - SERVICE_ACCOUNT_EMAIL=$(gcloud config get-value account) - - # Список репозиториев - REPOSITORIES=( - "telegram-bot-service" - "translation-service" - "transport-service" - "database-service" - "monitoring-service" - ) - - # Назначаем роли для каждого репозитория - for repo in "${REPOSITORIES[@]}"; do - gcloud artifacts repositories add-iam-policy-binding "$repo" \ - --location="$GCP_REGION" \ - --project="$GCP_PROJECT_ID" \ - --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \ - --role="roles/artifactregistry.writer" - done \ No newline at end of file diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml deleted file mode 100644 index 9ad34a8..0000000 --- a/.github/workflows/docker-build.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Docker Build and Push - -on: - push: - branches: [ main ] - paths: - - 'telegram_bot_service/**' - - 'translation_service/**' - - 'transport_service/**' - - '.github/workflows/docker-build.yml' - - workflow_dispatch: - inputs: - service: - description: 'Service to build' - required: true - type: choice - options: - - telegram_bot_service - - translation_service - - transport_service - -jobs: - build-and-push: - runs-on: ubuntu-latest - - strategy: - matrix: - service: - - telegram_bot_service - - translation_service - - transport_service - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Google Auth - id: auth - uses: google-github-actions/auth@v2 - with: - credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - - - name: Login to Google Artifact Registry - uses: docker/login-action@v2 - with: - registry: ${{ secrets.GCP_REGION }}-docker.pkg.dev - username: _json_key - password: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - - - name: Build and push to Docker Hub - uses: docker/build-push-action@v6 - with: - context: ./${{ matrix.service }} - push: true - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.service }}:latest - ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.service }}:${{ github.sha }} - - - name: Build and push to Google Artifact Registry - uses: docker/build-push-action@v6 - with: - context: ./${{ matrix.service }} - push: true - tags: | - europe-west12-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.service }}/${{ matrix.service }}:latest - europe-west12-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.service }}/${{ matrix.service }}:${{ github.sha }} \ No newline at end of file diff --git a/.github/workflows/gcp-deploy.yml b/.github/workflows/gcp-deploy.yml index e63afa0..4aaccce 100644 --- a/.github/workflows/gcp-deploy.yml +++ b/.github/workflows/gcp-deploy.yml @@ -2,73 +2,43 @@ name: Deploy to Google Cloud Run on: push: - branches: [ main ] - paths: - - 'telegram_bot_service/**' - - 'translation_service/**' - - 'transport_service/**' - - '.github/workflows/gcp-deploy.yml' - - '.github/workflows/docker-build.yml' + branches: + - main - workflow_dispatch: - inputs: - service: - description: 'Service to deploy' - required: true - type: choice - options: - - telegram_bot_service - - translation_service - - transport_service +env: + GCP_REGION: ${{ secrets.GCP_REGION }} + PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} + GKE_CLUSTER: ${{ secrets.GKE_CLUSTER_NAME }} + GKE_ZONE: ${{ secrets.GKE_ZONE }} jobs: - test: + build-and-deploy: runs-on: ubuntu-latest - strategy: - matrix: - service: - - telegram_bot_service - - translation_service - - transport_service - - steps: - - uses: actions/checkout@v4 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v4 with: python-version: '3.9' - + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest - pip install -r ${{ matrix.service }}/requirements.txt - - - name: Run tests - run: | - cd ${{ matrix.service }} - if [ -d "tests" ]; then - pytest tests/ - else - echo "No tests directory found for ${{ matrix.service }}" - fi - - deploy: - needs: test - runs-on: ubuntu-latest - strategy: - matrix: - service: - - telegram_bot_service - - translation_service - - transport_service + pip install pytest pytest-cov - steps: - - uses: actions/checkout@v4 + # Тестирование всех сервисов + - name: Run Tests + run: | + # Запуск тестов для каждого сервиса + cd transport_service && pytest + cd ../translation_service && pytest + cd ../telegram_bot_service && pytest - - name: Google Auth - id: auth + # Авторизация в Google Cloud + - name: Google Cloud Auth uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} @@ -78,35 +48,61 @@ jobs: - name: Configure Docker run: | - gcloud auth configure-docker ${{ secrets.GCP_REGION }}-docker.pkg.dev + gcloud auth configure-docker ${{ env.GCP_REGION }}-docker.pkg.dev + + # Сборка и публикация Docker-образов для каждого сервиса + - name: Build and Push Transport Service + run: | + cd transport_service + docker build -t ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/transport-service/service:${{ github.sha }} . + docker push ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/transport-service/service:${{ github.sha }} + + - name: Build and Push Translation Service + run: | + cd translation_service + docker build -t ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/translation-service/service:${{ github.sha }} . + docker push ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/translation-service/service:${{ github.sha }} - - name: Build Docker Image + - name: Build and Push Telegram Bot Service run: | - docker build -t ${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.service }}/service:${{ github.sha }} ./${{ matrix.service }} + cd telegram_bot_service + docker build -t ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/telegram-bot-service/service:${{ github.sha }} . + docker push ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/telegram-bot-service/service:${{ github.sha }} - - name: Push to Artifact Registry + # Деплой в Cloud Run (если применимо) + - name: Deploy to Cloud Run Transport Service run: | - docker push ${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.service }}/service:${{ github.sha }} + # Пример деплоя транспортного сервиса + gcloud run deploy transport-service \ + --image ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/transport-service/service:${{ github.sha }} \ + --platform managed \ + --region ${{ env.GCP_REGION }} \ + --allow-unauthenticated - - name: Deploy to Cloud Run + - name: Deploy to Cloud Run Translation Service run: | - SERVICE_NAME=$(echo "${{ matrix.service }}" | sed 's/_/-/g') - - case "${{ matrix.service }}" in - telegram_bot_service) - ENV_VARS="TELEGRAM_BOT_TOKEN=${{ secrets.TELEGRAM_BOT_TOKEN }}" - ;; - translation_service) - ENV_VARS="OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" - ;; - transport_service) - ENV_VARS="" - ;; - esac + # Пример деплоя транспортного сервиса + gcloud run deploy translation-service \ + --image ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/translation-service/service:${{ github.sha }} \ + --platform managed \ + --region ${{ env.GCP_REGION }} \ + --allow-unauthenticated \ + --port 8080 \ + --cpu 1 \ + --memory 512Mi \ + --max-instances 3 \ + --set-env-vars "DATABASE_URL=${{ secrets.DATABASE_URL }}" - gcloud run deploy $SERVICE_NAME \ - --image ${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.service }}/service:${{ github.sha }} \ + - name: Deploy to Cloud Run Telegram Bot Service + run: | + # Пример деплоя транспортного сервиса + gcloud run deploy telegram-bot \ + --image ${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/telegram-bot-service/service:${{ github.sha }} \ --platform managed \ - --region ${{ secrets.GCP_REGION }} \ + --region ${{ env.GCP_REGION }} \ --allow-unauthenticated \ - ${ENV_VARS:+ --set-env-vars $ENV_VARS} \ No newline at end of file + --port 8080 \ + --cpu 1 \ + --memory 512Mi \ + --max-instances 3 \ + --set-env-vars "TRANSPORT_SERVICE_URL=${{ secrets.TRANSPORT_SERVICE_URL }},TELEGRAM_BOT_TOKEN=${{ secrets.TELEGRAM_BOT_TOKEN }}" \ No newline at end of file diff --git a/telegram_bot_service/__init__.py b/telegram_bot_service/__init__.py new file mode 100644 index 0000000..d5861df --- /dev/null +++ b/telegram_bot_service/__init__.py @@ -0,0 +1 @@ +from .config import * \ No newline at end of file diff --git a/telegram_bot_service/handlers/message_handler.py b/telegram_bot_service/handlers/message_handler.py index 24c13aa..7f6c763 100644 --- a/telegram_bot_service/handlers/message_handler.py +++ b/telegram_bot_service/handlers/message_handler.py @@ -1,3 +1,8 @@ +""" +Модуль обработки входящих сообщений в Telegram боте. + +Содержит асинхронную функцию обработки сообщений от пользователей. +""" from telegram import Update from telegram.ext import CallbackContext import httpx @@ -6,7 +11,14 @@ logger = get_logger(__name__) -async def handle_message(update: Update, context: CallbackContext): +async def handle_message(update: Update, context: CallbackContext) -> None: + """ + Асинхронная функция обработки входящего сообщения. + + Args: + update (Update): Объект обновления от Telegram. + context (CallbackContext): Контекст выполнения. + """ try: message = update.message.text user_id = update.effective_user.id diff --git a/translation_service/__init__.py b/translation_service/__init__.py new file mode 100644 index 0000000..d5861df --- /dev/null +++ b/translation_service/__init__.py @@ -0,0 +1 @@ +from .config import * \ No newline at end of file diff --git a/translation_service/test/test_translation.py b/translation_service/tests/test_translation.py similarity index 100% rename from translation_service/test/test_translation.py rename to translation_service/tests/test_translation.py diff --git a/transport_service/__init__.py b/transport_service/__init__.py new file mode 100644 index 0000000..d5861df --- /dev/null +++ b/transport_service/__init__.py @@ -0,0 +1 @@ +from .config import * \ No newline at end of file diff --git a/transport_service/test/test_transport.py b/transport_service/tests/test_transport.py similarity index 100% rename from transport_service/test/test_transport.py rename to transport_service/tests/test_transport.py