248 آزمون، 22 گیت انتشار، بدون هیچ میانبُری: ما Statnive را چطور منتشر میکنیم
بیشتر افزونههای WordPress یک لینتر اجرا میکنند و کار را تمامشده میدانند. Statnive پیش از انتشار هر نسخه، از 5 لایه راستیآزمایی خودکار میگذرد؛ از هوکهای پیش از کامیت تا گیتهای انطباق با WordPress.org. اینجا دقیقاً میگوییم چه چیزهایی را بررسی میکنیم و چرا. (اعداد بر اساس نسخهٔ v0.4.9.)
پیش از نصب هر افزونه، به کد کس دیگری اعتماد میکنید
هر افزونهٔ WordPress که فعال میکنید، دسترسی کامل به پایگاهدادهٔ شما، پنل مدیریت و دادههای بازدیدکنندگانتان پیدا میکند. بیشتر صفحههای افزونه فقط یک امتیاز ستارهای و تاریخ «آخرین بهروزرسانی» را نشان میدهند. این اطلاعات برای یک تصمیم مبتنی بر اعتماد کافی نیست.
ما Statnive را طوری ساختیم که خودمان حاضر باشیم روی سایتهایمان به آن اعتماد کنیم. این نوشته شما را قدمبهقدم با همان خط لولهٔ کیفیتی آشنا میکند که هر خط از کد Statnive پیش از رسیدن به نصب WordPress شما از آن عبور میکند. هیچ ادعای مبهمی در کار نیست؛ بررسیهای مشخص، اعداد واقعی، و هشدارهای صادقانه دربارهٔ آنچه آزمون خودکار میتواند بگیرد و آنچه نمیتواند.
اعداد کلیدی (بر اساس v0.4.9): 248 آزمون واحد PHP، 31 بخش انطباق با WordPress.org، 22 گیت تخصصی انتشار (5 ایستا + 17 گرپ انطباق)، 3 نسخهٔ هدف PHP، و یک بودجهٔ 5 کیلوبایتی برای حجم ردیاب که روی تکتک بیلدها اعمال میشود.
لایهٔ 1: هوک پیش از کامیت — هیچ چیزی بدون بررسی وارد مخزن نمیشود
پیش از آنکه کد حتی وارد مخزن Git ما شود، یک هوک پیش از کامیت روی هر فایل استیجشده دو بررسی اجرا میکند:
برای تغییرات PHP:
- PHPCS (PHP CodeSniffer) فایلهای استیجشده را در برابر استانداردهای کدنویسی WordPress اعتبارسنجی میکند؛ همان مجموعه قواعدی که هستهٔ WordPress به کار میبرد. این کار، escape ناامن خروجی، نبودِ پاکسازی، و الگوهای غیراستاندارد کد را میگیرد.
- PHPUnit کل مجموعهٔ آزمون واحد را اجرا میکند. هر 248 آزمون باید پاس شوند. یک شکست کافی است تا جلوی کامیت گرفته شود.
برای تغییرات TypeScript/JavaScript:
- Vitest همهٔ آزمونهای کامپوننت React را اجرا میکند. رابط کاربری داشبورد نمیتواند بدون اینکه اینجا گرفته شود، پسرفت کند.
هوک پیش از کامیت عمداً سریع است؛ روی دستگاه توسعهدهنده در کمتر از 5 ثانیه اجرا میشود. هدف، جایگزینی CI نیست، بلکه گرفتنِ رایجترین اشتباهها پیش از آن است که یک رفتوبرگشت به GitHub را هدر دهند. در عمل، همین یک گیت حدود 80% از مشکلات را پیش از خروج از لپتاپ توسعهدهنده میگیرد.
لایهٔ 2: یکپارچهسازی پیوسته — 6 کار موازی روی هر پوش
هر پوش به شاخهٔ توسعه یا اصلی ما، و هر درخواست ادغام، یک خط لولهٔ CI روی GitHub Actions را با 6 کار موازی راه میاندازد:
| کار | چه چیزی را بررسی میکند | چرا مهم است |
|---|---|---|
| لینت (PHP 8.2، 8.3، 8.4) | PHPCS + PHPStan سطح 6 | استانداردهای کدنویسی و ایمنی نوع ایستا در 3 نسخهٔ PHP |
| آزمونهای واحد (PHP 8.2، 8.3، 8.4) | مجموعهٔ PHPUnit | درستیِ منطق در 3 نسخهٔ PHP |
| آزمون دودی کف حداقلی (PHP 8.0) | لینت نحوی + بوت بارگذار خودکار | اثبات میکند افزونه روی حداقل نسخهٔ اعلامشدهٔ PHP بارگذاری میشود |
| بیلد ردیاب | بیلد Vite + بررسی حجم gzip | بودجهٔ 5 کیلوبایتیِ gzip را روی ردیاب آماری اعمال میکند |
چرا 4 نسخهٔ PHP؟
سایتهای WordPress در دنیای واقعی روی PHP 8.0 تا 8.4 اجرا میشوند. تابعی که روی PHP 8.4 کار میکند، ممکن است روی PHP 8.0 رفتار متفاوتی داشته باشد؛ مقادیر پیشفرض پارامتر، قواعد اجبارِ نوع، و قابلیتهای منسوخ همگی در نسخههای مختلف فرق میکنند. ما روی سه نسخهای که مجموعهٔ کامل آزمونمان اجرا میشود (8.2، 8.3، 8.4) آزمون میگیریم و جداگانه تأیید میکنیم که کد تولیدی دستکم روی PHP 8.0 — حداقل اعلامشده در سربرگ افزونهٔ ما — پارس میشود و بوت میگیرد.
بودجهٔ 5 کیلوبایتیِ ردیاب
اسکریپت آماری JavaScript که بازدید صفحههای سایت شما را جمع میکند، یک سقف حجمی سفتوسخت دارد: 5,120 بایت پس از gzip. هر بیلد خروجی را اندازه میگیرد و اگر ردیاب از این بودجه بیشتر شود، خط لوله را شکستخورده اعلام میکند. این عدد دلبخواهی نیست؛ محک عملکرد ما نشان داد که حجم ردیاب مستقیماً با اثر روی LCP همبستگی دارد. این بودجه ما را وادار میکند مسیر بحرانی را کمینه نگه داریم و قابلیتهای غیرضروری را به یک اسکریپت ثانویهٔ ناهمگام موکول کنیم.
# From our CI workflow — the tracker size check
- name: Verify tracker size
run: |
MAX_SIZE=5120 # 5KB in bytes
GZIP_SIZE=$(gzip -c public/tracker/statnive.js | wc -c)
if [ "$GZIP_SIZE" -gt "$MAX_SIZE" ]; then
echo "::error::Tracker size (${GZIP_SIZE}B) exceeds limit (${MAX_SIZE}B)"
exit 1
fi
PHPStan در سطح 6
PHPStan ابزار تحلیل ایستایی است که باگها را بدون اجرای کد پیدا میکند. سطح 6 (از 10) ناهمخوانی نوعها، متغیرهای تعریفنشده، نوعهای بازگشتی نادرست، و مسیرهای کد مرده را میگیرد. ما آن را با افزونهٔ phpstan-wordpress اجرا میکنیم که امضای هوکهای WordPress، نوعهای بازگشتی فیلتر، و قراردادهای متد $wpdb را میفهمد. این روش، همراه با اجبارِ $wpdb->prepare()، خط دفاع اصلی ما در برابر تزریق SQL است؛ تحلیلگر ایستا هر پرسوجویی را که بهجای استفاده از عبارتهای آماده، ورودی کاربر را الحاق کند، نشانهگذاری میکند.
لایهٔ 3: انطباق با WordPress.org — 22 گیت انتشار
اینجا همان جایی است که خط لولهٔ کیفیت Statnive از بیشتر افزونههای WordPress جدا میشود. فراتر از لینت و آزمون استاندارد، ما 22 گیت انتشارِ مخصوصساخته (5 ایستا + 17 گرپ انطباق) اجرا میکنیم که راهنماهای افزونهٔ WordPress.org را اعمال میکنند؛ همان قواعدی که تیم بازبینی هنگام ثبت، دستی بررسی میکند.
بیشتر توسعهدهندگان افزونه زمانی این قواعد را کشف میکنند که ثبتشان رد میشود. ما اینها را خودکار کردیم تا تخلفها روی هر کامیت گرفته شوند:
گیتهای امنیتی
نگهبانهای ABSPATH — هر فایل PHP باید پیش از اجرا، defined('ABSPATH') را بررسی کند. این کار جلوی دسترسی مستقیم به فایلهای افزونه از طریق نشانی را میگیرد؛ دسترسیای که میتواند مسیرهای سرور را لو دهد یا کد را بیرون از بافت WordPress اجرا کند. گیت ما هر فایل .php در درخت منبع را پویش میکند و اگر فایلی این نگهبان را نداشته باشد، شکست میخورد.
الگوهای ممنوع — یک پویش خودکار جلوی توابع خطرناک PHP را که WordPress.org صراحتاً رد میکند میگیرد: eval()، exec()، shell_exec()، system()، passthru()، و curl_init(). همچنین تگهای کوتاه PHP، json_encode() خام (که باید wp_json_encode() باشد)، و مسیرهای wp-content نوشتهشدهٔ سفتوسخت را میگیرد.
انطباق با WP API — بررسی میکند که همهٔ اسکریپتها و شیوهنامهها بهجای تگهای <script> یا <link> نوشتهشدهٔ سفتوسخت، از سامانهٔ enqueue WordPress استفاده میکنند. همچنین به دنبال دسترسی پاکسازینشده به سوپرگلوبالها ($_GET، $_POST، $_REQUEST) است؛ یکی از مهمترین دلایلی که WordPress.org ثبت افزونهها را رد میکند.
گیتهای یکپارچگی
سازگاری readme و نسخه — نسخهٔ افزونه باید در سه جا یکسان باشد: تگ Stable در readme.txt، سربرگ statnive.php، و ثابت PHP به نام STATNIVE_VERSION. ناهمخوانی یعنی WordPress شمارهٔ نسخهٔ اشتباهی نشان میدهد؛ گیجکننده برای کاربران و یک پرچم قرمز برای بازبینها. این گیت همچنین شمار تگها (حداکثر 5)، طول توضیح کوتاه (حداکثر 150 نویسه)، وجود فایل LICENSE، و بخش افشای سرویسهای بیرونی را اعتبارسنجی میکند.
اعتبارسنجی ZIP توزیع — همان فایل ZIP را که قرار است در WordPress.org بارگذاری شود میسازد، سپس محتوایش را اعتبارسنجی میکند. فایلهای الزامی باید حاضر باشند (statnive.php، readme.txt، LICENSE، src/Plugin.php، منبع کوچکنشدهٔ ردیاب). فایلهای ممنوع باید غایب باشند (node_modules/، .git/، composer.json، tests/، phpunit، فایلهای پیکربندی). حجم ZIP باید زیر 25 مگابایت بماند.
برابری سربرگ — تأیید میکند که هر 11 فیلد الزامی سربرگ افزونه حاضر و سازگارند. بررسی میکند که نسخهٔ WordPress در Tested up to در فاصلهٔ 2 انتشار جزئی از نسخهٔ پایدار فعلی باشد؛ یک مقدار کهنه نشانهٔ افزونهای رهاشده است و میتواند رتبهٔ جستوجوی WordPress.org را تحت تأثیر بگذارد.
گیتهای معماری
بازدارندههای معماری — به دنبال الگوهایی است که نشانهٔ تخلف از سیاستها هستند: تماسهای HTTP خانهبهتلفن درون هوکهای فعالسازی (کاربر نباید هنگام فعالسازی افزونه شاهد درخواست شبکه باشد)، هوکهای بهروزرسان خودکار سفارشی (WordPress.org خودش بهروزرسانیها را مدیریت میکند)، و پایگاهدادهٔ GeoIP محصول MaxMind که همراه افزونه بستهبندی شده باشد (کاربران باید کلید مجوز خودشان را تأمین کنند).
مرز فریمیوم — نسخهٔ رایگان WordPress.org نباید کد دروازهبندی مجوز داشته باشد. این گیت به دنبال الگوهایی مانند isPro()، checkLicense()، trial_expires، و premium_only است؛ تا مطمئن شود بیلد .org واقعاً رایگان است، نه یک نسخهٔ آزمایشی ناقص.
ممیزی سرویسهای بیرونی — هر دامنهٔ https:// ارجاعشده در کد منبع PHP را استخراج میکند، سپس تأیید میکند هر کدام در بخش سرویسهای بیرونی readme.txt مستند شده است. هر اتصال بیرونی مستندنشده، بیلد را شکست میدهد. ما به این شکل شفافیت دربارهٔ مسیر جریان دادههای شما را تضمین میکنیم.
Statnive را بگیرید: کدی که میتوانید به آن اعتماد کنید
هر بررسیای که در این نوشته توضیح داده شد، روی هر تغییر بهصورت خودکار اجرا میشود. هیچ انسانی لازم نیست یادش بماند پویش امنیتی را اجرا کند یا سازگاری نسخه را بررسی کند؛ خط لوله آن را اعمال میکند. Statnive را از WordPress.org نصب کنید و نتیجه را ببینید: آمار سریع و خصوصی روی سرور خودتان.
لایهٔ 4: Plugin Check WordPress — سختگیرانهتر از حد لازم
Plugin Check (PCP) ابزاری رسمی از تیم WordPress.org است که همان بررسیهای خودکاری را اجرا میکند که تیم بازبینی به کار میبرد. بیشتر افزونهها PCP را طوری پیکربندی میکنند که فقط روی خطاها شکست بخورد.
Statnive هم روی خطاها و هم روی هشدارها شکست میخورد.
این یک انتخاب عمدی است. هشدارهای PCP اغلب مشکلات واقعی را نشان میدهند — استفاده از توابع منسوخ، شکافهای دسترسپذیری، نگرانیهای عملکردی — که از نظر فنی جلوی ثبت را نمیگیرند، اما کیفیت افزونه را بهمرور پایین میآورند. ما با برخورد با هشدارها همچون خطا، مشکلاتی را میگیریم که افزونههای دیگر با همانها منتشر میشوند.
گیت PCP روی پوشهٔ توزیع ساختهشده (نه درخت منبع) و با PHP 8.0 — حداقل اعلامشده — اجرا میشود. یعنی دقیقاً همان چیزی را آزمون میکنیم که کاربران نصب میکنند، روی قدیمیترین نسخهٔ PHP که پشتیبانی میکنیم.
لایهٔ 5: گیت انتشار — 31 بخش پیش از انتشار هر نسخه
پیش از هر انتشار، گیت کامل همهٔ موارد بالا را در یک تصمیم واحدِ پاسیاشکست ترکیب میکند:
گیتهای آزمون ایستا (همه باید پاس شوند):
| گیت | بررسی | ابزار |
|---|---|---|
| S-1 | استانداردهای کدنویسی WordPress | PHPCS |
| S-2 | تحلیل نوع ایستا | PHPStan سطح 6 |
| S-3 | آزمونهای واحد + یکپارچگی PHP | PHPUnit |
| S-4 | آزمونهای کامپوننت React | Vitest |
| S-5 | Plugin Check رسمی | PCP (خطاها + هشدارها) |
گیتهای گرپ انطباق (17 بررسی الگوی خودکار):
| گیتها | چه چیزی را اعمال میکنند |
|---|---|
| C-1 | نگهبانهای ABSPATH روی هر فایل PHP |
| C-2 | اعتبارسنجی فایل مجوز |
| C-3، C-4 | بدون خانهبهتلفن هنگام فعالسازی، بدون دیوار پرداخت پنهان |
| C-5 | ساختار readme، برابری نسخه، افشای سرویسهای بیرونی |
| C-6 | بدون دسترسی پاکسازینشده به سوپرگلوبالها |
| C-7 | بدون پایگاهدادهٔ GeoIP بستهبندیشده |
| C-8، C-9، C-10 | بدون بهروزرسان سفارشی، بدون کتابخانههای هستهٔ بستهبندیشده، بدون CDN بیرونی |
| C-11، C-12 | پاکسازی cron هنگام غیرفعالسازی، وجود تابع حذف نصب |
| C-13 | ساختار پوشهٔ داراییهای SVN |
| C-14 | یکپارچگی و حجم ZIP |
| C-15 | ساخت جدول پایگاهداده از قالب dbDelta پیروی میکند |
| C-16 | همهٔ رشتههای روبهروی کاربر بینالمللیسازی شدهاند |
| C-17 | هوکهای Privacy API WordPress ثبت شدهاند |
فراتر از گیتهای خودکار، هر انتشار شامل یک بازبینی دستی است که بودجههای عملکرد، سازگاری مرورگر، دسترسپذیری (WCAG 2.2 AA)، روشنیِ تجربهٔ کاربری پنل مدیریت، ایمنی ارتقا/مهاجرت، و مدیریت خطا را پوشش میدهد. سیاههٔ کامل، 31 بخش را در 3 سطح شدت در بر میگیرد:
- بحرانی — گیتهای خودکاری که خط لولهٔ انتشار را مسدود میکنند
- بازدارندهٔ انتشار — بررسیهای دستی که پیش از برچسبزدن یک نسخه باید پاس شوند
- گیت کیفیت — استانداردهایی که خودمان را به آنها پایبند میدانیم؛ بازبینی میشوند اما توصیهایاند
امنیت و حریم خصوصی: راستیآزماییشده با خط لوله، نه فقط وعدهدادهشده
بسیاری از افزونههای آماری قابلیتهای امنیت و حریم خصوصی را در صفحهٔ بازاریابیشان فهرست میکنند. ما ترجیح میدهیم نشان دهیم این وعدهها چطور بهصورت مکانیکی اعمال میشوند:
همهٔ پرسوجوهای SQL از عبارتهای آماده استفاده میکنند. افزونهٔ WordPress در PHPStan هر فراخوانی متد $wpdb را که بهجای استفاده از $wpdb->prepare() ورودی کاربر را الحاق کند، نشانهگذاری میکند. این مورد در زمان تحلیل ایستا گرفته میشود؛ پیش از آنکه کد اصلاً اجرا شود.
بدون کوکی، localStorage یا اثرانگشتگیری. گیتهای انطباق به دنبال توابع تنظیم کوکی و APIهای ذخیرهسازی مرورگر میگردند. مجموعهٔ آزمون واحد تأیید میکند که بار دادهٔ ردیاب فقط شناسههای هششده و برگشتناپذیر بازدیدکننده را در بر دارد.
نمکهای چرخان روزانه. هر بازدیدکننده هر روز یک هش متفاوت تولید میکند و این مانع ردیابی بینروزی میشود. این مورد را آزمونهای واحد اختصاصی پوشش میدهند که یکتایی هش را در چرخشهای نمک تأیید میکنند.
امضاهای HMAC روی بارهای دادهٔ ردیاب. هر بازدید صفحه با یک کلید تولیدشدهٔ سرور امضا میشود. راستیآزمایی امضا در مجموعهٔ آزمون واحد آزمون میشود؛ بارهای دادهٔ نامعتبر یا دستکاریشده رد میشوند.
شفافیت سرویسهای بیرونی. گیت CI هر دامنهٔ بیرونی را از کد منبع استخراج میکند و تأیید میکند که در افشای readme.txt ظاهر میشود. اگر توسعهدهندهای یک تماس HTTP به دامنهای تازه اضافه کند، بیلد تا مستندشدنِ آن دامنه شکست میخورد.
آنچه آزمون خودکار نمیتواند بگیرد
ما به شفافیت دربارهٔ محدودیتها باور داریم، نه فقط دربارهٔ تواناییها.
آزمونهای خودکار تأیید میکنند که کد تحت شرایط شناختهشده درست رفتار میکند. آنها نمیتوانند اینها را بگیرند:
- سردرگمی ظریف در تجربهٔ کاربری — نموداری در داشبورد که از نظر فنی درست است اما برای کاربران غیرفنی گمراهکننده است
- حالتهای مرزی عملکرد — پرسوجویی که با 1,000 ردیف سریع است اما در 100,000 ردیف کند میشود. ما برای مسیرهای بحرانی آزمون بار k6 داریم، اما نمیتوانند هر شکل از داده را پوشش دهند
- تعارضهای زیستبوم WordPress — تعاملهای افزونه یا پوسته که فقط روی پیکربندیهای میزبانی خاص بروز میکنند. ما در برابر WP 6.4 تا trunk آزمون میگیریم، اما زیستبوم WordPress بیش از 60,000 افزونه دارد
- آسیبپذیریهای روز صفر — هیچ میزان تحلیل ایستایی مانع بهرهکشی از مسیرهای حملهٔ ناشناختهٔ پیشین نمیشود
ما این شکافها را با بازبینی دستی روی هر انتشار، یک مخزن عمومی GitHub که هر کس میتواند کد را در آن ممیزی کند، و پایش فعال انجمنهای پشتیبانی WordPress.org برای گزارشهای نصبهای دنیای واقعی، کم میکنیم.
چرا این را منتشر کردیم
پژوهشها نشان میدهند که بیش از 50% توسعهدهندگان افزونهٔ WordPress آسیبپذیریهای گزارششده را پیش از افشای عمومی وصله نمیکنند. افزونهها سالها بدون بهروزرسانی میمانند. کاربران هیچ راهی ندارند که یک افزونهٔ خوبنگهداریشده را از یک افزونهٔ رهاشده تشخیص دهند، جز امتیاز ستارهای و تاریخ «آخرین بهروزرسانی».
به نظر ما زیستبوم WordPress سزاوار نشانههای بهتری است. انتشار خط لولهٔ کیفیتمان یک راه برای بالا بردن سطح توقع است؛ هم برای خودمان (حالا که عمومی شده، نمیتوانیم بیسروصدا از بررسیها بگذریم) و هم برای زیستبوم (سایر توسعهدهندگان افزونه میتوانند شیوههای مشابهی را به کار بگیرند).
اگر در حال ارزیابی افزونههای آماری برای سایت WordPress خود هستید، تشویقتان میکنیم از هر گزینه بپرسید: چطور آزمون میگیرید؟ پیش از یک انتشار چه بررسیهایی اجرا میشوند؟ میتوانم پیکربندی CI را ببینم؟
کل کدبیس Statnive روی GitHub متنباز است. هر فایل گردشکار، هر آزمون، و هر گیت انطباقی که در این نوشته توضیح داده شد، بهصورت عمومی قابل ممیزی است.
Statnive را امتحان کنید
همهٔ این مهندسی برای خدمت به یک هدف وجود دارد: دادن آماری به شما که میتوانید روی سرور WordPress خودتان به آن اعتماد کنید. بدون انتقال داده به اشخاص ثالث، بدون کوکی، بدون اسکریپتهای ردیابی که سایتتان را کند میکنند.
Statnive را رایگان از WordPress.org نصب کنید — دادههای شما روی سرور خودتان میماند، راستیآزماییشده با 248 آزمون و 22 گیت انتشار روی هر انتشار.