قالب گردش کار


این سند توضیح می‌دهد که چگونه گردش‌کارهای یکپارچه‌سازی مستمر را برای یک ترک زبان Exercism و با استفاده از GitHub Actions (GHA) راه‌اندازی کنید. در آن بهترین شیوه‌ها و نمونه‌هایی ارائه شده است تا با استفاده از آن‌ها گردش‌کارهای یکپارچه‌سازی مستمر خودتان را سریع، قابل‌اعتماد و مقاوم بسازید. گردش‌کارهای GHA در این پوشه را می‌توان برای کار با هر ابزار یکپارچه‌سازی مستمری تطبیق داد، چون ساختار پایه یکسان می‌ماند.

این سند چنین کارهایی انجام می‌دهد:

  • ترسیم یک گردش‌کار ایده‌آل برای یکپارچه‌سازی مستمر
  • بررسی ملاحظات و توصیه‌ها
  • در اختیار گذاشتن چند قالب برای استفاده
  • ارائه‌ی راهنمایی برای مهاجرت از Travis

نمونه‌ی پیاده‌سازی این فایل‌های گردش‌کار در exercism/javascript قابل مشاهده است.

کمک: این کار خیلی زیاد به نظر می‌رسد 😓

بقیه‌ی سند برای توضیح نحوه‌ی کار این گردش‌کارها نوشته شده است. اگر عجله دارید و فقط می‌خواهید بدون بهینه‌سازی اسکریپت‌های PR از Travis یا Circle به GHA روی بیاورید، راهنمای حدوداً ۱۰ دقیقه‌ای ما را درباره‌ی مهاجرت از Travis ببینید.

کنش‌های یکپارچه‌سازی مستمر ترک

کنش‌های پیشنهادی برای بررسی یکپارچگی محتوای مخزن شما عبارت‌اند از:

۱. لینت‌کردن configlet برای بررسی config.json ۲. بررسی وجود استاب‌ها ۳. بررسی مستندات (v3 به فایل‌های جدید نیاز دارد؛ ممکن است این کار به configlet منتقل شود) ۴. لینت‌کردن تمرین‌ها با یک پیکربندی «نگهدارندگان» ۵. آزمودن تمرین‌ها با استفاده از فایل‌های example/exemplar (می‌تواند شامل مرحله‌ی ساخت باشد)

همچنین ممکن است کنش‌های مخصوص ترک هم وجود داشته باشد. برای مثال:

۱. بررسی یکپارچگی پیکربندی‌های تمرین ۲. بررسی قالب‌بندی فایل‌های تمرین

و شاید بخواهید بررسی‌های بیشتری برای راحتی کار داشته باشید، مانند:

۱. اطمینان از وجود CONTRIBUTING ۲. اطمینان از وجود یک lockfile معقول برای وابستگی‌ها ۳. اطمینان از معتبر بودن پیوندهای داخل فایل‌های مارک‌داون ۴. ...

توصیه‌ها

دفعات اجرای بررسی‌ها

برای هر کنش، به این فکر کنید که هر چند وقت یک‌بار باید اجرا شود.

  • لینت‌کردن configlet آن‌قدر مهم است (چون اگر config.json خراب شود، ممکن است کل ترک از کار بیفتد) که احتمالاً باید همیشه اجرا شود، اما فقط لازم است یک‌بار در هر کامیت اجرا شود.
  • بررسی وجود یا یکپارچگی فایل‌ها فقط لازم است یک‌بار در هر کامیت اجرا شود.
  • اگر قرار است یک ترک با چند نسخه‌ی زمان اجرا یا چند نسخه‌ی کامپایلر اجرا شود، ساخت و آزمودن تمرین‌ها باید برای هر نسخه‌ی پشتیبانی‌شده انجام شود
  • احتمالاً PRها فقط لازم است کنش‌ها را روی فایل‌های افزوده‌شده یا تغییرکرده اجرا کنند، اما چون یک فایل می‌تواند روی یک تمرین اثر بگذارد، اگر یکی از فایل‌های یک تمرین تغییر کند، ایمن‌تر آن است که کنش‌ها برای خودِ تمرین اجرا شوند.

