نظرة على GitHub Actions واستخدامها في البيان

22 دقائق للقراءة

مقدمة

مع تحديث البيان من نافذة التقنية، كنا نقضي وقت طويل لتنفيذ الخطوات لإنشاء إصدار جديد، تجهيز الملفات ورفعها والقيام بالكثير من الخطوات، وقد ننسا بعضها ونحتاج لإعادة العمل.

قمت بالبحث عن حلول بديلة، ووجدت حل يقدم أكثر من ما نحتاج بكثير، فما هي GitHub Actions? وكيف نستخدمها في البيان؟ وكيف يتم استخدامها في إضافات NVDA?

بشكل مبسط، تُمكّنك GitHub Actions من تشغيل جهاز افتراضي (Virtual Machine) يعمل بأنظمة مثل Linux وWindows وmacOS، بحيث يتم إنشاء هذا الجهاز مؤقتًا عند الحاجة لتنفيذ إجراءات محددة ثم يُزال بعد انتهاء التنفيذ. هذه الفكرة تعني أنك لا تعمل على جهازك مباشرة، بل على بيئة نظيفة يتم تجهيزها تلقائيًا في كل مرة.
تُعتبر GitHub Actions منصة للتكامل المستمر (continuous integration) والتسليم المستمر (continuous delivery)، أو ما يُعرف اختصارًا بـ CI/CD، أي أنها تتيح لك بناء برنامجك واختباره ونشره بشكل تلقائي كلما حدث تغيير في المشروع.

تدعم GitHub Actions العديد من لغات البرمجة وإطارات العمل, تشمل Node.js, Python, Java, Ruby, PHP, Go, Rust, .NET, والمزيد.

الأتمتة داخل المستودع

تتيح لك المنصة أتمتة الإجراءات التي تتم داخل مستودع مشروعك عند حدوث أحداث معينة. على سبيل المثال، يمكنك إنشاء عملية تقوم ببناء البرنامج واختباره عند استقبال طلب سحب (pull request). كما يمكنك أتمتة التعامل مع الطلبات نفسها، مثل تشغيل فحوصات قبل قبولها، لكن يجب الانتباه أن قبول الطلب تلقائيًا لا يتم بشكل مباشر إلا إذا قمت بإعداد شروط وقواعد خاصة لذلك.
يمكنك أيضًا أتمتة التعامل مع المشاكل (issues)، بحيث يتم تصنيف أي issue جديدة تلقائيًا باستخدام labels محددة. بالإضافة إلى ذلك، يمكن تشغيل الأتمتة في حالات متعددة، سواء عند حدوث أحداث داخل المستودع أو في أوقات مجدولة أو حتى يدويًا.

مفهوم Workflows

تُسمى آلية الأتمتة في GitHub Actions باسم workflows، وهي العمليات المؤتمتة التي تقوم بتعريفها. يحتوي كل workflow على وظيفة واحدة أو أكثر تُسمى Job. يتم تعريف الـ workflow باستخدام ملف بصيغة YAML، ويكون هذا الملف مسؤولًا عن تحديد ما الذي يجب تنفيذه ومتى يتم تنفيذه.
يمكن تشغيل أي workflow عند حدث معين (event)، أو في وقت محدد (schedule)، أو بشكل يدوي. كما يمكن أن يحتوي المستودع على أكثر من workflow، ويتم حفظ هذه الملفات داخل المسار ‎.github/workflows‎ ضمن مجلد المشروع.

مفهوم Events

الأحداث (Events) هي التي تقوم بتشغيل الـ workflow، وهي تمثل أي نشاط يحدث داخل المستودع. على سبيل المثال، يمكن أن يكون الحدث هو إنشاء pull request، أو فتح issue، أو إرسال commit، أو دمج فرع. كما يمكن تشغيل workflow عبر API باستخدام طلب برمجي، أو تشغيله يدويًا عند الحاجة.

مفهوم Jobs

