CI/CD Integration
أدلة
التكامل مع CI/CD
تقبل كل نقطة طرفية للماسح مفتاح API، لذا يمكن تشغيل أيٍّ منها كخطوة ضمن خط الأنابيب. تتناول هذه الصفحة معنى مخرجات كل أداة، وكيفية تحويلها إلى بوابة نجاح/فشل، وأمثلة عملية لأربع منصات CI.
أساس احتساب النتائج لكل أداة
ما تُعيده كل نقطة طرفية، وما الذي ينبغي تحديد حد أدنى له.
| الأداة | المخرجات | الأساس | بوابة مدمجة |
|---|---|---|---|
| تدقيق الموقع الإلكتروني | 4 نتائج من 0 إلى 100: performance وseo وaccessibility وbestPractices | نتائج Lighthouse الخام. المعيار: 90 فأكثر جيدة، من 50 إلى 89 بحاجة إلى تحسين، أقل من 50 ضعيفة. | لا توجد بوابة مدمجة — اختر الحد الأدنى الخاص بك لكل نتيجة. |
| فحص الأمان | riskScore من 0 إلى 100 (كلما ارتفعت القيمة، زادت السلامة) | 100 مطروحًا منها خصومات مرجّحة حسب الشدة ومحدودة لكل فئة. درجات التقييم: A+ 90 فأكثر … F أقل من 30. | لا توجد بوابة مدمجة — اختر الحد الأدنى الخاص بك. |
| اختبار المتصفح | مصفوفات: jsErrors وbrokenLinks وformIssues وimgIssues (لكل منها severity: "error" | "warning") | لا توجد نتيجة إجمالية. | بوابة تعتمد على عدد المشكلات، مثل وجود أي severity === "error". |
| ماسح المستودعات | score من 0 إلى 100 + qualityGate: "passed" | "failed" | 100 مطروحًا منها خصومات مرجّحة حسب الشدة، محدودة لكل فئة. | بوابة مدمجة — تفشل تلقائيًا عند وجود أي مشكلة حرجة أو نتيجة أقل من 60. |
إيقاف خط الأنابيب
آلية عمل CI واحدة بغض النظر عن المنصة: أي خطوة تخرج برمز غير صفري تُفشل المهمة. لمنع طلب سحب (PR) أو طلب دمج فعليًا من الدمج، أضف هذه المهمة كـ فحص مطلوب/إلزامي ضمن إعدادات حماية الفرع أو موافقات طلبات الدمج في مضيف المستودع لديك — فشل خطوة واحدة بمفرده يظهر باللون الأحمر فقط، ولا يمنع الدمج من تلقاء نفسه.
أمثلة على خطوط الأنابيب
الفحوصات الأربعة نفسها — التدقيق، وفحص الأمان، واختبار المتصفح، وفحص المستودع — مكتوبة لأربع منصات. اختر نظام CI الخاص بك أدناه.
name: Scanverra checks
on: [pull_request]
jobs:
scanverra:
runs-on: ubuntu-latest
env:
API_KEY: ${{ secrets.SCANVERRA_API_KEY }}
TARGET_URL: https://staging.example.com # your deployed preview URL
steps:
- name: Website Audit (perf/SEO/a11y)
run: |
RES=$(curl -sf -X POST https://www.scanverra.com/api/audit \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d "{\"url\":\"$TARGET_URL\"}")
echo "$RES" | jq .
PERF=$(echo "$RES" | jq '.scores.performance')
A11Y=$(echo "$RES" | jq '.scores.accessibility')
if (( $(echo "$PERF < 50" | bc -l) )) || (( $(echo "$A11Y < 90" | bc -l) )); then
echo "::error::Audit failed thresholds (perf=$PERF, a11y=$A11Y)"
exit 1
fi
- name: Security Scan
run: |
RES=$(curl -sf -X POST https://www.scanverra.com/api/security-scan \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d "{\"url\":\"$TARGET_URL\"}")
RISK=$(echo "$RES" | jq '.riskScore')
echo "riskScore=$RISK"
[ "$RISK" -lt 70 ] && { echo "::error::Security risk score too low ($RISK)"; exit 1; }
true
- name: Browser Test (JS errors, broken links)
run: |
RES=$(curl -sf -X POST https://www.scanverra.com/api/browser-test \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d "{\"url\":\"$TARGET_URL\"}")
ERRORS=$(echo "$RES" | jq '[.jsErrors[]? | select(.severity=="error")] | length')
[ "$ERRORS" -gt 0 ] && { echo "::error::$ERRORS JS errors found"; exit 1; }
true
- name: Repo Scan (SAST, secrets, deps, quality gate)
run: |
SCAN_ID=$(curl -sf -X POST https://www.scanverra.com/api/repo/scan \
-H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"owner":"your-org","repo":"your-repo","branch":"${{ github.head_ref }}"}' | jq -r .scanId)
for i in $(seq 1 30); do
RESULT=$(curl -sf "https://www.scanverra.com/api/repo/result?id=$SCAN_ID" -H "X-API-Key: $API_KEY")
STATUS=$(echo "$RESULT" | jq -r .status)
[ "$STATUS" != "running" ] && break
sleep 10
done
echo "$RESULT" | jq '{score, qualityGate}'
GATE=$(echo "$RESULT" | jq -r .qualityGate)
[ "$GATE" = "failed" ] && { echo "::error::Repo quality gate failed"; exit 1; }
trueأين تُخزَّن مفتاح API كسرّ (secret)، حسب المنصة:
- GitHub Actions: سرّ على مستوى المستودع — Settings ← Secrets and variables ← Actions.
- GitLab CI: متغيّر CI/CD مُخفى (masked) — Settings ← CI/CD ← Variables.
- Azure Pipelines: متغيّر خط أنابيب سرّي (أيقونة القفل) أو مجموعة متغيرات (Variable Group) ضمن Pipelines ← Library.
- Jenkins: بيانات اعتماد نصية سرية (Secret text credential) — Manage Jenkins ← Credentials — يُشار إليها عبر
credentials(). تحتاج صورة الوكيل (agent image) أيضًا إلى تثبيتcurlوjqوbc؛ تتضمنها مسبقًا أدوات التشغيلubuntu-latestالمستضافة على GitHub وAzure، بينما لا تتضمنها صورةalpineفي GitLab (ومن هنا تأتي خطوةapk add).
تحتاج خطوة ماسح المستودعات إلى ربط حساب GitHub/Bitbucket/Azure الخاص بك مسبقًا في إعدادات Scanverra — فهي تفحص باستخدام الرمز (token) المخزَّن هناك، وليس رمزًا يُرسَل مع كل طلب.
ماسح المستودعات فقط هو من يُعيد حقل qualityGate الجاهز. أما بالنسبة للأدوات الثلاث الأخرى، فحدّد حدودك الخاصة مسبقًا وحافظ على ثباتها عبر جميع البيئات (على سبيل المثال، لا تقارن نتيجة أمان عنوان URL خاص ببيئة تجريبية بحد ضُبط لبيئة الإنتاج).