می‌تواند بسیار مفید باشد که کنش‌هایی که باید اجرا شوند، به‌صورت محلی هم در دسترس باشند. یعنی اسکریپت‌هایی که کار واقعی را انجام می‌دهند، به‌صورت دستی هم قابل اجرا باشند. برای این کار، کنش را داخل فایل‌های گردش‌کار درون‌خطی نکنید، بلکه یک اسکریپت مستقل بسازید. برای مثال، بررسی استاب‌ها را می‌توان کاملاً با bash داخل فایل گردش‌کار نوشت، اما توصیه‌ی این‌جا آن است که به‌جای آن یک اسکریپت اجرایی جدید به اسم scripts/ci-check بسازید.

«اما این دستور خیلی کوتاه است، مثلاً eslint . --ext ts --ext tsx.»

وقتی این دستور باید به‌روزرسانی شود، حالا باید در همه‌ی جاها به‌روزرسانی شود: در مستندات، در فایل‌های گردش‌کار و در ذهن نگهدارندگان. بیرون کشیدن این دستور و گذاشتنش در یک اسکریپت همه‌ی این‌ها را حل می‌کند. خواندن یک فایل گردش‌کار هم می‌تواند خیلی دلهره‌آور باشد.

بررسی‌ها روی PRهایی که تمرین‌ها در آن‌ها تغییر می‌کنند

اسکریپت‌های scripts/pr و scripts/pr-check (به قالب‌ها نگاه کنید) با چند آرگومان اجرا می‌شوند، یکی برای هر فایلی که در این PR تغییر کرده یا اضافه شده است. برای مثال، اگر two-fer به‌روزرسانی شده باشد، فراخوانی ممکن است چنین شکلی داشته باشد:

scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext

توصیه می‌شود کنش‌ها را روی تمرین تغییرکرده اجرا کنید، نه روی فایل تغییرکرده. دلیلش این است که تغییر یک فایل احتمالاً تغییرهای کل تمرین را در پی دارد (به پیکربندی و بسته‌ها فکر کنید).

آماده نیستید؟ / پیچیده است؟

پیش از پیاده‌سازی این بهینه‌سازی، می‌توان با خیال راحت آن را نادیده گرفت! راهنمای مهاجرت اشاره می‌کند که در مرحله‌ی بعدی اضافه می‌شود. اگر آرگومان‌های ورودی نادیده گرفته شوند، همه‌ی بررسی‌ها روی همه‌ی تمرین‌ها اجرا می‌شوند. این کاملاً اشکالی ندارد. فقط زمان بیشتری می‌برد.

بررسی‌های یکپارچگی

اگر ترک یک فایل وابستگی «سطح‌بالا» و/یا فایل‌های پیکربندی دیگری دارد، یک مرحله‌ی یکپارچگی اضافه کنید (که در کنار scripts/sync یا bin/sync قرار می‌گیرد و همه‌ی فایل‌های پیکربندی را به همه‌ی تمرین‌ها کپی می‌کند) تا مطمئن شوید فایل‌های سطح‌بالا/پایه با فایلی که به پوشه‌های تمرین کپی شده یکسان‌اند. حالا می‌توان وابستگی‌ها را به‌روزرسانی و در سراسر مخزن همگام‌سازی کرد و مطمئن شد که همه‌ی تمرین‌ها پیکربندی یکسانی دارند.

یک روش رایج برای انجام این کار استفاده از یک checksum است. اوبونتو (و توزیع‌های دیگر لینوکس) ابزاری به اسم sha1sum دارد، اما استفاده از هر روشی برای هش کردن یا کاهش فایل پیکربندی (md5، sha1، crc32) به یک مقدار checksum هم جواب می‌دهد:

$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md

بررسی‌های امنیتی

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

برای مثال:

- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1

اگر ابزارها برای مدیریت وابستگی‌ها lockfile دارند، در نظر بگیرید که آن را در مخزن ثبت کنید و از یک «lockfile قفل‌شده» داخل فایل‌های گردش‌کار استفاده کنید. برای مثال: npm ci، yarn install --frozen-lockfile و bundle install --frozen. این کار تضمین می‌کند که هنگام تغییر وابستگی‌ها، lockfile به‌روز باشد و جلوی ورود بسته‌های مخرب را می‌گیرد.

