Code Review چیست و چرا برای کیفیت نرمافزار مهم است؟
تعریف Code Review در جریان Pull Request، انواع Approve و Request changes طبق GitHub Docs، منافع کیفیت و دانش، و اشتباههای رایج بدون شعار.
بنیانگذار و مهندس محصول

نوشتن کد فقط نیمی از کار است؛ نیم دیگر این است که تغییر قبل از ورود به شاخهٔ مشترک، توسط انسان یا ترکیبی از انسان و ابزار دیده شود. Code Review (بررسی کد) دقیقاً همین توقفگاه است: خواندن diff، پرسیدن «چرا»، پیشنهاد اصلاح، و تصمیم آگاهانه برای Merge.
در اکوسیستم GitHub این کار معمولاً داخل Pull Request انجام میشود: Reviewer میتواند کامنت خطی بگذارد، تغییر پیشنهاد دهد، و در نهایت یکی از تصمیمهای Comment، Approve یا Request changes را ثبت کند. هدف نمایش قدرت نیست؛ کاهش ریسک باگ، نشت Secret، و دانش تکنفره است.
این مقاله تعریف عملی، منافع واقعی، هزینهها، چکلیست نویسنده و Reviewer، و نشانههای Review ناسالم را پوشش میدهد تا تیم بداند زمان Review سرمایهگذاری است یا ترمز نمایشی.

