کاربرد Action ها در Github

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

حالا مثلا ما چجور کارایی میتونیم بکنیم؟ تقریبا میشه گفت هرکاری رو میشه باهاش کرد. کامپایل کردن پروژه، تست کردن، پابلیش کردن و...

من معمولا فایل های خروجی که برای پروژه هام میگیرم بدلیل استفاده از ویژگی SelfContained و ایمیج های ReadyToRun برای اجرای سریعتر، معمولا حجمی حدود 140 مگ داره، حالا وقتی فشردش میکنم حجمش حدود 50 مگ میشه که اگر من بخوام هر دفعه که از برنامه خروجی میگیرم بیام فایل خروجی رو فشرده کنم و اون رو در گیتهاب اپلود بکنم هم فرایندی زمانبر هست هم اینکه تکراری و خسته کننده در نتیجه تصمیم گرفتم که از اکشن گیتهاب برای خودکارسازی این فرایند استفاده کنم.

توی این نوشته کوتاه میخوایم یه اکشن بنویسیم که بیاد بر اساس سورس کد موجود روی گیتهاب برنامه رو بیلد کنه، فایل اجرایی رو بصورت فایل فشرده Zip ایجاد کنه و در نهایت این فایل فشرده رو در قسمت Release گیتهاب منتشر کنه/

برای شروع کار اول باید در مخزن پروژه در سایت گیتهاب، به قسمت Action بریم.

حالا روی قسمت New workflow باید کلیک کنیم

اینجا شما میتونید از قالب های پیشفرض موجود هر کدوم رو خواستید انتخاب کنید، اما من ترجیح میدم کارمو با یه قالب خالی شروع کنم پس روی set up a workflow yourself کلیک میکنیم

کدهای پیشفرضی که وجود داره رو پاک کنید تا مثل عکس زیر یه فایل کاملا تمیز و خالی رو داشته باشیم

نکته ای که باید دقت کنید، اسم و مسیر فایل هستش، مسیر فایل رو اصلا نباید تغییر بدید، ولی اسم فایل رو میتونید اصلاح کنید ولی توجه کنید که پسوند فایل باید yml باشه.

حالا بریم سراغ نوشتن کدهای اکشن:

اول از همه کد زیر رو مینویسیم

name: &quotPublish&quot

این خط اسم اکشن مارو مشخص میکنه که قراره توی لیست workflow ها نمایش داده بشه

کدی بعدی که باید بنویسیم (در خط بعدی) باید مشخص بکنیم که این اکشن چه زمانی اجرا بشه تریگر های زیر استفاده بیشتری دارند:

push = هر زمان که کامیتی رو روی گیتهاب پوش کنید اکشن اجرا میشه

pull_request = هر زمان که یه پول رکوئست رو مرج کنید اجرا میشه

workflow_dispatch = برنامه نویس خودش میتونه با کلیک روی دکمه مشخصی در قسمت اکشن ها، اکشن موردنظر رو اجرا کنه

لیست کامل تریگر هارو میتونید اینجا مطالعه کنید.

ما از push استفاده میکنیم البته یکم تغییرش میدیم زمانی که شامل تگ هم باشه اجرا باشه

on:
  push:
    tags:
      - &quotv*&quot

نکته ای که هست ما در اخر این دستور از v* استفاده کردیم که داره اشاره میکنه اگر تگ بصورت v1.0.0 بود اجرا بشه اون * میتونه هر عددی باشه. حالا در پایان بهتر متوجه میشید.

3 تا متغیر ایجاد میکنیم تا محل فایل پروژه، اجرایی و فشرده رو نگه داره تا فایل اکشنمون زیاد شلوغ نشه

env:
  PROJECT_PATH: src/HandySub/HandySub.csproj
  ZIP_PATH: src/HandySub/bin/Release/net5.0-windows/win-x86/publish/HandySub-x86.zip
  EXE_PATH: src/HandySub/bin/Release/net5.0-windows/win-x86/publish/HandySub.exe