قالب‌ها

در این پوشه دست‌کم قالب‌های زیر وجود دارد:

  • configlet.yml: این گردش‌کار آخرین باینری configlet را دریافت می‌کند و این مخزن را لینت می‌کند. روی هر کامیت اجرا می‌شود. برای PRها، روی خود کامیت و یک درخت «پس از ادغام» اجرا می‌شود.
  • ci.yml: این گردش‌کار فقط روی شاخه‌ی main اجرا می‌شود، یک‌بار در هر کامیت. ۱. اجرای یک دستور «pre-check» (بررسی استاب‌ها، لینت، مستندات و غیره) برای همه‌ی تمرین‌ها ۲. اجرای یک دستور «ci» (ساخت و آزمون) برای چند نسخه، برای همه‌ی تمرین‌ها
  • pr.ci.yml: این گردش‌کار فقط روی PRها اجرا می‌شود، یک‌بار در هر کامیت. ۱. اجرای یک دستور «pre-check» (بررسی استاب‌ها، لینت، مستندات و غیره) برای فایل‌های تغییرکرده ۲. اجرای یک دستور «ci» (ساخت و آزمون) برای چند نسخه، برای تمرین‌های تغییرکرده

گردش‌کارهای غیر PR هم می‌توانند از طریق workflow_dispatch فعال شوند.

در بالای هر فایل فهرست شده است که کدام «اسکریپت‌ها» باید موجود باشند. اگر می‌خواهید این‌ها باینری باشند، scripts/xxx را با bin/xxx جایگزین کنید. برخی ابزارها الزاماً باینری‌ها را داخل پوشه‌ی bin می‌خواهند.

  • scripts/ci: اسکریپتی که باید همه‌ی تمرین‌ها را با استفاده از راه‌حل‌های نمونه در برابر آزمون‌ها بسازد و بیازماید
  • scripts/ci-check: اسکریپتی که باید همه‌ی تمرین‌ها را لینت کند و به‌صورت اختیاری استاب‌ها، یکپارچگی پیکربندی و موارد دیگر را بررسی کند
  • scripts/pr: مانند scripts/ci، اما باید فقط تمرین‌های برگرفته از مسیرهای ورودی را اجرا کند
  • scripts/pr-check: مانند scripts/ci-check، اما باید فقط برای فایل‌های برگرفته از مسیرهای ورودی یا تمرین‌های حاصل از آن‌ها اجرا شود

عیب‌یابی

اگر به مشکلی برخوردید یا می‌خواهید کسی گردش‌کارهایتان را بررسی کند، لطفاً به تیم @exercism/github-actions پیام بدهید.

یک فایل سطح‌بالا را تغییر داده‌اید که باید اجرای یکپارچه‌سازی مستمر را روی همه‌ی تمرین‌ها فعال کند

در زمان نگارش این متن، pr.ci.yml فقط آزمون «پسوند» را مجاز می‌داند. در حالت ایده‌آل، این باید به‌روزرسانی شود تا هر وقت فایل‌های مشخصی تغییر کردند (مثلاً باینری اجرای آزمون‌ها) همیشه فعال شود. اما این تغییرها اغلب کم‌تعدادند و توسط نگهدارندگان انجام می‌شوند، پس اینکه ci.yml همیشه و برای همه‌چیز روی شاخه‌ی main اجرا می‌شود، احتمالاً به‌قدر کافی ایمن است.

یک فایل scripts/xxx روی ویندوز ساخته‌اید و حالا روی {سیستم‌عامل دیگر} کار نمی‌کند

به‌صورت پیش‌فرض، فایل‌هایی که روی ویندوز ساخته می‌شوند، فراداده‌ای درباره‌ی اجرایی‌بودنشان در git-index ثبت نمی‌کنند، چون مدل مجوزها در ویندوز متفاوت است. Git به‌صورت پیش‌فرض از فراداده‌ی git-index استفاده می‌کند تا تعیین کند آیا فایل باید روی سیستم‌های مبتنی بر POSIX اجرایی باشد یا نه، و در نتیجه فایل scripts/xxx را غیرقابل‌اجرا می‌کند.

git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"