name: Auto Sync and Deploy # Triggers para execução da action on: push: branches: [ main, develop ] pull_request: branches: [ main ] schedule: # Executa a cada 30 minutos - cron: '*/30 * * * *' workflow_dispatch: inputs: force_deploy: description: 'Force deploy even without changes' required: false default: 'false' type: boolean target_branch: description: 'Target branch for deployment' required: false default: 'main' type: string env: NODE_VERSION: '18' PNPM_VERSION: '8' TARGET_REPO: 'Reifonas/TS_RDO' jobs: # Job para verificar mudanças check-changes: runs-on: ubuntu-latest outputs: has-changes: ${{ steps.changes.outputs.has-changes }} changed-files: ${{ steps.changes.outputs.changed-files }} steps: - name: Checkout código uses: actions/checkout@v4 with: fetch-depth: 2 - name: Verificar mudanças id: changes run: | if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ inputs.force_deploy }}" = "true" ]; then echo "has-changes=true" >> $GITHUB_OUTPUT echo "changed-files=scheduled-run" >> $GITHUB_OUTPUT else CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD || echo "") if [ -n "$CHANGED_FILES" ]; then echo "has-changes=true" >> $GITHUB_OUTPUT echo "changed-files<> $GITHUB_OUTPUT echo "$CHANGED_FILES" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT else echo "has-changes=false" >> $GITHUB_OUTPUT echo "changed-files=" >> $GITHUB_OUTPUT fi fi # Job para build e testes build-and-test: needs: check-changes if: needs.check-changes.outputs.has-changes == 'true' runs-on: ubuntu-latest steps: - name: Checkout código uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: ${{ env.PNPM_VERSION }} - name: Instalar dependências run: pnpm install --frozen-lockfile - name: Executar linting run: pnpm run lint continue-on-error: true - name: Executar testes run: pnpm run test continue-on-error: true - name: Build do projeto run: pnpm run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: build-files path: dist/ retention-days: 1 # Job para sincronização com repositório remoto sync-to-remote: needs: [check-changes, build-and-test] if: needs.check-changes.outputs.has-changes == 'true' runs-on: ubuntu-latest steps: - name: Checkout código atual uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Configurar Git run: | git config --global user.name "Auto Sync Bot" git config --global user.email "auto-sync@rdo-app.com" - name: Download build artifacts uses: actions/download-artifact@v4 with: name: build-files path: dist/ - name: Preparar arquivos para sincronização run: | # Criar diretório temporário mkdir -p /tmp/sync-repo # Copiar arquivos essenciais (excluir node_modules, logs, etc.) rsync -av --exclude='node_modules' \ --exclude='.git' \ --exclude='logs' \ --exclude='.env.local' \ --exclude='*.log' \ --exclude='.trae' \ --exclude='android' \ --exclude='ios' \ ./ /tmp/sync-repo/ - name: Clonar repositório remoto env: REMOTE_TOKEN: ${{ secrets.REMOTE_REPO_TOKEN }} run: | cd /tmp git clone https://${REMOTE_TOKEN}@github.com/${{ env.TARGET_REPO }}.git remote-repo cd remote-repo git checkout ${{ inputs.target_branch || 'main' }} || git checkout -b ${{ inputs.target_branch || 'main' }} - name: Sincronizar arquivos run: | cd /tmp/remote-repo # Remover arquivos antigos (exceto .git) find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + # Copiar novos arquivos cp -r /tmp/sync-repo/* . cp -r /tmp/sync-repo/.* . 2>/dev/null || true # Adicionar todos os arquivos git add . - name: Commit e Push para repositório remoto env: REMOTE_TOKEN: ${{ secrets.REMOTE_REPO_TOKEN }} run: | cd /tmp/remote-repo # Verificar se há mudanças if git diff --staged --quiet; then echo "Nenhuma mudança para sincronizar" exit 0 fi # Criar mensagem de commit COMMIT_MSG="Auto-sync from RDO-C: $(date '+%Y-%m-%d %H:%M:%S')" if [ "${{ needs.check-changes.outputs.changed-files }}" != "scheduled-run" ]; then COMMIT_MSG="$COMMIT_MSG\n\nChanged files:\n${{ needs.check-changes.outputs.changed-files }}" fi # Commit e push git commit -m "$COMMIT_MSG" git push origin ${{ inputs.target_branch || 'main' }} # Job para deploy (se necessário) deploy: needs: [check-changes, build-and-test, sync-to-remote] if: needs.check-changes.outputs.has-changes == 'true' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Checkout código uses: actions/checkout@v4 - name: Download build artifacts uses: actions/download-artifact@v4 with: name: build-files path: dist/ - name: Deploy para Netlify uses: nwtgck/actions-netlify@v3.0 with: publish-dir: './dist' production-branch: main github-token: ${{ secrets.GITHUB_TOKEN }} deploy-message: "Auto-deploy from commit ${{ github.sha }}" enable-pull-request-comment: false enable-commit-comment: true env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} timeout-minutes: 10 # Job para notificações notify: needs: [check-changes, build-and-test, sync-to-remote, deploy] if: always() && needs.check-changes.outputs.has-changes == 'true' runs-on: ubuntu-latest steps: - name: Notificar sucesso if: needs.sync-to-remote.result == 'success' run: | echo "✅ Sincronização concluída com sucesso!" echo "Repositório: ${{ env.TARGET_REPO }}" echo "Branch: ${{ inputs.target_branch || 'main' }}" echo "Commit: ${{ github.sha }}" - name: Notificar falha if: needs.sync-to-remote.result == 'failure' || needs.build-and-test.result == 'failure' run: | echo "❌ Falha na sincronização!" echo "Verifique os logs para mais detalhes." exit 1 # Job para limpeza cleanup: needs: [check-changes, build-and-test, sync-to-remote, deploy, notify] if: always() runs-on: ubuntu-latest steps: - name: Limpar artifacts uses: actions/github-script@v7 with: script: | const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.runId, }); for (const artifact of artifacts.data.artifacts) { if (artifact.name === 'build-files') { await github.rest.actions.deleteArtifact({ owner: context.repo.owner, repo: context.repo.repo, artifact_id: artifact.id, }); console.log(`Artifact ${artifact.name} removido`); } }