مقالات

ایجاد گردش کار GitHub CI عالی برای تیم ظاهری شما


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

اکنون بیش از یک سال است که این سرویس انتخابی من برای خطوط لوله خودکار CI/CD بوده است. را workflow سینتکس برای شروع آسان است و دارای مجموعه گسترده ای از ویژگی ها است که به شما کمک می کند صنایع دستی CI شما به روشی که شما و تیمتان می خواهید تجربه کنید.

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

چه چیزی می تواند یک گردش کار “خوب” GitHub CI را تشکیل دهد؟

من بهترین “پاسخ مهندسی” خود را به این سوال می دهم: بستگی داره تیم شما ممکن است نیازها یا اهداف خاصی داشته باشد که باعث می شود برخی از توصیه های من آنقدر که می تواند برای شما مفید نباشد. با این حال، برای این مقاله به دستورالعمل‌هایی نیاز داریم که به اعتقاد من برای ایجاد گردش‌های کاری مؤثر GitHub جهانی خواهد بود، مانند:

  • صرفه جویی در هزینه: «دقایق ساخت» را به کمترین مقدار ممکن کاهش دهید تا در پایان ماه صورتحساب هنگفتی نداشته باشید.

  • کارآمد: زمان تیم شما با ارزش است، گردش کار باید تا حد امکان سریع باشد، اما اگر مشکلی پیش بیاید سریع شکست می خورد.

  • خوب معماری: هر مرحله یک هدف دارد و ممکن است به مراحل دیگر بستگی داشته باشد. این نیز به معنای انجام ندادن «مراحل بیهوده» است.

اکنون که آن دستورالعمل ها را ایجاد کرده ایم، بیایید به یکی از مهم ترین نکات در این مقاله نگاه کنیم.

یک گردش کار برای حکومت بر همه آنها

بیایید به مجموعه ای از وظایفی که تیم فرانتند در هر روابط عمومی انجام می دهد نگاه کنیم:

  1. مگس می کند

  2. قالب بندی

  3. بررسی تایپ

  4. تست تک

  5. ساخت و ساز

  6. تست های انتها به انتها، شاید در مرورگرهای مختلف

اجرای آنها در گردش های کاری جداگانه ممکن است ساده ترین راه برای طراحی این وظایف به نظر برسد. با این حال، اگر چیزی به سادگی lint کار شکست خورد، هیچ راهی برای متوقف کردن کارهای گران قیمت شما وجود ندارد build یا آزمایشات سرتاسری شما از یک اجرا. و دوستان من خیلی موثر نیست.

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

برای مقابله با این، من انتخاب کردم تمام گردش های کاری من را در یک مجموعه ترکیب کنم. تمام کارهایی که قبلاً گردش کار مستقل بودند، بخشی از همان گردش کار منحصر به فرد شدند، اما این بار مشاغل.

نمونه کار گردش کار Github CI.

11

- name: Checkout Commit

12

uses: actions/checkout@v2

13

- name: Use Node.js ${{ matrix.node }}

14

uses: actions/setup-node@v1

16

node-version: ${{ matrix.node }}

خوبی کار این است که می توانید آنها را به صورت متوالی یا موازی اجرا کنید همانطور که شما می خواهید! GitHub یک کلمه کلیدی مفید به نام ارائه می دهد needs که به شما امکان می دهد یک یا چند شغل را به عنوان وابستگی تنظیم کنید، در نتیجه از اجرای یک کار جلوگیری می کند مگر اینکه کارهای وابسته با موفقیت به پایان برسد. این به ما امکان می دهد:

  • به سرعت گردش کار را شکست دهید. اگر یک کار کلیدی با شکست مواجه شود، گردش کار در اسرع وقت در روابط عمومی شما به عنوان ناموفق علامت گذاری می شود

  • از انجام کارهای بیهوده پرهزینه خودداری کنید هنگام اجرای یک گردش کار “محکوم به شکست”.

نمونه ای از کارهایی که به صورت موازی و متوالی اجرا می شوند

13

- name: Checkout Commit

14

uses: actions/checkout@v2

15

- name: Use Node.js ${{ matrix.node }}

16

uses: actions/setup-node@v1

18

node-version: ${{ matrix.node }}

23

runs-on: ubuntu-latest

28

- name: Checkout Commit

29

uses: actions/checkout@v2

30

- name: Use Node.js ${{ matrix.node }}

31

uses: actions/setup-node@v1

33

node-version: ${{ matrix.node }}

38

runs-on: ubuntu-latest

42

needs: [type-check, unit-test]

44

- name: Checkout Commit

45

uses: actions/checkout@v2

46

- name: Use Node.js ${{ matrix.node }}

47

uses: actions/setup-node@v1

49

node-version: ${{ matrix.node }}

