اولین بار که GitHub Actions را راه انداختم، فقط برای اجرای تست‌ها بود. چند ماه بعد، فهمیدم همان ابزار می‌تواند انتشار سایت را خودکار کند، مستندات را بسازد و حتی بررسی کند که آیا کد امنیتی درست نوشته شده. آن روز یاد گرفتم که GitHub Actions یک ابزار CI/CD نیست؛ یک بستر عمومی خودکارسازی است که محدودیتش فقط به تصور شما برمی‌گردد. اگر با Git آشنا نیستید، آموزش Git از صفر نقطه شروع خوبی است. برای مرور پایه‌ها، GitHub در ویکی‌پدیا هم مفید است.

GitHub Actions دقیقاً چیست؟

GitHub Actions یک سرویس خودکارسازی است که در بستر GitHub ارائه می‌شود و اجازه می‌دهد بر اساس رویدادهای مختلف در مخزن، کارهای مشخصی اجرا کنید. این کارها می‌توانند تست کد، ساخت artifact، استقرار روی سرور، ساخت مستندات یا هر عملیات دیگر باشد. این سرویس با فایل‌های YAML تعریف می‌شود که در پوشه .github/workflows قرار می‌گیرند. اگر با YAML آشنا نیستید، YAML را ساده یاد بگیرید پیش‌نیاز مفیدی است.

مزیت اصلی GitHub Actions، یکپارچگی با خود مخزن است. برخلاف ابزارهایی مثل Jenkins یا Travis CI که نیاز به سرویس جداگانه دارند، GitHub Actions در همان مخزن تعریف می‌شود و نیازی به زیرساخت اضافی ندارد. برای پروژه‌های متن‌باز، این ابزار رایگان است و برای پروژه‌های خصوصی، سهم رایگان ماهانه‌ای دارد. برای CI/CD در پروژه‌های وردپرسی، CI/CD برای پروژه‌های وردپرسی راهنمای کاربردی دارد.

GitHub Actions یک اجاق گاز خانگی است که می‌تواند هم غذا بپزد هم کیک، هم قهوه دم کند؛ فقط باید بدانید چه دستور پختی می‌خواهید.

آناتومی یک workflow حرفه‌ای

هر workflow، مجموعه‌ای از jobها است که در یک یا چند مرحله اجرا می‌شوند. ساختار پایه یک workflow شامل این بخش‌ها است:

  • name: نام workflow که در تب Actions نمایش داده می‌شود.
  • on: رویدادهایی که باعث اجرا می‌شوند، مثل push یا pull_request.
  • jobs: کارهایی که باید اجرا شوند.
  • steps: گام‌هایی که هر job در آن‌ها اجرا می‌شود.

یک workflow حرفه‌ای، سه اصل را رعایت می‌کند. اول، هر job یک مسئولیت مشخص دارد و از jobهای دیگر مستقل است. دوم، از cache برای وابستگی‌هایی که تکرار می‌شوند استفاده می‌کند تا زمان اجرا کم شود. سوم، از artifact برای انتقال داده بین jobها استفاده می‌کند. رعایت این سه اصل، اجرای workflow را سریع‌تر و مدیریت آن را ساده‌تر می‌کند. برای آشنایی با مدیریت مخزن، Pull Request در GitHub راهنمای کاملی دارد.

در پروژه‌های واقعی، معمولاً یک workflow اصلی برای CI (ادغام پیوسته) و یک workflow جدا برای CD (استقرار پیوسته) تعریف می‌شود. این تفکیک باعث می‌شود بتوانید CI را روی هر PR اجرا کنید اما CD را فقط روی main و به صورت کنترل‌شده. این الگو در پروژه‌های حساس به خصوص در فروشگاه‌های آنلاین، حیاتی است.

رویدادهای trigger و انتخاب درست

انتخاب trigger مناسب، اولین تصمیم طراحی workflow است. چند trigger رایج که در پروژه‌ها استفاده می‌کنم:

Triggerکاربردنکته
pushاجرای CI پس از ارسال کدمی‌توان شاخه‌های خاص را محدود کرد
pull_requestبررسی PR قبل از ادغامرایج‌ترین trigger در تیم‌ها
scheduleاجرای دوره‌ای، مثل بکاپ شبانهبا cron syntax تنظیم می‌شود
workflow_dispatchاجرای دستی از رابط GitHubبرای استقرار کنترل‌شده
releaseاجرا هنگام انتشار نسخه جدیدبرای ساخت artifact نهایی

یک نکته عملی که در پروژه‌ها به کارم آمده: برای triggerهای push، شاخه‌ها را محدود کنید. یعنی به جای اجرا روی هر push، فقط روی push به main یا develop اجرا شود. این کار جلوی اجرای بی‌دلیل workflow روی شاخه‌های feature را می‌گیرد و زمان CI را کاهش می‌دهد.

trigger workflow_dispatch بسیار قدرتمند است چون اجازه می‌دهد workflow را به صورت دستی از رابط GitHub اجرا کنید. این trigger برای استقرار به production بسیار مفید است: به جای اینکه هر push به main بلافاصله منتشر شود، باید یک نفر دکمه اجرا را بزند. این حالت برای پروژه‌های حساس توصیه می‌شود. برای مدیریت شاخه‌ها، برنچ در Git راهنمای کاربردی دارد.

ساختار job، step و runner

هر job در workflow، روی یک runner اجرا می‌شود. Runner یک ماشین مجازی است که GitHub فراهم می‌کند یا خودتان میزبانی می‌کنید. سه نوع اصلی runner: Ubuntu، Windows و macOS. برای اکثر پروژه‌های وب، Ubuntu انتخاب اول است چون سریع و رایگان است.

هر job از چند step تشکیل شده که به صورت ترتیبی اجرا می‌شوند. هر step می‌تواند یکی از این سه باشد: یک دستور shell، یک action آماده از marketplace، یا یک action سفارشی که خودتان نوشته‌اید. اکشن‌های آماده مثل actions/checkout، actions/setup-node و actions/cache کارهای رایج را ساده می‌کنند. برای کارهای سفارشی، می‌توانید از دستورات shell استفاده کنید یا اکشن اختصاصی بسازید.

یک نکته مهم در طراحی job: از needs برای تعیین وابستگی بین jobها استفاده کنید. اگر job دوم فقط بعد از موفقیت job اول باید اجرا شود، این وابستگی را صریح تعریف کنید. بدون این، jobها به صورت موازی اجرا می‌شوند و ممکن است قبل از آماده شدن پیش‌نیازها شروع شوند. برای آشنایی با مخازن، دستورات ضروری Git و مهاجرت از GitHub به GitLab را ببینید.

matrix build و تست چند محیطی

یکی از قدرتمندترین قابلیت‌های GitHub Actions، matrix build است. این قابلیت اجازه می‌دهد یک job را با ترکیب‌های مختلف متغیرها اجرا کنید. مثلاً تست پروژه در نسخه‌های مختلف PHP، Node.js یا MySQL. این کار برای پروژه‌هایی که باید در چند محیط کار کنند، حیاتی است.

مثال کاربردی: فرض کنید افزونه‌ای برای وردپرس دارید که باید در PHP نسخه‌های ۷.۴ تا ۸.۳ کار کند. با matrix، یک workflow تعریف می‌کنید و در آن، همه ترکیب‌ها به صورت موازی تست می‌شوند. این کار به جای چند ساعت اجرای دستی، در چند دقیقه انجام می‌شود. برای پروژه‌های وردپرسی، این تکنیک در تست و دیباگ پروژه‌های وردپرس توضیح داده شده است.

یک نکته ظریف در استفاده از matrix: تعداد ترکیب‌ها را محدود نگه دارید. اگر ده نسخه از هر متغیر داشته باشید، صد ترکیب می‌شود که اجرای همه، زمان و منابع زیادی می‌طلبد. بهترین رویکرد این است که فقط نسخه‌های پرکاربرد و مرزهای مهم را در matrix بگذارید و بقیه را در اجرای دوره‌ای شبانه بررسی کنید.