حالا باید دستورات خودکار سازی رو بنویسیم همه دستورات باید در قسمت jobs نوشته بشن

jobs:
  deploy:
    runs-on: windows-latest

به قسمت runs-on توجه کنید اینجا داریم میگیم که اکشن ما روی سرور ویندوزی و اخرین نسخه از اون اجرا بشه که اگر نیاز داشتید میتونید از linux استفاده کنید.

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

قدم اول اینه که اکشن رو اماده کنیم اکثر دستورات مهم توی این اکشن موجوده

    steps:
      - name: Initialize Actions
        uses: actions/checkout@v2

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

      - name: Initialize .Net
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.x

قبل از بیلد کردن پروژه باید کتابخانه ها و بسته های ناگت رو restore کنیم تا بیلد خطا نداشته باشه

      - name: Restore Project
        run: dotnet restore ${{ env.PROJECT_PATH }}

حالا دستور خروجی گرفتن رو مینویسیم (بدلایلی که نمیدونم چیه حتما باید توی فایل csproj ، runtimeidentifier پروژه مشخص باشه که اینجا ما از win-x86 استفاده کردیم در غیر این صورت خطا میگیرید)

      - name: Publish Project
        run: dotnet publish ${{ env.PROJECT_PATH }} -c Release --self-contained -r win-x86 --no-restore

حالا که فایل اجرایی رو ایجاد کردیم باید اون رو بصورت فشرده zip دربیاریم برای این کار از یه اکشن دیگه کمک میگیریم اول به اصطلاح using میکنیم اون رو بعد ازش استفاده میکنیم. 2 تا ورودی داره files و dest که به ترتیب باید ادرس فایل ها و محل ذخیره زیپ رو بهش بدیم که ما از متغیر هایی که قبلا ایجاد کردیم استفاده میکنیم.

      - name: Create Zip File
        uses: papeloto/action-zip@v1
        with:
          files: ${{ env.EXE_PATH }}
          dest: ${{ env.ZIP_PATH }}

در قدم اخر میایم از یه اکشن دیگه برای ساخت Release در قسمت گیتهاب کمک میگیریم، دقت کنید که برای اپلود کردن فایل زیپ داخل این Release، ما باید توکن و id این ریلیز رو ذخیره کنیم که اینجا میریزم داخل متغیر GITHUB_TOKEN و id، حالا این توکن رو از کجا میاریم؟ از قسمت secrets خود گیتهاب که شامل یسری اطلاعات از جمله توکن میشه، همچنین ما اسم تگ رو از طریق github.ref دریافت میکنیم (همون تگی که پوش کردیم تو گیتهاب)

      - name: Initialize Release
        uses: actions/create-release@v1
        id: create_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}      

حالا نوبته اینه که فایل زیپ رو اپلود کنیم، باز از یه اکشن دیگه کمک میگیریم، توکنی که قبلا ذخیره کردیم رو بهش میدیم همراه با فایل زیپ و در پایان به کمک id که قبلا ذخیره کردیم لینک فایل اپلود شده رو ازش دریافت میکنیم.

      - name: Create Release    
        uses: csexton/release-asset-action@v2
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          file: ${{ env.ZIP_PATH }}
          release-url: ${{ steps.create_release.outputs.upload_url }}

کد کامل رو اینجا ببینید

در اخر بر روی دکمه سبز رنگ بالا سمت راست start commit کلیک کنید تا تغییرات ثبت بشه.

برگردید به پروژه خودتون ترمینال رو باز کنید و یک تگ جدید ایجاد کنید.

git tag v1.0.0

حالا تگ ایجاد شده رو پوش کنید

git push origin tag v1.0.0

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

در قسمت ریلیز میتونید ببینید که ریلیز توسط ربات گیتهاب ایجاد شده