ممکن است تعجب کنید: چه کارهایی باید به صورت موازی انجام شود و چه کارهایی باید به ترتیب انجام شود؟ این به نیازهای تیم شما بستگی دارد.

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

تصویر زیر جریان کاری GitHub را نشان می دهد که CI را برای این وبلاگ تامین می کند. شما احتمالاً شباهت هایی با هم دارند:

تصویری از یک گردش کاری موفق Github که هر شغل و وابستگی آنها به یکدیگر را نشان می دهد.
تصویری از اجرای ناموفق جریان کاری Github. توجه کنید که چگونه شکست کار
تصویری از اجرای ناموفق جریان کاری Github. توجه کنید که چگونه شکست کار “ساخت” باعث ایجاد دو کار موازی e2e نشد، زیرا آنها برای موفقیت به این کار وابسته بودند.

همانطور که می بینید، با ترکیب همه گردش های کاری ما در یک و با دقت انتخاب کار برای موازی سازی یا اجرای متوالی، در نهایت به نحوه عملکرد خط لوله CI و وابستگی های بین هر یک از مراحل آن، دید بهتری خواهیم داشت.

اکنون که تمام مراحل CI در یک گردش کار واحد ترکیب شده‌اند، چالش اصلی این است که بفهمیم چگونه می‌توانیم آنها را تا حد امکان کارآمد کنیم. به اشتراک گذاشتن نتایج حیاتی کار.

با این حال، از همان ابتدا مشخص نیست که چگونه می توان نتایج کار را با سایر وظایف GitHub CI به اشتراک گذاشت. دو راه وجود دارد که من آنها را “موثر” یافته ام:

  1. با استفاده از کش با actions/cache

  2. آپلود/دانلود مصنوعات به ترتیب با استفاده از actions/upload-artifact و actions/download-artifact

اولین مورد “عالی” است، اما فقط برای کارهایی که تکراری هستند و نتایجی دارند که در طول زمان تغییر چندانی نمی کنند، مانند نصب وابستگی های NPM.

نمونه ای از اشتراک گذاری وابستگی های npm در چندین کار GitHub CI

10

- name: Checkout Commit

11

uses: actions/checkout@v2

12

- name: Use Node.js ${{ matrix.node }}

13

uses: actions/setup-node@v1

15

node-version: ${{ matrix.node }}

16

- name: Cache yarn dependencies

17

uses: actions/cache@v2

18

id: cache-dependencies

21

key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}

23

${{ runner.os }}-yarn-

24

- name: Install Dependencies

28

if: steps.cache-dependencies.outputs.cache-hit != 'true'

30

yarn install --force --non-interactive

34

runs-on: ubuntu-latest

40

- name: Checkout Commit

41

uses: actions/checkout@v2

42

- name: Use Node.js ${{ matrix.node }}

43

uses: actions/setup-node@v1

45

node-version: ${{ matrix.node }}

49

- name: Restore yarn dependencies

50

uses: actions/cache@v2

51

id: cache-dependencies

54

key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}

56

${{ runner.os }}-yarn-

با این حال، استفاده از مصنوعات چیزی است که تفاوت قابل توجهی در عملکرد گردش کار GitHub CI من ایجاد کرد.

برای مثال، اگر 2 کار دارید که به ترتیب تست‌های e2e خود را روی فایرفاکس و کروم اجرا می‌کنند، نمی‌خواهید رابط کاربری خود را دو بار بسازید، زیرا این کار می‌تواند تعداد “دقایق قابل پرداخت” را برای اجرای CI شما به میزان قابل توجهی افزایش دهد. راه حل بهینه در اینجا شامل داشتن یک است build قبل از اجرای آزمایشات پایان به انتها کار کنید فقط یک بار و بعد از آن مصنوعات ساخت را به اشتراک بگذارید با شما chrome-end-to-end و firefox-end-to-end مشاغل

برای رسیدن به این هدف باید از اهرم استفاده کنیم actions/upload-artifact و actions/download-artifact:

  • پس از موفقیت آمیز بودن ساخت، از آن استفاده کنید actions/upload-artifact برای آپلود مصنوعات ساخت خود

  • سپس استفاده کنید action/download-artifact از هر کاری که می خواهید این خروجی را دانلود کرده و از آن استفاده کنید

توجه به این نکته مهم است که این ترفند فقط به این دلیل کار می کند ما هر مرحله CI را در یک گردش کار اجرا می کنیم. شما فقط می توانید مصنوعاتی را در یک گردش کاری بارگیری کنید که در طول اجرای همان گردش کار آپلود شده اند.

برای به اشتراک گذاشتن نتیجه ساخت، مصنوعات را آپلود و دانلود کنید

13

- name: Upload build artifacts

14