تُعتبر الوظائف (Jobs) عبارة عن مجموعة من الخطوات داخل workflow، ويتم تنفيذ كل Job على بيئة تشغيل واحدة تُسمى runner. بشكل افتراضي تعمل الـ jobs بشكل متوازي (parallel)، ولكن يمكن ربطها بحيث تنتظر إحداها الأخرى قبل التنفيذ.
كل Job يمكن أن يحتوي على أوامر متعددة، مثل تشغيل سكربتات أو تنفيذ actions جاهزة، ويتم تنفيذها ضمن نفس البيئة.

مفهوم Steps

الخطوات (Steps) هي الأوامر الفعلية داخل كل Job، وهي التي تقوم بتنفيذ العمل الحقيقي. يمكن أن تكون الخطوة عبارة عن shell script تقوم بكتابته، أو استدعاء action جاهزة.
تعمل الخطوات بالترتيب وتعتمد على بعضها البعض، وهذا ما سنراه بشكل عملي في البيان. وبسبب أن جميع الخطوات داخل نفس الـ runner، يمكن مشاركة البيانات بينها بسهولة، وهو أمر مهم جدًا في بناء سلاسل تنفيذ مترابطة.

مفهوم Actions

الإجراءات (Actions) هي وحدات مستقلة قابلة لإعادة الاستخدام، تختلف عن الـ Jobs والـ Steps وإن كانت تُستدعى من داخل الـ Steps. يمكن اعتبارها كأدوات جاهزة تنفذ مهمة محددة، مثل تحميل المشروع، أو إعداد بيئة تشغيل، أو تنفيذ عملية نشر.
تساعد actions على تقليل كمية الكود المكتوب داخل workflow، ويمكن لأي مطور إنشاء action خاصة به ومشاركتها مع الآخرين لاستخدامها في مشاريعهم.
حيث يمكنك الحصول عليها من خلال متجر GitHub.

مفهوم Runners

تُعتبر Runners عبارة عن خوادم (servers) تقوم بتشغيل workflows. كل runner يقوم بتنفيذ Job واحدة في نفس الوقت، ولكن يمكن تشغيل عدة jobs بالتوازي باستخدام عدة runners.
تتميز بيئة التشغيل بأنها نظيفة وحديثة في كل مرة يتم فيها تشغيل workflow، مما يمنع تداخل العمليات السابقة مع الحالية. كما يمكن في الخطط المدفوعة استخدام أجهزة بإمكانيات أكبر، أو حتى تشغيل runners خاصة بك (self-hosted) إذا كنت تحتاج إلى إعدادات أو عتاد معين.

تبسيط

ما قد تفعله على جهازك لتنزيل برنامج أو تشغيل برنامج لتنفيذ وظيفة معينة يمكنك اختصاره وتنفيذه من خلال GitHub Actions. الفكرة الأساسية ليست محاكاة الضغط على الأزرار أو التفاعل مع الواجهة، بل تنفيذ أوامر (commands) بشكل مباشر كما لو أنك تكتبها في terminal.
على سبيل المثال، لتجميع برنامجك ضمن ملف تثبيت باستخدام Inno Setup، تقوم عادةً بتنزيل البرنامج وتثبيته، ثم فتح ملف ‎.iss‎ وتنفيذ عملية Compile. في GitHub Actions، يمكن تنفيذ هذه الخطوات باستخدام أوامر، مثل تنزيل البرنامج بصيغة صامتة (silent install)، ثم تشغيل أداة التجميع عبر سطر الأوامر.
والأهم من ذلك، أنه في الكثير من الحالات وخاصة مع Inno Setup توجد Actions جاهزة تقوم بهذه العمليات نيابة عنك، بحيث تكتفي بتحديد ملف .iss وسيتم تنفيذ باقي الخطوات تلقائيًا. هذا يوضح كيف تقلل الإجراءات Actions من كمية الكود والتعقيد في الـ workflow.
وبنفس الفكرة، يمكنك تثبيت Python أو أي لغة أخرى، وإعداد البيئة، ثم تنفيذ أي خطوات تحتاجها لبناء مشروعك.

