update #76
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: 🚀 Proxy Parser & Deploy | |
| on: | |
| # Запуск по расписанию - каждый час | |
| schedule: | |
| - cron: '0 * * * *' # Каждый час в 00 минут | |
| # Ручной запуск из интерфейса GitHub | |
| workflow_dispatch: | |
| inputs: | |
| max_sources: | |
| description: 'Максимальное количество источников для обработки (0 = все)' | |
| required: false | |
| default: '0' | |
| type: number | |
| test_all: | |
| description: 'Тестировать все найденные конфиги (может быть долго)' | |
| required: false | |
| default: false | |
| type: boolean | |
| debug_mode: | |
| description: 'Режим отладки (подробное логирование)' | |
| required: false | |
| default: false | |
| type: boolean | |
| # Запуск при изменениях в коде парсера | |
| push: | |
| branches: | |
| - main | |
| - master | |
| - develop | |
| paths: | |
| - 'source/parser.py' | |
| - '.github/workflows/parser.yml' | |
| - 'requirements.txt' | |
| tags: | |
| - 'v*' | |
| # Запуск при создании Pull Request (только проверка) | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| paths: | |
| - 'source/parser.py' | |
| types: [opened, synchronize, reopened] | |
| # Даем права на запись в репозиторий | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| actions: read | |
| checks: write | |
| pull-requests: write | |
| # Конкурентность - предотвращаем одновременные запуски | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| parse-and-deploy: | |
| name: 🔄 Parse & Deploy Proxies | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 # Максимальное время выполнения | |
| steps: | |
| # 1. Проверка кода | |
| - name: 📥 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| lfs: false | |
| # 2. Настройка Python | |
| - name: 🐍 Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| cache-dependency-path: | | |
| requirements.txt | |
| **/requirements.txt | |
| # 3. Кэширование зависимостей | |
| - name: 💾 Cache pip packages | |
| uses: actions/cache@v4 | |
| id: cache-pip | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| # 4. Установка зависимостей | |
| - name: 📦 Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install --upgrade setuptools wheel | |
| if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
| pip list # Показываем установленные пакеты для отладки | |
| # 5. Подготовка окружения | |
| - name: 🔧 Prepare environment | |
| id: prepare | |
| run: | | |
| # Создаем директории | |
| mkdir -p deploy/subscriptions | |
| mkdir -p logs | |
| # Устанавливаем переменные окружения | |
| echo "RUN_ID=${{ github.run_id }}" >> $GITHUB_ENV | |
| echo "RUN_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV | |
| echo "RUN_ATTEMPT=${{ github.run_attempt }}" >> $GITHUB_ENV | |
| # Переменные для парсера | |
| echo "MAX_SOURCES=${{ github.event.inputs.max_sources || '0' }}" >> $GITHUB_ENV | |
| echo "TEST_ALL=${{ github.event.inputs.test_all || 'false' }}" >> $GITHUB_ENV | |
| echo "DEBUG_MODE=${{ github.event.inputs.debug_mode || 'false' }}" >> $GITHUB_ENV | |
| # Текущее время | |
| echo "CURRENT_TIME=$(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_ENV | |
| # 6. Запуск парсера | |
| - name: 🏃 Run parser | |
| id: parser | |
| run: | | |
| echo "⏱️ Starting parser at $(date)" | |
| echo "📊 Configuration:" | |
| echo " - Max sources: $MAX_SOURCES" | |
| echo " - Test all: $TEST_ALL" | |
| echo " - Debug mode: $DEBUG_MODE" | |
| # Запускаем с таймаутом | |
| timeout 25m python source/parser.py 2>&1 | tee logs/parser.log | |
| # Проверяем результат | |
| if [ ${PIPESTATUS[0]} -eq 0 ]; then | |
| echo "✅ Parser completed successfully" | |
| echo "status=success" >> $GITHUB_OUTPUT | |
| else | |
| echo "❌ Parser failed with error" | |
| echo "status=failed" >> $GITHUB_OUTPUT | |
| exit 1 | |
| fi | |
| continue-on-error: false | |
| env: | |
| PYTHONUNBUFFERED: 1 | |
| PYTHONIOENCODING: utf-8 | |
| # 7. Проверка результатов | |
| - name: 🔍 Check results | |
| id: check | |
| run: | | |
| # Проверяем общий файл | |
| if [ -f "deploy/sub.txt" ]; then | |
| COUNT=$(wc -l < deploy/sub.txt | tr -d ' ') | |
| echo "📊 Found $COUNT proxies in total" | |
| echo "count=$COUNT" >> $GITHUB_OUTPUT | |
| # Показываем первые несколько строк | |
| echo "📋 First 5 proxies:" | |
| head -5 deploy/sub.txt | |
| # Проверяем минимальное количество | |
| if [ $COUNT -lt 10 ]; then | |
| echo "⚠️ Warning: Only $COUNT proxies found (minimum is 10)" | |
| echo "quality=low" >> $GITHUB_OUTPUT | |
| elif [ $COUNT -lt 50 ]; then | |
| echo "⚠️ Warning: Only $COUNT proxies found (minimum is 50)" | |
| echo "quality=medium" >> $GITHUB_OUTPUT | |
| else | |
| echo "✅ Good quality: $COUNT proxies found" | |
| echo "quality=high" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "❌ No proxies file created!" | |
| echo "count=0" >> $GITHUB_OUTPUT | |
| echo "quality=none" >> $GITHUB_OUTPUT | |
| exit 1 | |
| fi | |
| # Проверяем индивидуальные файлы | |
| if [ -d "deploy/subscriptions" ]; then | |
| SOURCE_COUNT=$(ls -1 deploy/subscriptions/ | wc -l) | |
| echo "📁 Found $SOURCE_COUNT source files" | |
| # Размер файлов | |
| TOTAL_SIZE=$(du -sh deploy/ | cut -f1) | |
| echo "📦 Total size: $TOTAL_SIZE" | |
| fi | |
| # Проверяем JSON если есть | |
| if [ -f "deploy/proxies.json" ]; then | |
| echo "📊 JSON details available" | |
| echo "json=true" >> $GITHUB_OUTPUT | |
| # Парсим статистику если есть jq | |
| if command -v jq &> /dev/null; then | |
| AVG_LATENCY=$(jq '. | map(.latency) | add / length' deploy/proxies.json) | |
| echo "📈 Average latency: ${AVG_LATENCY}ms" | |
| fi | |
| fi | |
| # 8. Создание отчета | |
| - name: 📝 Generate report | |
| id: report | |
| run: | | |
| cat > deploy/report.md << EOF | |
| # Proxy Parser Report | |
| **Run Information:** | |
| - Workflow: ${{ github.workflow }} | |
| - Run ID: ${{ github.run_id }} | |
| - Run Number: ${{ github.run_number }} | |
| - Event: ${{ github.event_name }} | |
| - Branch: ${{ github.ref_name }} | |
| - Commit: ${{ github.sha }} | |
| **Results:** | |
| - Total proxies: ${{ steps.check.outputs.count }} | |
| - Quality: ${{ steps.check.outputs.quality }} | |
| - Time: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | |
| **Statistics:** | |
| \`\`\` | |
| $(if [ -f "deploy/last_update.txt" ]; then cat deploy/last_update.txt; fi) | |
| \`\`\` | |
| **Sources processed:** $(ls -1 deploy/subscriptions/ 2>/dev/null | wc -l) | |
| --- | |
| *Generated by GitHub Actions on $(date)* | |
| EOF | |
| echo "✅ Report generated" | |
| # 9. Деплой на GitHub Pages | |
| - name: 📤 Deploy to GitHub Pages | |
| id: deployment | |
| if: success() && github.event_name != 'pull_request' | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./deploy | |
| publish_branch: gh-pages | |
| destination_dir: ./ | |
| user_name: 'github-actions[bot]' | |
| user_email: 'github-actions[bot]@users.noreply.github.com' | |
| commit_message: | | |
| Deploy proxies - ${{ steps.check.outputs.count }} found | |
| Run #${{ github.run_number }} | |
| Quality: ${{ steps.check.outputs.quality }} | |
| full_commit_message: ${{ github.event.head_commit.message }} | |
| keep_files: false | |
| enable_jekyll: true | |
| disable_nojekyll: false | |
| # 10. Создание Release (только для тегов или по расписанию) | |
| - name: 🏷️ Create Release | |
| if: success() && steps.check.outputs.count > 0 && (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: Proxy List v${{ github.run_number }} | |
| tag_name: v${{ github.run_number }} | |
| body_path: deploy/report.md | |
| files: | | |
| deploy/sub.txt | |
| deploy/proxies.json | |
| deploy/subscriptions/*.txt | |
| generate_release_notes: true | |
| prerelease: false | |
| draft: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # 11. Создание Issue если мало прокси | |
| - name: ⚠️ Create issue for low quality | |
| if: failure() || steps.check.outputs.quality == 'low' || steps.check.outputs.quality == 'none' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const quality = '${{ steps.check.outputs.quality }}'; | |
| const count = ${{ steps.check.outputs.count }}; | |
| let title = ''; | |
| let body = ''; | |
| if (count === 0) { | |
| title = '❌ No proxies found in latest run'; | |
| body = 'The parser failed to find any proxies. Please check the logs.'; | |
| } else if (quality === 'low') { | |
| title = '⚠️ Low quality proxy list detected'; | |
| body = `Only ${count} proxies were found, which is below the minimum threshold.`; | |
| } | |
| if (title) { | |
| github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: title, | |
| body: body + '\n\nRun: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
| }); | |
| } | |
| # 12. Загрузка артефактов | |
| - name: 📦 Upload artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: proxy-files-${{ github.run_number }} | |
| path: | | |
| deploy/ | |
| logs/ | |
| retention-days: 7 | |
| compression-level: 6 | |
| if-no-files-found: warn | |
| # 13. Очистка старых артефактов (опционально) | |
| - name: 🧹 Clean up old artifacts | |
| if: github.event_name == 'schedule' | |
| run: | | |
| echo "🧹 Cleaning up old artifacts is handled automatically by GitHub" | |
| # GitHub автоматически удаляет артефакты через retention-days | |
| # 14. Уведомление о статусе в логах | |
| - name: 📊 Final status | |
| if: always() | |
| run: | | |
| echo "═══════════════════════════════════════════" | |
| echo " FINAL STATUS" | |
| echo "═══════════════════════════════════════════" | |
| echo "Status: ${{ job.status }}" | |
| echo "Proxies found: ${{ steps.check.outputs.count }}" | |
| echo "Quality: ${{ steps.check.outputs.quality }}" | |
| echo "Duration: ${{ github.run_attempt }}" | |
| echo "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| echo "═══════════════════════════════════════════" | |
| # Проверяем доступность файлов | |
| echo "" | |
| echo "📁 Generated files:" | |
| if [ -f "deploy/sub.txt" ]; then | |
| echo " ✅ sub.txt - $(wc -l < deploy/sub.txt) lines" | |
| fi | |
| if [ -f "deploy/proxies.json" ]; then | |
| echo " ✅ proxies.json - $(du -h deploy/proxies.json | cut -f1)" | |
| fi | |
| if [ -d "deploy/subscriptions" ]; then | |
| echo " ✅ subscriptions/ - $(ls -1 deploy/subscriptions/ | wc -l) files" | |
| fi | |
| # Итоговое сообщение | |
| echo "" | |
| if [ "${{ job.status }}" == "success" ]; then | |
| echo "🎉 Workflow completed successfully!" | |
| else | |
| echo "💥 Workflow failed. Check logs for details." | |
| fi |