مدیریت secrets و امنیت

در workflow، اغلب به اطلاعات حساس مثل رمز دیتابیس، کلید API یا SSH key نیاز دارید. GitHub Secrets این اطلاعات را رمزنگاری شده نگه می‌دارد و در زمان اجرا، فقط در دسترس workflow قرار می‌دهد. هرگز این اطلاعات را در فایل workflow یا کد ننویسید. این یک قاعده ساده اما حیاتی است که در پروژه‌های واقعی، نقض کردنش فاجعه می‌سازد.

سه سطح برای secrets وجود دارد. Secrets سطح repository که در کل مخزن قابل استفاده است. Secrets سطح environment که برای محیط‌های خاص مثل staging و production استفاده می‌شود. Secrets سطح organization برای سازمان‌هایی که چند مخزن دارند. انتخاب سطح درست، مدیریت کلیدها را ساده‌تر می‌کند. برای اصول کلی امنیت API، امنیت API و بهترین روش‌ها راهنمای کاملی دارد.

نکات امنیتی که در پروژه‌ها رعایت می‌کنم: اول، secrets را هر چند ماه rotate کنید. دوم، از OIDC برای استقرار ابری استفاده کنید چون نیازی به نگهداری کلید بلندمدت نیست. سوم، محدودسازی دامنه actionهای third-party: فقط از actionهایی که creator معتبر دارند استفاده کنید. چهارم، لاگ‌ها را چک کنید تا اطلاعات حساس در آن‌ها چاپ نشود. برای راهنمای امنیت وردپرس، راهنمای امنیت وردپرس برای مبتدیان نقطه شروع خوبی است.

هر secret که در workflow استفاده می‌شود، یک کلید به سرور شماست. اگر این کلید مدیریت نشود، سرور شما در معرض خطر است.

استقرار خودکار در سرور

یکی از کاربردهای پرطرفدار GitHub Actions، استقرار خودکار روی سرور است. الگوی کلی این است: بعد از ادغام PR به main، یک workflow اجرا می‌شود که کد را به سرور منتقل و آن را فعال می‌کند. برای پروژه‌های وردپرسی، این استقرار می‌تواند شامل انتقال فایل‌ها، اجرای migration دیتابیس و پاک کردن کش باشد.

سه روش رایج استقرار: اول، SSH به سرور و اجرای دستورات git pull یا rsync. دوم، استفاده از API سرویس‌های میزبانی مثل Vercel یا Netlify. سوم، استقرار با ابزارهای ابری مثل AWS CodeDeploy. انتخاب روش بستگی به زیرساخت پروژه دارد. برای پروژه‌های وردپرسی که روی هاست اشتراکی هستند، روش SSH معمولاً انتخاب اول است.

یک نکته حیاتی در استقرار: همیشه یک stage برای staging داشته باشید و فقط بعد از تأیید staging به production بروید. این کار جلوی بسیاری از فاجعه‌ها را می‌گیرد. برای اجرای این چرخه، تست و دیباگ پروژه‌های وردپرسی و CI/CD برای پروژه‌های وردپرسی راهنمای کاملی دارند. برای امنیت SSH، اصول مدیریت رمز عبور امن را ببینید.

کاربردهای فراتر از CI/CD

بسیاری GitHub Actions را فقط برای تست و استقرار می‌شناسند اما این ابزار کاربردهای بسیار بیشتری دارد:

  • بررسی امنیت کد: با ابزارهایی مثل CodeQL می‌توان خودکار آسیب‌پذیری‌ها را پیدا کرد.
  • به‌روزرسانی وابستگی‌ها: با Dependabot می‌توان PRهای خودکار برای آپدیت پکیج‌ها ساخت.
  • ساخت مستندات: با هر تغییر در API، مستندات به‌روز تولید و منتشر شود.
  • آماری و گزارش‌گیری: اجرای اسکریپت‌های گزارش‌گیری در زمان مشخص.
  • اسکن امنیتی: بررسی کد برای الگوهای خطرناک، پیش از ادغام PR.
  • خودکارسازی فرآیندهای داخلی: مثل ساخت برچسب نسخه و انتشار release.