uses: actions/upload-artifact@v2

27

- name: Download build artifacts

28

uses: actions/download-artifact@v2

35

uses: cypress-io/github-action@v2.10.1

45

- name: Download build artifacts

46

uses: actions/download-artifact@v2

51

uses: cypress-io/github-action@v2.10.1

هنگام آپلود مصنوعات، گزینه روزهای نگهداری را تنظیم کنید

9

- name: Upload build artifacts

10

uses: actions/upload-artifact@v2

آخرین نکته من و شاید مورد علاقه من به دلیل سادگی آن است پایان دادن به اجرای گردش کار تکراری.

اغلب برای من اتفاق می‌افتد: من با شعبه فعلی تمام شده‌ام و تصمیم می‌گیرم کدم را فشار دهم و یک PR باز کنم، بنابراین یک اجرای گردش کار را آغاز می‌کنم. سپس چند ثانیه بعد متوجه شدم که فراموش کردم این یکی را شروع کنم console.log یا در جایی اشتباه تایپی کرده اید و باید تغییر دیگری را فشار دهید، بنابراین اجرای گردش کار دیگری را راه اندازی می کند.

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

برای جلوگیری از این نوع چیزها، گیت هاب اخیراً مفهومی را معرفی کرده است همزمانی گردش کار.

اس concurrency کلمه کلیدی شما می توانید ایجاد کنید گروه موازی برای گردش کار (یا شغل) شما. اگر اجرای فعلی در حال اجرا باشد، هر گونه اجرای گردش کار از همان گروه همزمان را به عنوان “در انتظار” علامت گذاری می کند. شما همچنین می توانید تصمیم بگیرید هر فرآیند کاری فعلی را در همان گروه موازی لغو کنید هر بار که یک گردش کار جدید به صف اضافه می شود.

نمونه ای از یک گردش کار GitHub با استفاده از گروه های همزمان

10

group: ${{ github.head_ref }}

13

cancel-in-progress: true

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

بنابراین، اکنون که تمام نکات را برای ایجاد گردش کاری Github CI کامل برای برآورده کردن نیازهای CI یک تیم frontend بررسی کردیم، بیایید نگاهی به نحوه انطباق آنها با دستورالعمل‌هایی که قبلاً ایجاد کردیم بیاندازیم:

آیا باعث صرفه جویی در هزینه ها می شود؟
بله، ما مطمئن شده‌ایم که نتیجه مراحل گران‌قیمت مانند به‌عنوان مثال را به اشتراک بگذاریم build و برای کش کردن مراحل تکراری که باید در طول گردش کار انجام دهیم، مانند نصب وابستگی‌هایمان.

آیا موثر است؟
مطمئنا کارآمدتر از اجرای هر کار در یک گردش کاری جداگانه! ما نه تنها مشاغل آزاد را موازی می کنیم e2e-tests-firefox و e2e-tests-chromeما همچنین مطمئن می شویم که به لطف استفاده از هر گردش کار تکراری را لغو می کنیم گروه های همزمان.

آیا از نظر معماری خوب است؟
همانطور که در تصویر قبلی نشان داده شده در این پست وبلاگ دیدیم، اکنون به راحتی می توان تمام مراحل و وابستگی های آنها را تجسم کرد. ترکیب هر کار در یک گردش کار واحد و طراحی آن وظایف با استفاده از needs کلمه کلیدی درک کل خط لوله CI را آسانتر کرد.

به یک مثال کامل نیاز دارید؟ نگران نباش، من شما را تحت پوشش قرار داده ام 🙌! می توانید گردش کار Github CI من را شامل تمام نکات و مثال های این مقاله در مخزن GitHub این وبلاگ بیابید. این کاملاً ضخیم و طولانی است، به همین دلیل است که من آن را مستقیماً در اینجا ادغام نکردم، زیرا ممکن است حواس‌تان را پرت کند.

امیدوارم برخی از نکاتی که در این پست وبلاگ ارائه کرده‌ام به شما و تیمتان کمک کند تا گردش‌های کاری GitHub خود را بهبود ببخشید و در نتیجه به یک خط لوله سریع و قابل اعتماد CI برای پروژه‌های فرانت‌اند مورد علاقه خود برسید! آیا نکات دیگری وجود دارد که آرزو می کنید در این مقاله گنجانده می شدم؟ سایر اسرار GitHub CI که باعث شد تیم شما قابل ذکر باشد؟ مثل همیشه، با ما تماس بگیرید! من دوست دارم در مورد آنچه برای شما مفید است بیشتر بیاموزم و آنها را برای بهبود بیشتر این مقاله آزمایش کنم!


Source link

نوشته های مشابه

دیدگاهتان را بنویسید

همچنین ببینید
بستن
دکمه بازگشت به بالا