أفكار أخرى ممكنة

يمكنك أتمتة إجراء يقوم برفع ملف إلى خادم عند تحقق شرط معين، أو سحب بيانات من مصدر خارجي وتنفيذ عمليات بناءً عليها، أو حتى تنفيذ مهام دورية لمعالجة بيانات أو تحديثات. الفكرة العامة هي أنك تتحكم بجهاز افتراضي ينفذ أوامر محددة بدقة، دون الحاجة لأي تفاعل يدوي.

كيف تعمل GitHub Actions في البيان

سنأخذ فكرة بسيطة عن ما يتطلبه تحديث “البيان” في كل مرة، لنلاحظ الفرق بعد تطبيق الأتمتة.
في الوضع التقليدي، يجب أولًا تثبيت Python، ثم إنشاء بيئة (environment) وتثبيت المكتبات والملحقات التي يعتمد عليها البيان، وهذا ليس أمر ثابت خلال التطوير، فقد نستخدم إصدار مختلف عن الإصدار المعتمد في النسخة الرسمية، كما قد نختبر ملحقات إضافية يتعين علينا إزالتها مع ملحقاتها، أو إنشاء بيئة نظيفة.
ثم تشغيل سكربت يقوم بتحويل البرنامج من Python إلى ملف ‎.exe‎ قابل للتوزيع.
بعد ذلك، يجب فتح مجلد المستندات الذي يحتوي على دليل الاستخدام، وحذف ملفات ‎.md‎ لتجنب تضمينها في النسخة النهائية، نظرًا لأن المستخدم يتعامل مع ملفات HTML جاهزة، وهذه خطوة يتم نسيانها كثيرًا.
ثم تأتي مرحلة تنزيل Inno Setup وتثبيته، ثم الانتقال إلى ملف ‎albayan.iss‎ وتنفيذ عملية التجميع. بعد ذلك، يجب إعادة تسمية الملف الناتج ليطابق رقم الإصدار الحالي.
الخطوة التالية هي رفع الملف إلى GitHub وإنشاء إصدار (release). ثم علينا إضافة خطوة جديدة لنقل مجلد الأذكار الصوتية إلى مجلد بيانات المستخدم، وإنشاء نسخة إضافية مضغوطة بصيغة ‎zip‎ بدون استخدام Inno Setup, وذلك لإنتاج نسخة محمولة، مع تسميتها بنفس رقم الإصدار.
كل هذه الخطوات يمكن تنفيذها يدويًا، لكنها معرضة للنسيان والخطأ. أما باستخدام GitHub Actions، فيمكن تنفيذها بالكامل بخطوات بسيطة ومن واجهة واحدة.
نسعى لأتمتة المزيد من الخطوات مع استمرار تطوير البيان، لكن ما تم ذكره يمثل الوضع الحالي لل workflows في وقت كتابة هذا المقال. لدينا عدة workflows، منها workflow مخصص لإنشاء نسخة اختبارية للتغييرات الموجودة في فرع Beta، بالإضافة إلى workflows أخرى تخدم مراحل مختلفة من التطوير.
لكننا سنركز على المستخدم في إنشاء تحديثات البيان حاليًا.

إنشاء البيان:

إذا كانت لديك workflows تعمل بشكل يدوي، أي تقوم بتشغيلها أنت، يجب عليك وضع ملفاتها في الفرع الرئيسي لمشروعك.

وبالتالي، لدينا الـ Workflow الذي سنشاركه في هذا المسار.
albayan.github\workflows\Build and Release Albayan.yml

ومحتواه كالتالي:

# This workflow builds Albayan using cx-Freeze on Windows, then publishes it as a GitHub release
name: Build and Release Albayan # يشير إلى اسم الإجراء الذي سيظهر.

# الخطوات التالية تتضمن إنشاء نموذج يتضمن حقول يتم طلبها عند تشغيل الـ Workflow.
on:
  workflow_dispatch: # يعني أن التشغيل يدوي من داخل GitHub (زر Run workflow).

