diff --git a/.github/workflows/deploy.yml.disabled b/.github/workflows/deploy.yml.disabled deleted file mode 100644 index 376d1a6..0000000 --- a/.github/workflows/deploy.yml.disabled +++ /dev/null @@ -1,151 +0,0 @@ -name: Deploy - -# Secrets necessários: -# DEPLOY_HOST → IP ou hostname do servidor -# DEPLOY_USER → usuário SSH -# DEPLOY_SSH_KEY → chave privada SSH (RSA ou Ed25519) -# DEPLOY_PATH → path no servidor (ex: /opt/dissmodel-platform) -# MINIO_ROOT_USER → usado no .env do servidor -# MINIO_ROOT_PASSWORD → usado no .env do servidor -# API_KEYS → chaves de API para o FastAPI - -on: - push: - branches: - - main - workflow_dispatch: - inputs: - environment: - description: 'Ambiente para deploy' - required: true - type: choice - options: - - staging - - production - -jobs: - build-and-push: - runs-on: ubuntu-latest - outputs: - image_tag: ${{ github.sha }} - steps: - - uses: actions/checkout@v4 - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push API - uses: docker/build-push-action@v5 - with: - context: ./services/api - file: ./services/api/Dockerfile - push: true - tags: | - ghcr.io/${{ github.repository }}/api:${{ github.sha }} - ghcr.io/${{ github.repository }}/api:latest - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push Worker - uses: docker/build-push-action@v5 - with: - context: ./services/worker - file: ./services/worker/Dockerfile - push: true - tags: | - ghcr.io/${{ github.repository }}/worker:${{ github.sha }} - ghcr.io/${{ github.repository }}/worker:latest - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push Frontend - uses: docker/build-push-action@v5 - with: - context: ./services/frontend - file: ./services/frontend/Dockerfile - push: true - tags: | - ghcr.io/${{ github.repository }}/frontend:${{ github.sha }} - ghcr.io/${{ github.repository }}/frontend:latest - cache-from: type=gha - cache-to: type=gha,mode=max - - deploy-ssh: - needs: build-and-push - runs-on: ubuntu-latest - steps: - - name: Deploy via SSH - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.DEPLOY_HOST }} - username: ${{ secrets.DEPLOY_USER }} - key: ${{ secrets.DEPLOY_SSH_KEY }} - script: | - cd ${{ secrets.DEPLOY_PATH }} || exit 1 - git pull origin main - - sed -i '/^IMAGE_TAG=/d' .env - echo "IMAGE_TAG=${{ github.sha }}" >> .env - - sed -i '/^MINIO_ROOT_USER=/d' .env - echo "MINIO_ROOT_USER=${{ secrets.MINIO_ROOT_USER }}" >> .env - - sed -i '/^MINIO_ROOT_PASSWORD=/d' .env - echo "MINIO_ROOT_PASSWORD=${{ secrets.MINIO_ROOT_PASSWORD }}" >> .env - - sed -i '/^API_KEYS=/d' .env - echo "API_KEYS=${{ secrets.API_KEYS }}" >> .env - - docker compose -f docker-compose.prod.yml pull - docker compose -f docker-compose.prod.yml up -d --remove-orphans - - sleep 10 - - if ! docker compose -f docker-compose.prod.yml exec api curl -f http://localhost:8000/health; then - echo "Healthcheck API falhou, iniciando rollback..." - git checkout HEAD^ - PREV_SHA=$(git rev-parse HEAD) - sed -i '/^IMAGE_TAG=/d' .env - echo "IMAGE_TAG=$PREV_SHA" >> .env - docker compose -f docker-compose.prod.yml pull - docker compose -f docker-compose.prod.yml up -d --remove-orphans - exit 1 - fi - - sleep 30 - if [ -f "scripts/health-check.sh" ]; then - bash scripts/health-check.sh || { - echo "Healthcheck completo falhou, iniciando rollback..." - git checkout HEAD^ - PREV_SHA=$(git rev-parse HEAD) - sed -i '/^IMAGE_TAG=/d' .env - echo "IMAGE_TAG=$PREV_SHA" >> .env - docker compose -f docker-compose.prod.yml pull - docker compose -f docker-compose.prod.yml up -d --remove-orphans - exit 1 - } - fi - - notify: - needs: [deploy-ssh] - if: always() - runs-on: ubuntu-latest - steps: - - name: Generate Summary - run: | - echo "## Deploy Summary" >> $GITHUB_STEP_SUMMARY - echo "- **Tag Deployada**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY - echo "- **Ambiente**: \`${{ github.event.inputs.environment || 'production' }}\`" >> $GITHUB_STEP_SUMMARY - if [ "${{ needs.deploy-ssh.result }}" = "success" ]; then - echo "- **Status**: ✅ Sucesso" >> $GITHUB_STEP_SUMMARY - else - echo "- **Status**: ❌ Falha" >> $GITHUB_STEP_SUMMARY - fi - echo "- **Link para o Run**: [Run #${{ github.run_id }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/pr-executor.yml b/.github/workflows/pr-executor.yml deleted file mode 100644 index 3986887..0000000 --- a/.github/workflows/pr-executor.yml +++ /dev/null @@ -1,152 +0,0 @@ -name: PR Executor Validation - -# Este é o mecanismo de segurança do MVP para novos executors. -# Um executor que passa aqui pode ser mergeado com confiança. -# O workflow bloqueia falhas na validação do contrato e tipagem e foca apenas em PRs para novos executors. - -on: - pull_request: - paths: - - 'services/worker/executors/**' - -jobs: - security: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install Bandit - run: pip install bandit - - name: Run Security Check on modified files - run: | - FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '*.py' || true) - if [ -n "$FILES" ]; then - bandit -r $FILES -ll -ii - else - echo "No python files changed." - fi - - typecheck: - needs: security - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - cache: 'pip' - - name: Install dependencies - run: | - pip install mypy - pip install -r services/worker/requirements.txt - - name: Run Mypy on modified executor files - run: | - FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'services/worker/executors/*.py' || true) - if [ -n "$FILES" ]; then - mypy --strict $FILES - else - echo "No executor files changed." - fi - - contract: - needs: typecheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - cache: 'pip' - - name: Install dependencies - run: | - pip install -r services/worker/requirements.txt - - name: Run Contract Tests - run: | - export PYTHONPATH=$PWD/services - python -c " - from dissmodel.executor.testing import ExecutorTestHarness - from dissmodel.executor.registry import ExecutorRegistry - import worker.executors - import sys - - failed = False - for name, cls in ExecutorRegistry._executors.items(): - print(f'Testing {name}...') - harness = ExecutorTestHarness(cls) - if not harness.run_contract_tests(): - failed = True - - if failed: - sys.exit(1) - " - - unittest: - needs: contract - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check if tests exist - id: check_tests - run: | - if [ -d "services/worker/tests/" ] && [ "$(ls -A services/worker/tests/)" ]; then - echo "has_tests=true" >> $GITHUB_OUTPUT - else - echo "has_tests=false" >> $GITHUB_OUTPUT - fi - - name: Set up Python - if: steps.check_tests.outputs.has_tests == 'true' - uses: actions/setup-python@v5 - with: - python-version: '3.11' - cache: 'pip' - - name: Install dependencies - if: steps.check_tests.outputs.has_tests == 'true' - run: | - pip install pytest - pip install -r services/worker/requirements.txt - - name: Run Unit Tests - if: steps.check_tests.outputs.has_tests == 'true' - run: pytest services/worker/tests/ - - pr-comment: - needs: [security, typecheck, contract, unittest] - if: always() - runs-on: ubuntu-latest - steps: - - name: Comment PR - uses: actions/github-script@v7 - with: - script: | - const statusMap = { - 'success': '✅', - 'failure': '❌', - 'skipped': '⏭️', - 'cancelled': '🚫' - }; - - const secStatus = statusMap['${{ needs.security.result }}'] || '❓'; - const typStatus = statusMap['${{ needs.typecheck.result }}'] || '❓'; - const conStatus = statusMap['${{ needs.contract.result }}'] || '❓'; - - let uniStatus = '⏭️'; - if ('${{ needs.unittest.result }}' && '${{ needs.unittest.result }}' !== 'skipped') { - uniStatus = statusMap['${{ needs.unittest.result }}'] || '❓'; - } - - const body = `### PR Validation Results\n\n| Job | Status |\n|-----------|--------|\n| Security | ${secStatus} |\n| Typecheck | ${typStatus} |\n| Contract | ${conStatus} |\n| Tests | ${uniStatus} |`; - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: body - });