۴ الگوی GitHub Actions برای ETL در Monorepo
اجرای سه سایت از یک monorepo مشکلات متعددی ایجاد میکند. شما با سه کار ETL مجزا، سه بازسازی محتوا (rebuild) و سه خط لوله (pipeline) استقرار روبرو هستید. اگر آنها را هماهنگ نکنید، با هم تداخل پیدا میکنند.
من شش هفته را صرف تست زمانبندیها کردم تا این ساختار را پایدار کنم. در اینجا چهار الگویی که استفاده میکنم آورده شده است.
۱. استفاده از اختلاف زمانی (Time Offsets) برای کارهای Cron
اجرای همزمان تمام کارهای ETL باعث بروز خطا میشود. کارها برای محدودیت نرخ (rate limits) API با هم رقابت میکنند. وقتی HuggingFace یا GitHub خطای 429 برمیگردانند، اجرا با شکست مواجه میشود.
من برای جلوگیری از این اتفاق، از اختلاف زمانی ۳۰ دقیقهای استفاده میکنم.
- کار اول در ساعت ۰۲:۰۰ شروع میشود
- کار دوم در ساعت ۰۲:۳۰ شروع میشود
- کار سوم در ساعت ۰۳:۰۰ شروع میشود
سی دقیقه زمان کافی است تا یک عملیات دریافت (pull) سنگین قبل از شروع کار بعدی تمام شود. این کار باعث تمیز ماندن لاگها و جلوگیری از تداخلهای API میشود.
۲. استفاده از پرچمهای Skip برای جلوگیری از بازسازیهای غیرضروری
هر کار ETL با یک استقرار در Vercel پایان مییابد. مشکل زمانی پیش میآید که کامیتهای مربوط به مقالات نیز باعث بازسازی (rebuild) شوند. بدون داشتن یک برنامه، هر بهروزرسانی مقاله، هر سه سایت را مجبور به بازسازی میکند. این کار باعث هدر رفتن دقایق build میشود.
من از تگ [skip publish-articles] در پیامهای کامیت ETL استفاده میکنم.
من مرحلهای را به workflow خود اضافه کردم تا این پرچم را بررسی کند. اگر این تگ وجود داشته باشد، workflow مرحله build و deploy را نادیده میگیرد. این کار باعث میشود خط لولههای ETL از خط لولههای مقالات جدا بمانند.
۳. استفاده از فیلترهای مسیر (Path Filters) برای هدف قرار دادن سایتهای خاص
شما نمیخواهید بهروزرسانی یک سایت باعث سه استقرار شود. من workflow هر سایت را طوری تنظیم میکنم که فقط پوشه خودش و پوشه پکیجهای مشترک (shared packages) را زیر نظر داشته باشد.
منطق نمونه:
- سایت ابزارهای AI فقط
apps/ai-tools/را زیر نظر میگیرد - سایت OSS فقط
apps/oss-alternatives/را زیر نظر میگیرد
اگر کدی را در دایرکتوری مشترک تغییر دهید، همه سایتها بازسازی خواهند شد. من این سبک معامله (trade-off) را میپذیرم، زیرا تغییرات در کدهای مشترک نادر هستند.
۴. افزودن Manual Dispatch برای کنترل بیشتر
Cron کارهای روزمره را مدیریت میکند. Manual dispatch بقیه موارد را مدیریت میکند. من از workflow_dispatch استفاده میکنم تا بتوانم:
- یک کار ETL شکستخورده را دوباره اجرا کنم
- پس از افزودن داده، یک بازنشانی (refresh) اجباری انجام دهم
- یک اجرای آزمایشی (dry run) برای تست دادهها بدون نوشتن در پایگاه داده انجام دهم
رابط کاربری GitHub یک منوی کشویی برای این انتخابها نشان میدهد. این کار از غلطهای تایپی جلوگیری کرده و عیبیابی (debugging) را آسان میکند.
خلاصه
این الگوها پیچیده نیستند، بلکه صریح و مشخص هستند. من یک فایل markdown ساده در مخزن خود نگه میدارم تا این قوانین را مستند کنم. این کار تضمین میکند که هنگام اضافه کردن workflowهای جدید، سیستم را خراب نکنم.