# يمكن أن يكون على سبيل المثال: push ليتم تشغيله عند دفع commit أو أي حدث آخر يتم دعمه.

    inputs:
      file_name: # اسم ملف التثبيت النهائي.
        description: 'Installer file name (with or without .exe)'# وصف يظهر مع الحقل، يمكن كتابة .exe أو تجاهلها وسنتعامل مع ذلك لاحقًا.
        required: true # يصنف المربع على إنه إلزامي، أي لا يمكن تشغيل العمل دون كتابة شيء هنا.
        default: 'AlbayanSetup' # قيمة افتراضية حيث يمكن تعديلها.
      tag_name: # لكتابة اسم للtag الذي سيتم استخدامه مع الإصدار.
        description: 'Tag name (e.g. v1.0.0)' # مثال مع الحقل يوضح ما يمكن كتابته.
        required: true # يحدد إنه مطلوب، أي إلزامي.
        default: 'v1.0.0' # يضيف قيمة افتراضية.
      release_name: # حقل يتم استخدامه لكتابة عنوان الrelease الذي سيظهر مع الإصدار في صفحة releases.
        description: 'Release title (e.g. Albayan v1.0.0)' # وصف يشرح مثال عن ما يمكن كتابته.
        required: true # يشير إلى أن الحقل مطلوب.
        default: 'Albayan Release' # قيمة افتراضية للحقل.
      release_body: # ما ستكتبه في وصف الإصدار، مشكلة هذا الحقل عدم دعم الأسطر المتعددة، وبالتالي، نتجاهله حاليًا ونعدل الإصدار، لكن توجد طرق بديلة مثل تنفيذ خطوة تأخذ المستجدات من المستودع وتضيفها هنا، وهي أمور سننفذها لاحقًا.
        description: 'Release description (Markdown supported)' # وصف للحقل.
        required: false # يوضح أن الحقل ليس إلزامي.
        default: '' # يحدد قيمة فارغة كقيمة افتراضية.


# هنا ننهي ما سيتم طلبه عند التشغيل، ثم ننتقل إلى أذونات العمل.
permissions: # الأذونات.
  contents: write # يسمح للـ workflow بإنشاء Releases وTags ورفع ملفات، في حالات أخرى يمكنك الاكتفاء بالقراءة Read وذلك في حال عدم رغبتك بتنفيذ إجراء على المستودع مثل إنشاء إصدار.


jobs: # هنا يبدأ تعريف الوظائف.
  build: # تعريف وظيفة Build.
    runs-on: windows-latest # تشغيل على أحدث بيئة Windows (GitHub Runner).
    steps: # تبدأ هنا بتعريف الخطوات.
    - name: Checkout repository # اسم الخطوة التي ستسحب نسخة من المستودع لتشغيلها على الخادم.
      uses: actions/checkout@v6 # تحدد إصدار الإجراء المستخدم، وكما نلاحظ، يقوم هذا الإجراء بسحب (clone) كود المشروع إلى بيئة التنفيذ تلقائياً، مما يغنيك عن كتابة خطوة clone يدوياً.
      # بدون هذه الخطوة لن يكون لديك أي ملفات للعمل عليها.

    - name: Set up Python 3.14 (latest patch) # خطوة تعرف تثبيت Python.
      uses: actions/setup-python@v6 # تحدد الإجراء المستخدم مع إصداره، أي إننا لن نقوم بتنزيل Python وتثبيته بشكل يدوي.
      with:
        python-version: "3.14" # بهذه الطريقة تم تحديد إصدار Python وبسبب عدم تحديد إصدار فرعي، سيتم تثبيت أحدث إصدار.


    - name: Upgrade pip and install dependencies # تعريف اسم الخطوة، التي ستقوم بترقية pip إلى أحدث إصدار، ثم تنزيل ملحقات البيان المطلوبة.
      shell: pwsh # تحدد هنا إنك ستستخدم أوامر shell.
      run: | # تحدد الأمر الذي سيتم تشغيله.
        python -m pip install --upgrade pip # نمرر أمر تحديث Pip.
        if (Test-Path "requirements.txt") { # نضع شرط يتحقق من وجود ملف requirements.txt وفي حال تحققه:
            pip install -r requirements.txt
        }  # ننفذ أمر تثبيت الملحقات والمكتبات من خلال ملف requirements.txt.

    - name: Build with cx-Freeze # هنا نحدد اسم الخطوة التي ستقوم ببناء البيان من خلال cx_Freeze.
      shell: pwsh
      run: |
        python setup.py build # هنا نقوم بتنفيذ أمر تشغيل سكربت تحويل البرنامج إلى exe.
      # يقوم بتشغيل سكربت setup.py
      # والذي بدوره ينشئ مجلد build يحتوي على نسخة جاهزة للتشغيل من البرنامج.


