GitHub Actions روی Mac Mini خانگی: ۴ برابر سریعتر و رایگان!
خلاصهٔ کاملتر
اگه با GitHub Actions روی ریپوهای خصوصی کار میکنی، احتمالاً با سقف ۲۰۰۰ دقیقه رایگان در ماه آشنا هستی. یه توسعهدهنده که به این محدودیت خورده بود، تصمیم گرفت به جای پرداخت پول بیشتر، Mac Mini M4 خودش رو که ۲۴/۷ روشنه تبدیل به یه سرور CI خانگی کنه.
ایده اصلی اینه که GitHub Actions بهت اجازه میده ماشینهای خودت رو به عنوان «runner» ثبت کنی. یه پروسه سبکوزن روی ماشینت اجرا میشه که از طریق HTTPS به GitHub وصل میشه، جابها رو میگیره، اجرا میکنه و نتیجه رو گزارش میده. چون ارتباط outbound هست، نیازی به باز کردن پورت روی شبکه خانگی نیست.
نتیجه نهایی ۴ تا runner موازی هست که همه زیر یه یوزر macOS اختصاصی به اسم actions-runner اجرا میشن. هر runner توی دایرکتوری جداگانهای (runner-1 تا runner-4) نصب شده و workflowها فقط کافیه بنویسن runs-on: self-hosted تا GitHub به صورت خودکار جاب رو به یه runner بیکار بده.
قبل از رسیدن به این راهحل، چند گزینه دیگه هم بررسی شده: macOS VM از طریق Virtualization framework اپل، که محدودیت ۲ VM همزمان داره و برای ۴+ runner کافی نیست. Docker container هم گزینهای بود که isolation و parallelism خوبی میداد ولی overhead عملیاتی زیادی داشت (ساخت ایمیج سفارشی با PHP و Node، مدیریت lifecycle کانتینرها). و البته پرداخت هزینه بیشتر که سادهترین گزینه بود ولی با نرخ $0.008 در دقیقه برای Linux runner، با مصرف زیاد گرون میشه.
یه نکته مهم در نصب اینه که runner به عنوان سرویس نصب میشه تا بعد از ریستارت هم بالا بیاد. مشکل اینه که svc.sh install یه LaunchAgent میسازه که برای یوزرهای بدون GUI session کار نمیکنه. راهحل اینه که فایل plist رو به LaunchDaemons منتقل کنی:
sudo mv /Users/actions-runner/Library/LaunchAgents/actions.runner.*.plist /Library/LaunchDaemons/
sudo chown root:wheel /Library/LaunchDaemons/actions.runner.*.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/actions.runner.*.plistدر workflowها هم تغییرات جالبی داده شده: چون وابستگیها (vendor/، node_modules/) بین رانها روی فایلسیستم میمونن، دیگه نیازی به استفاده از actions/cache نیست. همچنین actions/setup-php و actions/setup-node هم حذف شدن چون ابزارها از قبل روی ماشین نصبن. یه نکته کوچیک هم اینه که چون چند runner یه MySQL مشترک دارن، هر کدوم باید از دیتابیس تست جداگانه استفاده کنن که با متغیر ${{ runner.name }} حل میشه:
env:
DB_DATABASE: actions_test_${{ runner.name }}نتایج benchmark واقعاً چشمگیره: جابهای PHP tests از ۶ دقیقه به ۱ دقیقه و ۱۵ ثانیه رسیدن (۴.۸ برابر سریعتر)، Lint از ۵ دقیقه به ۱ دقیقه و ۱۰ ثانیه (۴.۳ برابر)، و JS tests از ۱ دقیقه به ۳۰ ثانیه (۲.۳ برابر). این سرعت هم از قدرت چیپ M4 نسبت به VM های 2-vCPU گیتهاب میاد، هم از اینکه وابستگیها کش شدن.
این روش برای سولو دولوپرهایی که ریپوهای خصوصی دارن و ماشینی که ۲۴/۷ روشنه ایدهآله. ولی برای تیمها isolation کافی نداره، autoscaling نداره و نگهداریش به عهده خودته. برای تیمها سرویسهایی مثل Depot یا Runs-On گزینههای بهتری هستن.
نکات کلیدی:
- با self-hosted runner روی Mac Mini M4، جابهای CI تا ۴.۸ برابر سریعتر میشن
- محدودیت ۲۰۰۰ دقیقه رایگان ماهانه حذف میشه و هزینهای نداره
- ۴ runner موازی زیر یه یوزر macOS اختصاصی با LaunchDaemons راهاندازی میشن
- وابستگیها بین رانها کش میشن و نیازی به نصب مجدد نیست
- برای تیمها مناسب نیست؛ isolation سختافزاری و autoscaling نداره
- macOS VM به خاطر محدودیت ۲ VM همزمان اپل، گزینه مناسبی نبود




