داستان از جایی شروع میشه که تیم تصمیم میگیره از گیت فلو پیروی کنه، Gitflow روشی برای مدیریت گیتمون هستش به طوریکه روند مشخصی داشته باشه و تیم همگی با هم هماهنگ باشن و یک ساختار یکپارچه رو برای کامیت ها، برنچ ها و ... داشته باشند. اگر دربارش میخواین بیشتر بدونین، میتونین از اینجا بخونین و بدونین که برای پروژه همراه اول گیتمون رو چطور مدیریت میکردیم.
خب ما توی گیت فلو از Pull(Merge) Request استفاده میکنیم که در ادامه فقط PR صداش میکنیم. PR یعنی ما یه برنچ محافظت شده داریم که قراره یه سری کد که تازه دولوپ شده یا تغییراتی روی اون انجام شده رو روش مرج کنیم و به اون اضافه کنیم. حالا بذارین با یه مثال بریم جلو
ما یک فیچر لاگین داریم که قراره دولوپ شه. برنامه نویس میاد و از برنچDevelop (برنچی که استیبل ترین کدمون روش هست، یعنی کدهایی که تست شده و آماده هست برسه دست مردم) یه برنچ جدید به نام Feature/Login میسازه، و شروع میکنه به کار کردن وقتی که این فیچر تمام شد، باید کارشو بیاره روی Develop که آماده ریلیز بشه. حالا اینجا دوتا سناریو هستش :
خودش مستقیم مرج کنه با Develop در این حالت همه برنامه نویسا به Develop و مرج کردن روی اون دسترسی کامل دارن به همین دلیل هرگونه خطایی روش محتمل هستش و در نتیجه نمیشه گفت که Develop یه برنچ اماده ریلیز هستش.
یک PR بده تا افرادی که دسترسی مرج Develop رو دارن اینکارو انجام بدن در این حالت فقط بعضی اعضا حق مرج کردن برنچ جدید با Develop رو دارن که این یه لایه محافظتی قرار میده.
ما قرار رویکرد دوم رو دونبال کنیم،
بعد از اینکه PR ثبت شد، یکی (یا چندتا) از اعضای دیگه تیم وظیفه داره کد جدید رو بررسی کنه به چند دلیل :
مطمئن بشیم که قواعد و نامگذاری ها و قانونای درون تیمیمون رعایت شدن
کد دقیقا کاری که باید بکنه رو انجام میده
شاید جایی بتونیم از کدهای جدیدتری استفاده کنیم
شاید بتونیم اون کدو از نظر پرفورمنس بهبود بدیم
شاید چیزی فراموش شده و فرد جدید که به کد نگاه میکنه متوجه اون بشه
از نظر خوانایی و قابل درک بودن کد خوبه یا نه؟
شاید یه سری لاگ و ... توی کد باشه بتونیم حذفشون کنیم
تست ها نوشته شدن؟
مموری لیک نداریم؟
کد جدید از نظر ساختار درسته؟ نمیتونیم ماژولارش کنیم تا بعدا هم ازش استفاده کنیم؟
این بررسی ها به دلیل ضعف برنامه نویس اول نیست، بلکه وقتی کسی چندین ساعت زمان برای پیاده سازی یه فیچر میذاره، خیلی وقتا خسته میشه و شاید یجاهایی رو از روی خستگی یه طوری دیگه پیاده سازی کنه که با قوانین یا قواعد کل تیم متناقض باشه، یا اینکه اصلا دیدگاه های نفر دوم شاید بتونه به بهبود کد کمک کنه، اصلا شاید برنامه نویس دوم، به دلیل اینکه بخش دیگه ای از اون کد رو قبلا پیاده سازی کرده،یه چیزایی قبلا زده بود که میتونست توی کد جدید استفاده بشه و نیاز به پیاده سازی بعضی چیزا نبود و ...، همینجور که میبینیم ممکنه این عمل به صورت ناخداگاه یا نا خواسته روی برنامه نویس اول تاثیر منفی بذاره در نتیجه، وقتی کسی کدی رو بررسی میکنه باید به موارد زیر توجه داشته باشه :
کسی که کد رو میخونه باید بدونه که کامنت هایی که روی اون کد میذاره، نوشته هستند و برنامه نویس اول، فقط متنو میبینه و حالت صورت یا احساسات شما رو نمیبینه در نتیجه باید با دقت نوشته بشن و حواسمون باشه که نرم بیان بشن مثلا جمله : "این کد رو اینجوری بنویس..." میتونه به شکل "به نظرم شاید بتونیم از این کد هم استفاده کنیم، نظر تو چیه؟" تغییر کنه.
وقتی کامنتی میذاریم، بدونیم که کامنتها معمولا مختصر هستند و ممکنه منظورو دقیق نرسونند، اگر تونستیم حتما چیزی که میگیم یه نمونه کد هم براش قرار بدیم که منظور واضح تر بشه
اگر کامنت و پاسخ ها بیشتر از ۳،۴ تا شد، بهتره بریم و به صورت حضوری حرف بزنیم چون مشخصه که منظورامونو نمیتونیم درست به هم برسونیم
کد رویو ها یکی از دردسترس ترین راه ها برای یادگیری و آموزش هستند، برنامه نویس جونیور با نگاه کردن به کد های سنیور ها میتونه یاد بگیره و یا سوال هایی بپرسه و همچنین سنیور ها با نگاه کردن به کدهای جونیور ها میتونین چیزای جدید یاد بگیرن و هم به بقیه یاد بدن با کامنتایی که میذارن. در نتیجه کد ریو ها برای همه باید باشه و کاملا چرخشی باشه یعنی بین تمام اعضای تیم تقسیم بشه این وظیفه
یه جاهایی نیاز به رفتو برگشت نیست، مثلا یه غلط املایی نیاز نیست گوشزد بشه، میتونیم خودمون برنچو بگیریم درستش کنیم و بذاریم بالا، فقط باید یه کامنت بذاریم که "اینجا غلط املایی بود با اجازه خودم درستش کردم" یا اینکه "اگه اجازه بدی خودم درستش کنم"...
کدهایی که بررسی میکنیم باید تماما در یک مرحله بررسی بشه، یعنی اینجور نباشه که نصفشو الان بررسی کنیم و بگیم مشکلاتو برطرف کنند و بعدا نصف دیگه رو بررسی کنیم. دو دلیل داره اول اینکه وقتی کد رفتو برگشت ممکنه همونجا هایی که تغییر کرده بازم مشکل داشته باشه و دوم اینکه رفتو برگشت ها برای برنامه نویس اول کمی خسته کنندس، بهتره تمام موارد همون موقع گفته بشه تا اونم، همه رو توی یه مرحله درست کنه
موارد Conventions و lint میتونن به صورت اوتوماتیک انجام بشن، گیت hook میگیره و با هر کامیت یه اسکریپت ران میکنه روی کد، اینجوری میتونین اون مواردو همون اول که در حال توسعه هست، پیدا کنین و تصحیح کنین
وقتی دارین ریویو میکنین یه کانتکستی از چیزی که دارین ریویو میکنین داشته باشین، مثلا تسک جیراش رو بخونین، این کمک میکنه هم جاهای تاریک اپلیکیشن کمتر بشن، و هر بخشو حداقل دو نفر دربارش بدونن
کد ریویو ها از ۱۵ تا ۱ ساعت میتونین طول بکشن که بهتره به نسبت هر تسک توی زمان برنامه ریزی و اسپرینت پلنینگ در نظر گرفته بشه
اینجا یه مفهوم جالب به نام Merge Hell داریم
با Merge Hell آشنا بشیم
روند PR میتونه مارو درگیر خودش کنه، چون حتی کوچیکترین تغییرات هم نیاز به PR دارند، یعنی هر تغییر یه PR میتونه باشه در نتیجه ما با حجم زیادی از PRها مواجه میشیم، این کارو میتونه سخت کنه و اصطلاحا توی جهنم این درخواستا گرفتار شین.
چطور از Merge Hell فرار کنیم؟
و... PR ها باید بین تمام اعضای تیم تقسیم بشه، حتی الامکان سعی بشه که PR نه اونقدر کوچیک باشن و نه اونقدر بزرگ که بررسیشون سخت شه. PR ها رو کسی که میزنه خودشم توی توضیحاتش افرادیو منشن کنه، بر اساس سایز اون فیچر از یک تا چند نفر رو منشن کنه و همچنین این افراد میتونن از کسایی انتخاب شن که با اون بخش کمی اشنایی داشته باشن و همچنین کسی که هیچ ارتباطی با اون بخش نداشته و حتی یکی از تیم اندروید یا iOS یا تیم دیگری که اونا هم همین فیچر رو پیاده سازی کرده اند
خلاصه و نتیجه گیری
برای اینکه بتونیم روند PR رو نظم بدیم باید یه سری موارد رو در نظر داشته باشیم
یک تمپلیت داشته باشیم که هرکسی که PR رو زد، اون موارد رو قبلش انجام داده باشه مثلا خود فرد قبلش کد هاشو Review کرده باشه، تست هاشو نوشته باشه، از نظر Code Conventions کدشو بررسی کرده باشه همچنین توی PR لینک جیرای اون تسک رو داده باشه و یه توضیح کوچیک که چطور کارشو انجام داده، اگه لینک جیرا نداره، یه توضیح کوچیک بده که اصلا این تسک قراره چه کاری بکنه تا کسی که میاد ریویو میکنه یه تصویر کلی از کار داشته باشه
ریویو کننده باید توی کامنتا خیلی با ادب و محتاط عمل کنه و سعی کنه همه چیزو واضح بیان کنه، بحثا نباید زیاد باشه و از گفتگوی رودرو استفاده بشه اگر طولانی شد چون هیچ متنی نمیتونه به اندازه حرف زدن مفهوم و احساسات رو برسونه و قطعا کار سریعتر پیش میره
همه تیم باید ریویو کنند و اهمیتی نداره که کدی که نوشته شده توسط سنیور ها بوده یا نه. کدها چرخشی ریویو میشن تا تیم کامل از هم خبر داشته باشند و همگی یه تصویر کلی از کارهایی که توی اپ انجام میشه رو داشته باشند.
کد ریویو جایی هستش که میشه برای knowledge sharing ازش استفاده کرد، پیشنهاد من اینه که از این فرصت استفاده کنید. اگر در کامنتی اطلاعات مفیدی ردو بدل شد، کسی که PR رو ثبت کرده اون اطلاعات مفید رو توی Wiki قرار بده تا همه بخونند و اگر کسی به تیم اضافه شد راحت اون ویکی رو بررسی کنه و دیگه اشتباهات قبلیو تکرار نکنه و اون زمان حفظ بشه برای کل تیم
وقتی داریم برای تسک ها برنامه ریزی میکنیم، زمان Code Review ها حتما توی تایم ها در نظر گرفته بشه چون گاهی وقتا واقعا زمانگیر و انرژی بر هستند
توی کد ریویو ها، Conventions ها بررسی بشه، اگر فیچر بزرگی هستش حتما ریویو کننده اون کد رو پول کنه و روی گوشیش تست کنه تا مطمئن شه روی گوشی اونم درست داره کار میکنه، اگر کد بزرگ هستش، حداقل ۲ نفر به غیر از توسعه دهنده اون کد، اونو ریویو کنند، اگر کاریو میشه اوتوماتیک کرد حتما با CI/CD یا هوک های گیت، اونو انجام بدیم تا در زمان صرفه جویی بشه.
برنامه نویس حتما اگر کد جدیدی استفاده میکند یا روشیو پیاده سازی میکند، کامنت بالای کدش بذارد که وقتی ریویو کننده مبیبنه، بتونه یاد بگیره و درکش ساده تر بشه
کد ها بر اساس سایزشون میتونن از یک تا چند ریویو کننده داشته باشند و به نسبت حساسیت نیاز به اپرومنت بیشتری برای مرج شدن دارن.
کد ریویو ها کم ارزش یا بی ارزش نیستند و میتونن فرصت مناسبی برای اموزش و یادگیری و همچنین پیاده کردن باگ های احتمالی باشند و همچنین کمک میکنن که یک کد بیس یکپارچه و تمیز داشته باشیم.