# نظرًا لوجود ملفات المستندات مثل دليل الاستخدام والمستجدات في مجلد documentation في مجلد المشروع، يتم نسخهم إلى مجلد البرنامج أثناء إنشائه، نريد إزالة ملفات md والإبقاء على أي ملفات أخرى.
    - name: Remove markdown documentation files # تقوم هذه الخطوة بحذف ملفات md من مجلد توثيق البيان.
      shell: pwsh
      run: |
        $docPath = "albayan_build\documentation" # يتم هنا تعريف متغير باسم docPath وتحديد قيمته كمسار المستندات في مجلد albayan_build\documentation مجلد albayan_build هو ناتج عملية الإنشاء من cx_Freez.
        if (Test-Path $docPath) { # هنا نضع شرط للتأكد من مطابقة المسار.
            Remove-Item "$docPath\*.md" -ErrorAction SilentlyContinue
        }  # هنا ننفذ أمر shell يبحث عن أي ملف ينتهي بالامتداد .md ويحذفه، وفي حال عدم وجود أي ملفات يتابع بدون عرض أخطاء.


    - name: Download and install latest Inno Setup # نعرف خطوة لتنزيل وتثبيت Inno Setup وعلى الرغم من توفير إجراء جاهز على GitHub, لكننا سنستخدم التنزيل بشكل يدوي.
      shell: pwsh
      run: |
        Invoke-WebRequest -Uri https://jrsoftware.org/download.php/is.exe -OutFile is.exe # يقوم هذا الأمر بتنزيل البرنامج من موقعه من الرابط المباشر المضمن.
        Start-Process -Wait -FilePath .\is.exe -ArgumentList '/VERYSILENT','/SUPPRESSMSGBOXES','/NORESTART','/SP' # هنا يتم تشغيل ملف التثبيت مع تمرير معاملات تشغله بشكل صامت وتتجاوز أي رسائل وتمنع طلب إعادة التشغيل، وهي أوامر في Inno Setup.

      # يتم التثبيت بصمت (Silent install) بدون أي نوافذ.
      # VERYSILENT: بدون واجهة
      # SUPPRESSMSGBOXES: منع الرسائل
      # NORESTART: منع إعادة التشغيل


    - name: Package with Inno Setup # تعريف خطوة لتجميع البرنامج كملف تثبيت باستخدام Inno Setup، أي تحويل ملفات البرنامج إلى Setup.exe قابل للتثبيت.
      shell: pwsh # تحديد استخدام PowerShell لتنفيذ الأوامر داخل هذه الخطوة.
      run: | # بداية كتابة أوامر سيتم تنفيذها بشكل متسلسل.
        $isccPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" # تعريف متغير يحتوي على المسار الافتراضي لبرنامج ISCC وهو المترجم الخاص بـ Inno Setup المسؤول عن إنشاء ملف التثبيت.
        if (!(Test-Path $isccPath)) { # شرط يتحقق إذا كان المسار السابق غير موجود (أي ربما تم تثبيت البرنامج في مسار مختلف).
            $isccPath = "C:\Program Files\Inno Setup 6\ISCC.exe" # في حال عدم وجوده في Program Files (x86)، نجرب المسار البديل في Program Files.
        }
        Start-Process -Wait -FilePath $isccPath -ArgumentList "albayan.iss"  # تشغيل برنامج ISCC مع تمرير ملف albayan.iss الذي يحتوي تعليمات بناء ملف التثبيت، مع الانتظار حتى انتهاء التنفيذ.

    - name: Rename installer # تعريف خطوة مسؤولة عن إعادة تسمية ملف التثبيت الناتج من Inno Setup.
      shell: pwsh # استخدام PowerShell.
      run: |
        $input = "${{ github.event.inputs.file_name }}" # إحضار اسم الملف الذي أدخله المستخدم عند تشغيل الـ workflow وتخزينه في متغير.
        if (-not $input.ToLower().EndsWith(".exe")) { # التحقق مما إذا كان الاسم لا ينتهي بـ .exe (لأن المستخدم قد لا يكتب الامتداد)، ولذلك ذكرنا في البداية أن وجود exe هو أمر اختياري.
            $input = "$input.exe" # في حال عدم وجود الامتداد، يتم إضافته تلقائيًا لضمان أن الملف تنفيذي.
        }
        $source = "albayan_build\AlbayanSetup.exe" # تحديد المسار والاسم الأصلي لملف التثبيت الناتج من Inno Setup في متغير.
        $dest   = "albayan_build\$input" # تحديد المسار الجديد مع الاسم الجديد الذي اختاره المستخدم.
        if ($source -ne $dest) { # التحقق أن الاسم الجديد مختلف عن القديم لتجنب تنفيذ إعادة تسمية غير ضرورية.
            Rename-Item -Path $source -NewName $input # تنفيذ عملية إعادة التسمية داخل مجلد البناء.
        }
        # Copy installer outside albayan_build so it won't be included in the portable ZIP # تعليق  نسخ ملف التثبيت إلى خارج المسار لتجنب تضمينه في النسخة المحمولة لاحقًا.
        Copy-Item -Path "albayan_build\$input" -Destination "$input" # نسخ ملف التثبيت إلى خارج مجلد البناء حتى لا يتم تضمينه داخل النسخة المحمولة (ZIP).
        echo "INSTALLER_NAME=$input" >> $env:GITHUB_ENV # تخزين اسم ملف التثبيت في متغير بيئة ليتم استخدامه لاحقًا في خطوة إنشاء الإصدار.

    - name: Create Portable ZIP # تعريف خطوة لإنشاء نسخة محمولة من البرنامج (Portable) بصيغة ZIP بدون الحاجة للتثبيت.
      shell: pwsh # استخدام PowerShell.
      run: |
        # Move athkar folder to User Data\audio\athkar (portable structure) # وصف خطوة لنقل مجلد الأذكار في النسخة المحمولة من audio\athkar إلى User Data\audio\athkar.
        $source = "albayan_build\Audio\athkar" # تحديد موقع مجلد الأذكار داخل مجلد البناء.
        $dest   = "albayan_build\user_data\audio\athkar" # تحديد الموقع الجديد داخل هيكل بيانات المستخدم الخاص بالنسخة المحمولة.
        if (Test-Path $source) { # التحقق من وجود مجلد الأذكار في المسار الأصلي.
            New-Item -ItemType Directory -Path $dest -Force | Out-Null # إنشاء المجلد الجديد (حتى لو كان موجود مسبقًا) بدون إظهار مخرجات.
            Move-Item -Path "$source\*" -Destination $dest -Force # نقل جميع الملفات من المجلد القديم إلى الجديد.
            Remove-Item $source -Recurse -Force # حذف المجلد الأصلي بعد النقل لتجنب التكرار.
        }

        # Remove installer from build folder before zipping تعليق يشرح حذف ملف التثبيت من مجلد النسخة قبل ضغطها.
        Remove-Item "albayan_build\$env:INSTALLER_NAME" -ErrorAction SilentlyContinue # حذف ملف التثبيت من داخل مجلد البناء حتى لا يتم تضمينه داخل ملف ZIP.

        # Strip .exe if provided to format the zip name nicely تعليق يتضمن شرح الخطوة القادمة لإزالة اسم exe من ملف النسخة المحمولة.
        $baseName = "${{ github.event.inputs.file_name }}" # إحضار اسم الملف المدخل من المستخدم مرة أخرى لاستخدامه في تسمية ملف ZIP.
        if ($baseName.ToLower().EndsWith(".exe")) { # التحقق إذا كان الاسم يحتوي على .exe في النهاية.
            $baseName = $baseName.Substring(0, $baseName.Length - 4) # إزالة الامتداد للحصول على اسم نظيف.
        }
        $zipName = "$baseName`_Portable.zip" # إنشاء اسم ملف ZIP بإضافة _Portable لتمييزه كنسخة محمولة.

        # Copy build contents into an Albayan subfolder, then zip that folder #تعليق يشرح نسخ ملفات البرنامج إلى مجلد لضغطه.
        New-Item -ItemType Directory -Path "portable_output\Albayan" -Force | Out-Null # إنشاء مجلد مؤقت لتجهيز محتويات النسخة المحمولة.
        Copy-Item -Path "albayan_build\*" -Destination "portable_output\Albayan" -Recurse -Force # نسخ جميع ملفات البرنامج إلى هذا المجلد.
        Compress-Archive -Path "portable_output\Albayan" -DestinationPath $zipName # ضغط المجلد بالكامل إلى ملف ZIP.

        # Save the zip file name to environment variables for the release step وصف حفظ اسم ملف النسخة المحمولة المضغوط لاستخدامه لاحقًا.
        echo "PORTABLE_NAME=$zipName" >> $env:GITHUB_ENV # حفظ اسم ملف ZIP في متغير بيئة لاستخدامه لاحقًا في رفع الملفات إلى الإصدار.

    - name: Create tag and release # تعريف خطوة إنشاء Tag وإصدار (Release) على GitHub ورفع الملفات الناتجة.
      uses: softprops/action-gh-release@v2 # استخدام Action جاهز لإنشاء Releases على GitHub مع تحديد الإصدار 2 كإصدار الإجراء..
      with:
        tag_name: ${{ github.event.inputs.tag_name }} # تحديد اسم الـ Tag الذي سيتم إنشاؤه أو استخدامه.
        name: ${{ github.event.inputs.release_name }} # تحديد اسم الإصدار الذي سيظهر للمستخدمين.
        body: ${{ github.event.inputs.release_body }} # وضع وصف الإصدار (إن تم إدخاله).
        files: | # تحديد قائمة الملفات التي سيتم رفعها داخل الإصدار.
          ${{ env.INSTALLER_NAME }} # ملف التثبيت الذي تم إنشاؤه سابقًا.
          ${{ env.PORTABLE_NAME }} # ملف النسخة المحمولة ZIP.
        target_commitish: ${{ github.ref_name }} # تحديد الفرع الذي سيتم إنشاء الإصدار بناءً عليه.
        prerelease: false # تحديد أن الإصدار ليس تجريبي (Pre-release).
        draft: false # تحديد أن الإصدار سيتم نشره مباشرة وليس كمسودة.
        make_latest: true # تعيين هذا الإصدار كأحدث إصدار في المستودع.

