GitHub Actions: بهترین روش‌ها


این سندِ در حال تکمیل مجموعه‌ای از بهترین شیوه‌ها برای استفاده از GitHub Actions است. اگر پیشنهاد یا مطلبی برای افزودن دارید، لطفاً در GitHub یک pull request باز کنید!

مجموعه‌ی بهترین شیوه‌ها

برای workflowها مهلت زمانی تعیین کنید

به‌طور پیش‌فرض، GitHub Actions اگر workflowها تا ۶ ساعت تمام نشوند، آن‌ها را متوقف می‌کند. بسیاری از workflowها به این مقدار زمان برای پایان یافتن نیاز ندارند، اما گاهی خطاهای پیش‌بینی‌نشده رخ می‌دهد یا یک job معلق می‌ماند تا اینکه اجرای workflow شش ساعت پس از شروعش متوقف شود. بنابراین توصیه می‌شود مهلت زمانی کوتاه‌تری تعیین کنید.

مهلت زمانی ایده‌آل به خود workflow بستگی دارد، اما ۳۰ دقیقه معمولاً برای workflowهای موجود در مخزن‌های Exercism بیش از اندازه کافی است.

این کار مزایای زیر را دارد:

  • PRها نصف روز در انتظار CI نمی‌مانند، مشکلات زودتر شناسایی می‌شوند یا می‌توان اجرای workflow را دوباره شروع کرد.
  • تعداد کل buildهای موازی محدود است، و اگر jobهای معلق زود لغو شوند، برای PRهای دیگر مشکلی ایجاد نمی‌کنند.

مثال

jobs:
  configlet:
    timeout-minutes: 30
    runs-on: ubuntu-latest
    steps:
      - [...]

بررسی کنید که آیا به actionهای (طرف ثالث) واقعاً نیاز هست

با actionها باید مانند وابستگی‌ها در زبان برنامه‌نویسی محبوبتان رفتار کنید1؛ آن‌ها کدی هستند که نویسندگان ثالث، خارج از کنترل Exercism، نوشته‌اند. حتی اگر به نویسندگان action اعتماد داشته باشید، ممکن است یک تصاحب خصمانه‌ی مخزن رخ دهد که به‌طور غیرمستقیم به آن افراد دسترسی به مخزن‌های Exercism، از جمله دسترسی نوشتن، می‌دهد.

بنابراین باید با دقت بررسی کنید که آیا افزودن یک action جدید واقعاً ارزشش را دارد یا بهتر است کد را به یک action (جدید) تحت کنترل Exercism منتقل کنید.

همچنین بررسی کنید که آیا action به‌طور فعال نگهداری می‌شود یا نه، مثلاً با بررسی فعالیت اخیر مخزن یا اطمینان از اینکه action بخشی از یک سازمان است و نه یک حساب شخصی.

actionهایی که توسط GitHub یا سازمان Exercism منتشر شده‌اند، عموماً می‌توان بدون بررسی خاص، نسبتاً ایمن دانست.

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

به‌طور پیش‌فرض، توکن دسترسی‌ای که به workflow داده می‌شود، مجوزهای گسترده‌ای دارد، هم برای خواندن و هم برای نوشتن.

اصل کمترین سطح دسترسی را نیز باید در مورد workflowها به کار برد.

می‌توانید تعیین کنید که یک workflow به کدام مجوزها نیاز دارد، به‌صورت جداگانه برای هر workflow.

مثال

اگر یک workflow فقط به خواندن محتوای یک مخزن نیاز دارد و نه نوشتن در آن، مثلاً چون یک بررسی معمولی CI است، می‌توانید توکن را به شکل زیر محدود کنید:

permissions:
  contents: read

برای فهرست کامل مجوزها، مستندات GitHub را ببینید.

actionها را به SHAها پین کنید

هنگام استفاده از actionهای دیگر، آن‌ها را به یک کامیت (از طریق SHA آن) پین کنید، نه به یک شاخه یا برچسب. این کار تضمین می‌کند که هر بار همان کد اجرا شود، چیزی که هنگام پین کردن به یک شاخه یا برچسب تضمین نمی‌شود.

این کار دو مزیت دارد:

۱. build شما را پایدار می‌کند ۲. مانع از آن می‌شود که یک مهاجم شاخه/برچسب را طوری تغییر دهد که به کد مخرب اشاره کند

تنها استثنای این قاعده می‌تواند actionهایی باشد که خودمان (Exercism) ساخته‌ایم.

پیدا کردن SHA کامیت

