أتمتة مراجعة تحديثات npm قبل ما الديون تتراكم
مستوى القارئ: متوسط
هتكسب نظام بسيط يخلي تحديثات npm تظهر كل أسبوع في GitHub Issue واضح، بدل ما تكتشف بعد شهرين إن عندك 27 حزمة متأخرة.
المشكلة باختصار
الطريقة الشائعة إن الفريق يعمل npm outdated لما يحصل bug أو vulnerability. الطريقة دي بتفشل لأن المراجعة بتبقى رد فعل، مش عادة ثابتة. لو عندك مشروع React أو Next.js فيه 80 dependency، تأخير المراجعة 30 يوم ممكن يخلي تحديث major واحد يتحول إلى 6 تحديثات متداخلة.
الافتراض هنا إن عندك مشروع Node.js موجود على GitHub، وبتستخدم package-lock.json، وعايز تنبيه للمراجعة فقط. الأوتوميشن مش هيعمل upgrade تلقائي. وده مقصود.
مثال سريع قبل الشرح الدقيق
ركز في السيناريو ده: عندك dashboard داخلي، والفريق بيعمل release كل أسبوعين. بدل ما حد يفتح التيرمنال يدويًا، GitHub Actions يشتغل كل يوم إثنين الساعة 07:10 UTC، ينفذ npm ci، ثم npm outdated --json، ولو لقى تحديثات يفتح issue بعنوان ثابت. المالك يراجع، يقرر: minor آمن، major يحتاج PR منفصل، أو تجاهل مؤقت.
الرقم العملي: المراجعة الشهرية تترك نافذة drift حوالي 30 يوم. الأوتوميشن الأسبوعي يقللها إلى 7 أيام. ده تقليل تقريبي 76% في زمن بقاء التحديثات بدون نظر، لكنه لا يعني 76% أمان أعلى. هو فقط يقلل زمن الغفلة.
ملف GitHub Actions القابل للنسخ
اعمل ملف جديد في .github/workflows/npm-outdated-review.yml. أفضل طريقة هنا إنك تفتح issue للمراجعة، مش PR تلقائي، لأن latest ممكن يكسر compatibility حتى لو الاختبارات خضراء.
name: Weekly npm outdated review
on:
schedule:
- cron: "10 7 * * 1"
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
outdated:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install locked dependencies
run: npm ci
- name: Collect outdated packages
run: npm outdated --json > outdated.json || true
- name: Build issue body
run: |
node <<'NODE'
const fs = require('fs');
const raw = fs.existsSync('outdated.json') ? fs.readFileSync('outdated.json', 'utf8').trim() : '';
const data = raw ? JSON.parse(raw) : {};
const rows = Object.entries(data).map(([name, info]) => {
return `| ${name} | ${info.current} | ${info.wanted} | ${info.latest} | ${info.type || ''} |`;
});
if (rows.length === 0) {
fs.writeFileSync('issue.md', '');
process.exit(0);
}
const body = [
'## npm outdated weekly review',
'',
'| package | current | wanted | latest | type |',
'|---|---:|---:|---:|---|',
...rows,
'',
'Decision rule:',
'- Patch/minor: update in one PR if tests are stable.',
'- Major: open a separate PR with changelog review.',
'- Unknown owner: assign the package area owner first.'
].join('\n');
fs.writeFileSync('issue.md', body);
NODE
- name: Open review issue
if: hashFiles('issue.md') != ''
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ ! -s issue.md ]; then
echo "No outdated packages found"
exit 0
fi
existing=$(gh issue list --state open --label dependency-review --json title --jq '.[] | select(.title == "Weekly npm outdated review") | .title' | head -n 1)
if [ -n "$existing" ]; then
echo "Review issue already open"
exit 0
fi
gh issue create \
--title "Weekly npm outdated review" \
--label "dependency-review" \
--body-file issue.md
اللي بيحصل فعلاً
npm outdated يقارن بين 3 قيم مهمة. current هي النسخة الموجودة عندك. wanted هي أعلى نسخة مسموحة داخل range الموجود في package.json. latest هي أحدث نسخة منشورة تحت dist-tag الافتراضي. بالظبط هنا تظهر الفائدة: لو wanted قريب وlatest بعيد، يبقى عندك major jump محتاج قرار، مش مجرد تحديث عادي.
الـ trade-off هنا واضح. بتكسب مراجعة منتظمة وسجل قرارات داخل Issues. بتخسر دقائق CI أسبوعيًا، واحتمال issue زائد لو مشروعك فيه dependencies كتير بتتغير بسرعة. لو الدقيقة على runner عندك مكلفة، شغله أسبوعيًا وليس يوميًا.
متى لا تستخدم هذه الطريقة
لا تستخدمها كبديل لفحص الثغرات. npm outdated يتكلم عن حداثة الحزم، مش عن CVE severity. لو هدفك الأمن فقط، استخدم audit أو أداة مخصصة زي Dependabot/Renovate مع policy واضحة. كذلك لا تستخدمها لو الريبو monorepo ضخم وفيه 20 workspace بدون فلترة؛ ابدأ بworkspace واحد عشان الإشارة متتحولش لضوضاء.
مصادر اعتمد عليها المقال
الخطوة التالية
افتح الريبو، أضف الملف كما هو، وشغله يدويًا من workflow_dispatch. لو فتح issue مليان packages، لا تحدثهم كلهم مرة واحدة؛ ابدأ بأول 3 minor updates ومعاهم اختبار regression واضح.