تشغيل الـ Workflow

كما ذكرنا، يجب أن يكون في مسار .github\workflows في مشروعك، وفي حالة التشغيل اليدوي، يجب أن يكون في الفرع الرئيسي الافتراضي.

وإذا أردت تنفيذه على فرع آخر فيجب أن يكون في الفرع المطلوب تنفيذه، إلى جانب الرئيسي.

في حالتنا سننتقل إلى مستودع البيان. ومن قائمة المستودع سنختار Actions ثم نختار Build and Release Albayan ونضغط على Run workflow.

سيطلب التالي:

  • Use workflow from: قائمة تحديد الفرع Branch الذي سيتم استخدامه.
  • Workflow inputs: تحدد مدخلات البيانات التي سيتم تضمينها.
  • Installer file name (with or without .exe)*: اسم ملف التثبيت مع أو بدون .exe.
  • Tag name (e.g. v1.0.0)*: اسم الTag.
  • Release title (e.g. Albayan v1.0.0)*: اسم الإصدار.
  • Release description (Markdown supported): وصف الإصدار.
  • ثم نضغط على Run workflow.

سيبدأ التنفيذ ويمكننا رؤية الخطوة الحالية والوقت المنقضي وتقدم العمل، كما يمكننا عرض سجل الخطوات لأي تشغيل في أي وقت، فكل تشغيل للإجراء يتم ترقيمه بعدد مرات التشغيل.