معمولاً می‌خواهید به SHA کامیت یک انتشار مشخص پین کنید. برای پیدا کردن SHA کامیت یک انتشار، به صفحه‌ی انتشارهای مخزن آن action بروید (مثلاً https://github.com/actions/checkout/releases). انتشار مورد نظرتان را پیدا کنید و روی SHA کوتاه‌شده (مثلاً a12a394) که در بخش خلاصه، سمت چپ انتشار فهرست شده است کلیک کنید. سپس به صفحه‌ی جزئیات انتشار هدایت می‌شوید که SHA کامیت کاملِ قابل استفاده را فهرست می‌کند.

مثال

- name: Checkout code
  uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846

test runnerها را به یک نسخه پین کنید

بیشتر workflowها روی runnerهای پشتیبانی‌شده‌ی GitHub اجرا می‌شوند. هنگام استفاده از یکی از این runnerها، به‌جای آخرین نسخه از یک نسخه‌ی مشخص استفاده کنید.

این کار تضمین می‌کند که workflow همیشه روی همان runner اجرا شود، که build شما را پایدار می‌کند.

مثال

از این استفاده کنید:

runs-on: ubuntu-22.04

به‌جای این:

runs-on: ubuntu-latest

راه‌اندازی یک راهبرد همزمانی را در نظر بگیرید

اغلب اجرای CI روی کامیت‌های میانی، اگر در این فاصله کامیت جدیدتری push شده باشد، نه لازم است و نه مفید.

می‌توانید یک راهبرد همزمانی پیکربندی کنید تا workflowهای در حال اجرا در همان زمینه به‌طور خودکار لغو شوند.

مثال

برای لغو buildهای میانی در یک PR، می‌توانید از تنظیمات همزمانی زیر استفاده کنید:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
اعلامیه‌ی طرف ثالث

مثال بالا بر پایه‌ی workflow CI در PkgTemplates.jl است که تحت مجوز MIT منتشر شده است:

مجوز MIT

حق نشر (c) ۲۰۱۷-۲۰۲۰ Chris de Graaf، Invenia Technical Computing Corporation

بدین‌وسیله به هر شخصی که نسخه‌ای از این نرم‌افزار و فایل‌های مستندات مرتبط با آن («نرم‌افزار») را به‌صورت رایگان دریافت می‌کند، اجازه داده می‌شود که بدون هیچ محدودیتی با نرم‌افزار کار کند، از جمله و بدون محدودیت حق استفاده، کپی، تغییر، ادغام، انتشار، توزیع، اعطای مجوز فرعی و/یا فروش نسخه‌هایی از نرم‌افزار، و اجازه دادن به افرادی که نرم‌افزار در اختیارشان قرار می‌گیرد تا همین کار را انجام دهند، مشروط بر رعایت شرایط زیر:

اعلامیه‌ی حق نشر بالا و همین اعلامیه‌ی اجازه باید در تمام نسخه‌ها یا بخش‌های قابل‌توجهی از نرم‌افزار گنجانده شود.

نرم‌افزار «همان‌گونه که هست» ارائه می‌شود، بدون هیچ‌گونه ضمانت، صریح یا ضمنی، از جمله اما نه محدود به ضمانت‌های قابلیت فروش، تناسب برای هدفی خاص و عدم نقض حقوق دیگران. در هیچ حالتی نویسندگان یا دارندگان حق نشر در قبال هیچ ادعا، خسارت یا مسئولیت دیگری مسئول نیستند، چه در یک اقدام قراردادی، چه نقض حق یا غیر آن، که از نرم‌افزار یا استفاده از آن یا سایر معاملات مرتبط با نرم‌افزار ناشی شود.

بررسی کنید که واقعاً به کدام محرک‌ها نیاز هست

راهنمای «تقویت امنیت GitHub Actions» را بخوانید

شیوه‌های ذکرشده در بالا به‌هیچ‌وجه جامع نیستند. برای یک راهنمای کامل درباره‌ی شیوه‌های امنیتی خوب برای استفاده‌ی ایمن از GitHub Actions، راهنمای امنیتی GitHub را ببینید.

چک‌لیست workflow

می‌توانید از چک‌لیست زیر برای بررسی اینکه آیا یک workflow بهترین شیوه‌ها را رعایت می‌کند استفاده کنید. این چک‌لیست قرار نیست کامل باشد، بلکه روی مهم‌ترین موارد تمرکز دارد.

نسخه‌ای برای کپی‌پیست، مثلاً برای PRها

  1. مگر اینکه زبان از اکوسیستم npm استفاده کند. ↩