4 патерни GitHub Actions для Monorepo ETL
Запуск трьох сайтів з одного монорепозиторію створює проблеми. Ви стикаєтеся з трьома окремими ETL-завданнями, трьома перезбірками контенту та трьома конвеєрами розгортання. Якщо їх не координувати, вони конфліктуватимуть.
Я витратив шість тижнів на тестування графіків, щоб стабілізувати цю систему. Ось чотири патерни, які я використовую.
- Використовуйте часові зміщення для Cron-завдань
Запуск усіх ETL-завдань одночасно призводить до збоїв. Завдання конкурують за ліміти запитів API (rate limits). Коли HuggingFace або GitHub повертають помилку 429, виконання завершується невдало.
Щоб запобігти цьому, я використовую 30-хвилинні зміщення.
- Завдання перше запускається о 02:00
- Завдання друге запускається о 02:30
- Завдання третє запускається о 03:00
Тридцяти хвилин достатньо, щоб завершити важке завантаження (pull) до початку наступного завдання. Це дозволяє тримати логи чистими та запобігає конфліктам API.
- Використовуйте прапорці пропуску (skip flags), щоб зупинити непотрібні перезбірки
Кожне ETL-завдання завершується розгортанням у Vercel. Проблема виникає тоді, коли комміти зі статтями також запускають перезбірки. Без плану кожне оновлення статті змушує всі три сайти перезбиратися. Це марнує хвилини збірки (build minutes).
Я використовую тег [skip publish-articles] у повідомленнях до коммітів ETL.
Я додав крок у свій workflow, щоб перевіряти наявність цього прапорця. Якщо тег існує, workflow пропускає крок збірки та розгортання. Це дозволяє відокремити ETL-конвеєри від конвеєрів оновлення статей.
- Використовуйте фільтри шляхів (path filters) для вибору конкретних сайтів
Ви не хочете, щоб оновлення одного сайту запускало три розгортання. Я налаштовую workflow кожного сайту так, щоб він стежив лише за своєю папкою та спільною папкою пакетів (shared packages).
Приклад логіки:
- Сайт AI tools стежить лише за apps/ai-tools/
- Сайт OSS стежить лише за apps/oss-alternatives/
Якщо ви зміните код у спільній директорії, усі сайти будуть перезібрані. Я приймаю цей компроміс, оскільки зміни у спільному коді трапляються рідко.
- Додайте ручний запуск (manual dispatch) для контролю
Cron обробляє щоденну рутину. Manual dispatch обробляє все інше. Я використовую workflow_dispatch, щоб мати змогу:
- Перезапустити невдале ETL-завдання
- Примусово оновити дані після їх додавання
- Виконати тестовий запуск (dry run), щоб перевірити дані без запису в базу даних
Інтерфейс GitHub пропонує випадаюче меню для цих варіантів. Це запобігає помилкам у написанні та полегшує налагодження.
Summary
Ці патерни не є складними. Вони є явними. Я зберігаю простий markdown-файл у своєму репозиторії, щоб задокументувати ці правила. Це гарантує, що я не зламаю систему, коли додаватиму нові workflow.