وفي حال فشل التشغيل أو حدوث خطأ يمنع الإكمال، سيتم الإيقاف وعرض الخطأ لتراجع العمل وتقوم بتصحيحه.

أما في حال نجاح العمل, فسيتم إنشاء إصدار جديد قام برفعه بوت @github-actions ويمكن تعديله أو حذفه.

وفقًا للكود الحالي، إذا أدخلت اسم Tag موجود سيتم التعامل معه دون إنشاء Tag جديد.

وبالتالي: كما نلاحظ، يكفي تشغيل الإجراء، كتابة البيانات، ثم الحصول على إصدار جاهز.

وبذلك نختصر عدد كبير من الخطوات ونبتعد عن العمل من أجهزتنا الشخصية، ونضمن وجود بيئة تطوير حديثة نظيفة لا تحتوي على أي ملفات أو ملحقات غير ضرورية.

يمكن تنظيم العمل السابق بشكل أكبر وإضافة المزيد من خطوات التبسيط، كما أن بعض الإجراءات تتم من خلال ملف عمل exe وملف عمل التثبيت وبالتالي يمكننا تبسيط العمل بشكل أكبر.

ملاحظات

مع التعمق في هذا المجال، ستجد الكثير من التفاصيل مثل الأمان والمصادقة وعدد الدقائق الشهرية بشكل مجاني، فالإجراءات للمستودعات الخاصة ليست مجانية كما هو الحال مع المستودعات العامة.