پاسخ کوتاه
Code Review فرآیند بررسی تغییرات پیشنهادی قبل از ادغام در شاخهٔ اصلی (یا هر شاخهٔ محافظتشده) است. در GitHub، Pull Request Review به افراد اجازه میدهد بازخورد بدهند، بهبود پیشنهاد کنند، و قبل از Merge تأیید یا درخواست اصلاح کنند. هر کسی با دسترسی خواندن میتواند کامنت بگذارد؛ درخواست رسمی Review و قوانین اجباری به سطح دسترسی و تنظیمات مخزن بستگی دارد.
Review خوب باگ منطقی، قرارداد API، خوانایی، تست، و ریسک امنیتی را زود میگیرد؛ Review بد فقط سلیقهٔ فاصلهگذاری را جروبحث میکند یا بدون خواندن Approve میزند. کیفیت نرمافزار از ترکیب تست خودکار + Review انسانی + اندازهٔ کوچک تغییر میآید — نه از یکی بهتنهایی.
Approve بدون خواندن، امضای خالی است؛ Request changes بدون پیشنهاد مشخص، فقط اصطکاک است.
Review در عمل روی Pull Request
طبق مستندات GitHub دربارهٔ Pull Request Reviews، وقتی Reviewer بررسی را Submit میکند یکی از این تصمیمها را انتخاب میکند:
| تصمیم | معنی عملی |
|---|---|
| Comment | بازخورد عمومی بدون تأیید یا رد صریح |
| Approve | سیگنال آمادگی برای Merge |
| Request changes | نویسنده باید بازخورد را قبل از Merge رسیدگی کند |
علاوه بر تصمیم نهایی، میتوان روی خطوط مشخص کامنت گذاشت، پیشنهاد دقیق (suggestion) داد، و جزئیات پیادهسازی را بحث کرد. این گفتگوها در تایملاین PR میمانند تا تیم تصمیم و دلیلش را بعداً ببیند.
درخواست Review و الزام آن
برای Request کردن Review معمولاً دسترسی Write لازم است. میتوان فرد یا تیم دارای Read را بهعنوان Reviewer گذاشت تا اعلان بگیرند. اگر CODEOWNERS تعریف شده باشد، GitHub میتواند مالکان کد را خودکار صدا بزند. ادمین مخزن میتواند Approval اجباری بگذارد تا شاخههای مهم بدون Review لازم Merge نشوند — بخشی از Protected Branch.
چرا برای کیفیت مهم است؟
- خطای منطقی که تست واحد ندیده را انسان گاهی میبیند — بهویژه Edge Caseهای دامنهٔ کسبوکار.
- دانش پخش میشود: نفر دوم میفهمد این بخش سیستم چگونه کار میکند.
- استاندارد تیمی (نامگذاری، خطا، لاگ، امنیت) بدون پلیسبازی در عمل منتقل میشود.
- تغییرات پرریسک (پرداخت، احراز هویت، مهاجرت داده) شانس بیشتری برای توقف دارند.
- تاریخچهٔ تصمیم در PR میماند؛ شش ماه بعد «چرا اینطور شد؟» جواب دارد.
کیفیت فقط نبود باگ نیست. خوانایی، قابلیت نگهداری، و کاهش Bus Factor هم خروجی Review سالماند. اگر فقط یک نفر کل ماژول را میفهمد، Review اجباری حداقل یک نفر دوم میسازد.
چه چیزی را Review کنیم؟ چه چیزی را نه؟
اولویت بالا
- درستی رفتار نسبت به Acceptance Criteria یا توضیح PR.
- امنیت: احراز هویت، مجوز، تزریق، Secret، لاگ حساس.
- سازگاری API و مهاجرت دادهٔ برگشتپذیر.
- تستهای معنادار برای مسیر خوشحال و شکست.
- عملکرد در مسیرهای داغ (N+1، قفل، timeout).
اولویت پایین یا ابزار
فاصلهگذاری، ترتیب Import، و قانونهای Style را تا حد ممکن به Formatter و Linter بسپارید. اگر Reviewer نیمساعت روی فاصله بحث میکند، هزینهٔ فرصت کیفیت واقعی را میپردازید. انسان برای قضاوت دامنه و ریسک است؛ ربات برای یکنواختی ظاهری.
عادتهای نویسندهٔ PR
- PR را کوچک نگه دارید؛ چند صد خط متمرکز بهتر از هزار خط مخلوط است.
- در توضیح بنویسید: مسئله، راهحل، نحوهٔ تست، ریسک، و اسکرین/لاگ در صورت نیاز.
- قبل از درخواست Review خودتان Files changed را بخوانید — انگار غریبهاید.
- CI را سبز کنید مگر موضوع PR تعمیر CI باشد.
- به کامنتها با اصلاح یا توضیح پاسخ دهید؛ Ignore خاموش اعتماد را میسوزاند.
Draft برای کار نیمهتمام مفید است تا Reviewرها با نوتیفیکیشن زودرس خسته نشوند. وقتی Ready شد، صریح Review بخواهید.
عادتهای Reviewer
- اول هدف تغییر را بفهمید، بعد خطبهخط بروید.
- سوال بپرسید قبل از حکم قطعی؛ شاید زمینه در Issue باشد.
- پیشنهاد مشخص بدهید («این تابع را خالص کنید چون…») نه فقط «بد است».
- بین Blocker و Nit تفاوت بگذارید؛ Nit را اختیاری علامت بزنید.
- اگر Approve میکنید، مسئول همان سطح ریسکی باشید که دیدهاید.
زمان پاسخ مهم است. Reviewی که سه روز معطل میماند، نویسنده را به PRهای بزرگتر و عجلهٔ بیشتر هل میدهد — حلقهٔ معیوب.
Review و ابزار خودکار
تب Checks در PR تست، Build و اعتبارسنجی را نشان میدهد. Findings میتواند هشدارهای بررسی خودکار را کنار diff بیاورد. اینها جایگزین Review انسانی نیستند؛ لایهٔ اول فیلترند. تیم بالغ: Linter و تست را اجباری میکند، و انسان روی منطق و محصول تمرکز میکند.
Secret scanning و قوانین Branch Protection مکمل Reviewاند. Reviewر باید به رشتههای شبیه کلید، فایل .env، و credential در تستها حساس باشد — حتی اگر ابزار چیزی نگفته باشد.
نشانههای فرهنگ ناسالم
| نشانه | پیامد محتمل | اصلاح اولیه |
|---|---|---|
| Approve ظرف یک دقیقه روی PR بزرگ | باگ و دانش تکنفره | الزام اندازه + چکلیست کوتاه |
| بحث بیپایان روی سلیقه | فرسودگی | Formatter اجباری؛ راهنمای Style کوتاه |
| فقط Lead حق Approve دارد | گلوگاه و صف | CODEOWNERS توزیعشده؛ مربیگری |
| Request changes مبهم | رفتوبرگشت بیحاصل | الزام پیشنهاد یا مثال |
| هیچ Review روی hotfix | ریسک تولید | مسیر اضطراری مکتوب با Review بعدی |
برای PM و مالک محصول
وقتی مهندس میگوید «منتظر Reviewام»، این تأخیر اغلب کیفیت است نه بهانه. کار شما کمک به کوچک کردن Scope، اولویتبندی واضح، و محافظت از زمان Review در تقویم است — نه حذف Review برای رسیدن به تاریخ ساختگی.
معیارهای مفید: میانهٔ زمان تا اولین Review، درصد PR با حداقل یک Comment معنادار، نرخ برگشت بعد از Merge، و رضایت نویسنده/Reviewر در بازبینی فصلی. عدد خام «تعداد Approve» بهتنهایی گمراهکننده است.
حداقل سیاست برای تیم ۳ تا ۱۰ نفره
- هیچ Merge به main بدون یک Approve از نفر دوم (بهجز توافق مکتوب hotfix).
- PR بالای حدود ۴۰۰ خط خالص را بشکنید مگر مهاجرت اجباری یکتکه.
- Linter/Formatter در CI اجباری.
- مسیرهای پرداخت، احراز هویت و Secret همیشه دو Reviewر یا Lead + یک نفر.
- یک صفحهٔ کوتاه «چگونه Review میکنیم» در README یا Wiki.
سیاست باید کوتاه بماند وگرنه کسی نمیخواند. جزئیات ابزار را در قالب مخزن بگذارید، نه در جلسهٔ یکساعتهٔ تکراری.
جمعبندی برای تصمیم
Code Review توقفگاه انسانی کیفیت است که در GitHub داخل Pull Request با تصمیمهای Comment، Approve و Request changes رسمی شده است. ارزشش وقتی ظاهر میشود که تغییر کوچک باشد، توضیح روشن باشد، ابزار ظاهر را یکدست کند، و انسان روی ریسک و منطق تمرکز کند.
اگر فقط یک تغییر این Sprint میدهید: Approve بدون خواندن را ممنوع کنید و اندازهٔ متوسط PR را نصف کنید. کیفیت از همین دو عادت بیشتر از شعار «ما Review داریم» بالا میرود.
Review ناهمزمان و فرهنگ بازخورد
بیشتر تیمهای توزیعشده Review را ناهمزمان انجام میدهند: نویسنده توضیح مینویسد، Reviewر در بازهٔ کاری خودش میخواند. این فقط وقتی کار میکند که SLA داخلی وجود داشته باشد — مثلاً اولین پاسخ ظرف یک روز کاری برای PRهای متوسط. بدون SLA، نویسنده یا Scope را بزرگ میکند یا مستقیم به شاخهٔ اصلی فشار میآورد.
لحن بازخورد مهم است. جملهٔ این اشتباه است بدون جایگزین، دفاعی میسازد. اشاره به ریسک و پیشنهاد مسیر خروج همان نکته را سازندهتر میکند. Review دربارهٔ کد است نه شخصیت.
چه کسی باید Review کند؟
نفر دوم آگاه به دامنه بهتر از هر کسی که آنلاین است میباشد. CODEOWNERS این را خودکار میکند ولی اگر فقط یک Owner برای نیمی از مخزن باشد، دوباره گلوگاه میسازید. چرخش Reviewر و زوجسازی در PRهای آموزشی، دانش را پخش میکند.
برای تغییرات محصولی حساس، گاهی Review محصول یا طراحی لازم است — نه فقط مهندس. PR جای جایگزینی کامل مشخصات نیست، ولی اسکرین و لینک طرح جلوی سورپرایز بعد از Merge را میگیرد.
Review امنیتی حداقلی
- آیا ورودی کاربر اعتبارسنجی و Encode مناسب دارد؟
- آیا مسیر جدید احراز هویت و مجوز را دور میزند؟
- آیا Secret، کلید، یا دادهٔ واقعی در diff هست؟
- آیا لاگ جدید فیلد حساس چاپ میکند؟
- آیا وابستگی جدید با License و نگهداری مشخص است؟
این فهرست جای ارزیابی امنیتی کامل را نمیگیرد؛ حداقل چشمی است که قبل از Merge ارزان تمام میشود.
آیا Review سرعت را کم میکند؟
در کوتاهمدت بله، یک صف اضافه میکند. در میانمدت معمولاً سرعت تحویل پایدار را بالا میبرد چون بازکاری بعد از Production گرانتر است. اگر Review صف را هفتهای میکند، مشکل فرآیند است: PR بزرگ، Reviewر کم، یا اولویتبندی مبهم — نه اصل بررسی.
اندازهگیری قبل از شعار: میانهٔ زمان از باز شدن PR تا Merge را همراه نرخ حادثه بعد از Merge ببینید. تصمیم را با دادهٔ همان تیم بگیرید.
زوجبرنامهنویسی در برابر Review
Pairing میتواند بخشی از دانش را همان لحظه منتقل کند و بعداً Review سبکتر شود. جایگزین کامل Review رسمی برای مسیرهای پرریسک نیست مگر اینکه سیاست تیم صریح بگوید دو نفر همزمان روی یک تغییر معادل Approve است و آن را ثبت کند. ابهام اینجا بعداً در حسابرسی دردسر میسازد.
چکلیست پنجدقیقهای قبل از Approve
- توضیح PR را خواندم و هدف را فهمیدم.
- Files changed را کامل دیدم نه فقط تب Conversation.
- تستها یا دلیل نبودنشان را پذیرفتم.
- ریسک امنیتی آشکار ندیدم یا ثبت کردم.
- اگر Nit دارم، از Blocker جدا علامت زدم.
منابع و مراجع
- GitHub Docs — About pull request reviews — https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews
- GitHub Docs — About pull requests — https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
برای اتصال Review به امنیت مخزن، مقالات Public/Private و محافظت از Secret را در ادامه بخوانید.
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




