اگر آدمی هستید که همیشه دنبال ویژگی های جدید میگرده و تکنولوژی براش مهمه این مطلب رو مطالعه کنید.
این مطلب به توسعه بازی با استفاده از موتور بازیسازی یونیتی میپردازه و روش اتوماتیک کردن تست و خروجی گرفتن از پروژه رو با استفاده از Gitlab CI/CD آموزش میده.
لازمه مطالعه این مقاله آشنایی کافی با یونیتی، Unit Test و Git هستش. بقیه چیزا اینجا آموزش داده شده.
اول از همه یه تعریف کوتاه و مختصری از CI با هم داشته باشیم. CI مخفف Continuous Integration هست و به طور خلاصه به فرآیند اتوماتیک تست کردن و خروجی گرفتن اپلیکیشن به طور مداوم گفته میشه.
با استفاده از CI هر بار که کدی توی ریپوزیتوری خاصی مثل gitlab مرج میشه، یکبار تست و خروجی گرفته میشه تا از صحت کدهای مرج شده اطمینان حاصل بشه و به این صورت ما همیشه یک Nightly Build خواهیم داشت.
وقتی همکارتون پروژه رو روی ریپوزیتوری مرج میکنه، یکی باید کدهایی که زده رو تست و کنه و مطمئن شه که برای خروجی گرفتن از پروژه مشکلی پیش نیومده باشه. حالا شما اگر مدیر بخش برنامه نویسی باشید چکار میکنید؟ با هر بار merge شدن پروژه روی گیتلب همه این کارها رو به صورت دستی انجام میدید؟ مسلماً این کار بسیار زمان بر هست و باعث کند شدن روند توسعه میشه. اینجاست که CI به کمک شما میاد. تستهای سلامت کد به صورت خودکار انجام میشه و سریعا در مورد خطاهای کد به صورت خودکار به شما اطلاع رسانی میشه. به این وضعیت اصطلاحاً بازخورد سریع یا Fast Feedback میگن. پاس شدن تستها و خروجی گرفتن از پروژه مهمترین بخش تولید هر اپلیکیشنی رو شامل میشه و با اتوماتیک کردن این فرآیند میشه با سرعت و دقت بالاتری بازی خودتون رو توسعه بدید.
اول از همه اگر در سایت Gitlab حساب ندارید یک حساب کاربری تهیه کنید. البته از اونجایی که گیتلب ما رو تحریم کرده برای ورود به سایت میتونید از شکن استفاده کنید.
بعد از اینکه اکانت رو ساختید وارد Gitlab بشید و یک پروژه بسازید.
برای مثال من پروژهای به نام unity-ci-project ساختم. بعد از اینکه پروژه رو ساختید یک کلون از پروژه بگیرید و دو تا فولدر الزامی Assets و ProjectSettings رو به فولدرتون اضافه کنید تا یونیتی بتونه پروژه رو باز کنه.
بعد از اینکه پروژه رو باز کردید اولین کاری که میکنیم اینه که یک کلاس تست بنویسیم. اگر با یونیت تست نوشتن در یونیتی آشنا نیستید میتونید این مقاله را مطالعه کنید.
خوب برای این کار من یک تست خیلی ساده مینویسم. (این کلاس رو تو دایرکتوری Assets/Editor تولید کردم)
using NUnit.Framework; public class ExampleTest { [Test] public void ExampleTestPassing() { Assert.Pass(); } }
این تست داره میگه که هر اتفاقی که افتاد تست رو Pass کن. حالا وقتی برگردیم به محیط یونیتی میتونیم تست رو انجام بدیم و از صحتش مطمئن بشیم.
ما کار خاصی در این لحظه قرار نیست انجام بدیم و هدفمون اینه که ببینیم تستی که نوشتیم توسط گیتلب صحت سنجی میشه یا نه. برای این کار پروژه رو روی گیتلب پوش میکنیم. فقط قبلش فراموش نشه که فایل gitignore. به پروژه به شکل زیر اضافه بشه.
اگر تو محیط ویندوز هستید با git bash میتونید این فایل رو با دستور vi .gitignore بسازید.
/[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Bb]uild/ /[Bb]uilds/ /Assets/AssetStoreTools* ExportedObj/ .consulo/ *.csproj *.unityproj *.sln *.suo *.tmp *.user *.userprefs *.pidb *.booproj *.svd # Unity3D generated meta files *.pidb.meta # Unity3D Generated File On Crash Reports sysinfo.txt # Builds *.apk *.unitypackage
بعدش با git bash آدرس ریموت و ... رو بزنید و با یه کامیت مثلا Initial commit پروژه رو پوش کنید.
git remote add origin https://gitlab.com/......... /unity-ci-project.git آدرس ریپوزیتوری گیت شما git add -A git commit -m "Initial commit" git push -u origin master
برای اینکه بتونیم از CI/CD گیتلب استفاده کنیم باید یک فایل به نام gitlab-ci.yml. در دایرکتوری روت پروژه بسازیم. این فایل هم میتونید به همون روشی که توضیح دادم تولید کنید.
برای ادیت کردن فایل yml من از vs code استفاده میکنم تا بتونم راحتتر خطاهای حین کار رو متوجه بشم.
برای نوشتن یک فایل yml که گیتلب برای CI ازش استفاده میکنه دستورهای خاصی وجود داره که میتونید از داکیومنت خود گیتلب که بهترین مرجع این کاره استفاده کنید.
خوب بیاید یک gitlab-ci.yml. ساده درست کنیم.
stages: - test - build - deploy unit-test: stage: test script: echo 'Testing...' unity-build: stage: build script: echo 'Building...' unity-deploy: stage: deploy script: echo 'Deploying...'
پارامترها:
تو فایلی که ما نوشتیم 3 تا Stage به نام Test، buildو deploy وجود داره که هر کدوم کار خاصی رو انجام میده.
برای مثال ما گفتیم در هنگام تست که استیجی به نام test داره کار unit-test رو انجام بده و Testing.... رو چاپ کنه
این فایل رو به پروژه اضافه میکنیم و پروژه رو روی برنچ master پوش میکنیم و گیتلب رو روی کروم (یا هر Browser دیگهای که استفاده میکنید) باز میکنیم.
git add -A git commit -m 'Added .gitlab-ci.yml' git push origin master
حالا وقتی تب CI/CD رو تو پنل گیتلب از سمت چپ باز کنیم متوجه میشیم که یکسری پروسسها در حال انجامه.
یکم که صبر کنیم 3 تا استیجی که معرفی کرده بودیم تیک دار میشن و صحت انجام کار ما مشخص میشه.
همونطور که در عکس بالا میبینید Pipeline به کل محیطی که فرآیند Testو Buildو Deploy کردن انجام میپذیره گفته میشه و هر استیج به صورت مجزا (مثلا استیج Test) و کارهایی که باید انجام بده ( مثلا unit-test)، در زیر هر استیج، مشخص شده.
برای مثال تصویری از Job استیج Build رو گذاشتم تا ببینیم که کاری که ازش خواسته بودیم یعنی echo کردن Building انجام شده و صحت کار ما مشخص شده.
پیش بسوی Gitlab Runner
نمیدونم تا به حال اسم Gitlab Runner به گوشتون خورده یا نه. ولی الآن که میخوایم از Gitlab CI/CD استفاده کنیم زیاد ازش میشنویم.
گیتلب رانر به ما کمک میکنه تا سایت گیتلب رو به سیستم شخصیمون متصل کنیم و لاگ ها و پروسسها رو روی کامپیوتر خودمون داشته باشیم.
اولین کاری که باید انجام بشه اینه که Gitlab Runner مربوط به سیستم عاملتون رو دانلود کنید. راهنمای دانلود و استفاده قدم به قدم از Gitlab Runner در اینجا قابل مشاهده هست.
برای مثال من که از ویندوز 64 بیتی استفاده میکنم از این لینک آخرین نسخه رو دانلود کردم و فایل دانلودی رو در آدرس C:\Gitlab Runner کپی کردم.
شروع کار با Gitlab Runner خیلی ساده است. کافیه با cmd به آدرس Gitlab Runner بریم و به صورت زیر عمل کنیم.
cd C:\GitLab-Runner .\gitlab-runner-windows-amd64.exe install .\gitlab-runner-windows-amd64.exe start
و تمام.
با این کار Gitlab Runner برای شما نصب و استارت میشه. حالا برای وصل کردن پروژه، روی سایت گیتلب و گیتلب رانر روی سیستم عامل، باید عملیات رجیستر رو انجام بدیم.
برای رجیستر کردن به پنل گیتلب برید و از تب Setting بخش CI/CD رو پیدا کنید و از اونجا بخش Runner را Expand کنید تا به Set up a specific Runner manually برسید. (یکم راهش صعب العبوره!)
در این بخش آموزش قدم به قدم رجیستر کردن گیتلب رانر قرار داده شده.
در این مرحله با استفاده از cmd به آدرس Gitlab Runner برید و به شکل زیر عمل کنید.
با انجام این کار رجیستر ما با موفقیت انجام میشه. ?
بعد از اینکار فایل gitlab-ci.yml. رو باز کنید و تگ unity رو به stage ها اضافه کنید (برای اینکه Gitlab Runner ما فقط کارهایی که تگ یونیتی دارن رو اجرا کنه). و پروژه رو Push کنید تا نتیجه کارها مشخص بشه.
stages: - test - build - deploy unit-test: script: "echo 'Testing...'" stage: test tags: - unity unity-build: script: "echo 'Building...'" stage: build tags: - unity unity-deploy: script: "echo 'Deploying...'" stage: deploy tags: - unity
دستورات گیت هم به صورت زیر میزنیم
git add -A git commit -m 'Added unity tag in .gitlab-ci.yml' git push origin master
همینطور که میبینید ماشینی که به نام FirstRunner ساختیم و رجیستر کردیم با استفاده از Gitlab Runner درحال اجر است.
حالا که تونستیم با موفقیت تمام این کارها رو انجام بدیم، وقتشه که از Command Line های یونیتی کمال استفاده رو ببریم و یونیت تست های edit mode و خروجی گرفتن رو با استفاده از Gitlab انجام بدیم.
اگر در مورد Command Line های یونیتی اطلاع ندارید از این لینک استفاده کنید.
الآن وقتشه که gitlab-ci.yml. رو باز کنیم و تغییرات لازمه رو انجام بدیم.
stages: - test - build - deploy unit-test: script: - C:\"Program Files"\Unity\Editor\Unity.exe -batchmode -projectPath -runTests -testPlatform editmode -logFile -testResults C:\Logs\UnitTest.log stage: test tags: - unity build-android: script: - C:\"Program Files"\Unity\Editor\Unity.exe -batchmode -nographics -executeMethod BuildScript.Build -projectPath C:\Users\omidfth\Documents\Projects\UnityProjects\unity-ci- project -quit -logFile C:\Logs\AndroidLog.log stage: build tags: - unity
من بخش deploy رو فعلا پاک کردم و یک job به نام build-android اضافه کردم.
برای یونیت تست : کارها در بخش script مربوط به خودش نوشته شده. تو این بخش از Command Line های یونیتی استفاده شده به این صورت که یونیتی رو در حالت batchmode اجرا میشه و یونیت تست های editmode رو انجام میده و لاگش رو در مسیری که مشخص کردیم میریزه.
در قسمت build-android هم اسکریپت مربوط به build گرفتن اندروید وجود داره. در Command Line های یونیتی بخشی با عنوان executeMethod وجود داره که مشخص میکنه چه متدی از پروژه موقع اجرا یونیتی ران بشه. به عنوان مثال من یک کلاس به نام BuildScript.cs در دایرکتوری Assets/Editor درست کردم و یک متد استاتیک به نام Build رو صدا زدم. در قسمت projectPath هم من آدرس پروژه که قراره خروجی گرفته بشه رو دادم.
کلاس BuildScript.cs به شکل زیر نوشته میشه.
using System; using UnityEditor; public class BuildScript { public static readonly string[] scenes = { "Assets/Scenes/main.unity",}; public static void Build() { Console.Write("build for Android"); BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions { scenes = scenes, // add scenes locationPathName = "./builds/android.apk", //set location target = BuildTarget.Android, // build for Android options = BuildOptions.None // set default for others }; BuildPipeline.BuildPlayer(buildPlayerOptions); //build } }
در این متد گفته شده که بعد از خروجی گرفتن فایل apk ای به نام android.apk در مسیر builds/android.apk (کنار فولدر Assets) ساخته بشه.
بعد از این کار پروژه رو کامیت و پوش میکنیم روی گیتلب و منتظر نتیجه میمونیم. تو این لحظه پروژه تستی ما در حال Build گرفتن هست. بعد از پاس شدن همه job ها به آدرس پروژهتون برید و بیلد اندرویدتون رو پیدا کنید.
سپس برنامه رو نصب میکنیم تا از صحت خروجی مطمئن بشیم.
همینطور که در تصویر مشاهده میکنید unity-ci-project به درستی نصب و اجرا شد.
تبریک میگم.
شما تا اینجای کار تونستید یک فرآیند اتوماتیک تست و خروجی گرفتن رو انجام بدید و هر بار که پروژه رو روی گیتلب پوش و با برنچ master مرج میکنید تمام این اتفاقات به صورت اتوماتیک میوفته و اگر وسط کار مشکلی پیش بیاد درجا بهتون ایمیل میاد که یه جای کار مشکل خورده.
امیدوارم این مقاله تونسته باشه به درکتون از CI و اتومیت کردن توسعه بازی کمک کرده باشه.