لذلك، ابحث واقرأ واختر ما يناسبك.

بعض الإجراءات تعمل بشكل جاهز وتتعامل مع الأخطاء وتسهل كتابة الكود، لذلك، حاول الاستفادة من الإجراءات الجاهزة في GitHub Marketplace قدر الإمكان، إذ توفر معالجة للأخطاء وتقلل من حجم الكود الذي تكتبه.

يتم بنفس الآلية أتمتة تحديث إضافات NVDA من بعض مطوري الإضافات، بحيث يتم دمج الترجمات والتحقق من الإضافة وإنشاء الإصدار.

في الختام

تعتبر GitHub Actions خيار مميز لتنظيم العمل ونشر التحديثات واختبارها والتعامل مع المستودع وإرسال وتلقي البيانات وأتمتة الكثير من الإجراءات لتتم بشكل ثابت ومحدد وتلقائي.

قد نناقش في مقالات لاحقة إجراءات أخرى مثل تطوير موقع ويب من خلال مستودع GitHub وأتمتة رفع التغييرات إلى الخادم لتظهر للمستخدمين بشكل فوري.

عن Qais Alrefai

مطور برمجيات من سوريا ومؤسس نافذة التقنية. أعمل على جعل التقنية أكثر سهولة في الوصول وأستمتع باستخدام بايثون والعمل مع الذكاء الاصطناعي. أهتم بالتقنية والبرمجة والموسيقى والكتابة، وأحب استكشاف الأفكار من خلال البرمجة وصناعة المحتوى. أحب القهوة والمطر، ولدي معرفة بعدة مفاهيم في لغات برمجة مختلفة.

تحقق أيضا

نظرة سريعة على Antigravity 2.0

أطلقت Google إصدار جديد من منصة تطوير الوكلاء Antigravity ليعمل بشكل منفصل عن المحرر المبني… أكمل القراءة » نظرة سريعة على Antigravity 2.0

اكتب تعليقًا