یکی از کاربردهای جالب که در پروژه‌های وردپرسی پیاده کردم: با GitHub Actions، هر شب یک اسکن امنیتی روی پلاگین‌ها و پوسته‌های پروژه انجام می‌شود و در صورت پیدا شدن آسیب‌پذیری، اعلان می‌فرستد. این کار به‌جای بررسی دستی، زمان تیم را آزاد می‌کند. برای مستندسازی، مستندسازی API و مستندسازی REST API با Swagger راهنمای کاملی دارند. برای ساختار مستندات، ساختاربندی پروژه توسعه وردپرس را ببینید.

پرسش‌های پرتکرار درباره GitHub Actions

تفاوت GitHub Actions و Jenkins چیست؟ GitHub Actions به مخزن یکپارچه است و نیاز به سرور جداگانه ندارد. Jenkins یک سرور CI مستقل است که به نگهداری نیاز دارد. برای پروژه‌های کوچک و متوسط، GitHub Actions انتخاب ساده‌تری است.

آیا GitHub Actions رایگان است؟ برای مخازن عمومی، بله و بدون محدودیت. برای مخازن خصوصی، سهمیه ماهانه رایگان دارد و بعد از آن، بر اساس دقیقه محاسبه می‌شود. برای پروژه‌های معمولی، این سهمیه کافی است.

چند workflow می‌توانم تعریف کنم؟ محدودیت سخت‌افزاری وجود ندارد. اما برای مدیریت ساده، معمولاً هر پروژه سه تا پنج workflow دارد: CI، CD، security scan و release.

آیا می‌توانم workflow را به صورت محلی تست کنم؟ بله، با ابزاری مثل act می‌توانید workflow را در محیط محلی اجرا کنید. این کار سرعت توسعه را بسیار بالا می‌برد چون نیازی به push در مخزن نیست.

چگونه از مصرف زیاد دقیقه جلوگیری کنم؟ با محدود کردن triggerها، استفاده از cache، انتخاب jobهای ضروری و کاهش ماتریس build. همچنین برای workflowهای طولانی، از self-hosted runner استفاده کنید.

برای یادگیری Git و GitHub، آموزش Git از صفر، دستورات ضروری Git و Pull Request در GitHub را ببینید. برای کار با GitLab CI که معادل این ابزار است، GitLab برای تیم‌های DevOps راهنمای کاربردی دارد. برای پروژه‌های وردپرسی، گیت در توسعه وردپرس و تست و دیباگ پروژه‌های وردپرس نکات ارزشمندی دارند. برای مدیریت پروژه، مدیریت پروژه با GitHub Projects و Jira را ببینید.

آنچه از پروژه‌های واقعی یاد گرفتم

سه چیز بعد از سال‌ها کار با GitHub Actions در ذهنم جا افتاده. اول، این ابزار یک بستر عمومی خودکارسازی است، نه فقط CI/CD. دوم، امنیت secrets و محدودسازی actionهای third-party باید از روز اول جدی گرفته شود. سوم، هر workflow باید هدف مشخصی داشته باشد؛ workflowهای زیاد و شلوغ، به جای کمک، بهره‌وری را می‌کاهند. برای اصول کدنویسی تمیز که این نظم را ساده‌تر می‌کند، اصول کدنویسی تمیز را ببینید. برای سایر ابزارهای DevOps، نقد و بررسی Docker، Kubernetes برای مبتدیان و ابزارهای ضروری توسعه را ببینید.

اگر تجربه‌ای از یک workflow خلاقانه در GitHub Actions دارید یا چالش خاصی در پیاده‌سازی آن داشتید، در دیدگاه بنویسید. برای من جالب است بدانم کدام کاربرد فراتر از CI/CD بیشترین ارزش را در پروژه شما ایجاد کرده است. ⚙️