كيف أقوم بدمج تحليل الكود الثابت في خطوط أنابيب CI/CD؟

كيف أقوم بدمج تحليل الكود الثابت في خطوط أنابيب CI/CD؟

في كوم 11 يونيو، 2026

كل سطر برمجي يصل إلى مرحلة الإنتاج كُتب بواسطة شخصٍ اعتقد بصحته. تحليل الكود الثابت هو نظام آلي يتحقق من صحة هذا الاعتقاد، ليس بتشغيل الكود، بل بقراءة بنيته، وتتبع تدفقات بياناته، ومقارنته بأنماط معروفة من الثغرات الأمنية والأخطاء ومخالفات الجودة. السؤال ليس ما إذا كان ينبغي تشغيله، بل أين في مسار التطوير يُشغّل، وما الأداة المناسبة، وما هي المعايير التي يجب تطبيقها، وكيفية ضمان سرعة التغذية الراجعة بما يكفي ليُبادر المطورون إلى العمل بها بدلًا من تجاهلها.

يكمن الفرق بين التحليل الثابت كإجراء شكلي والتحليل الثابت كبوابة جودة حقيقية في الإعدادات. فالماسح الضوئي الذي يعمل وينتج تقريرًا لا يقرأه أحد ليس إلا استعراضًا. أما بوابة الجودة التي تُفشل عملية البناء عند ظهور ثغرات أمنية حرجة جديدة، وتمنع الدمج عند انخفاض التغطية عن الحد الأدنى، وتُظهر ملاحظات دقيقة على الملفات والأسطر في واجهة مراجعة طلبات السحب، فهي نظام يُغير سلوكه لحظة اتخاذ القرارات.

أين في مسار المعالجة يتم إجراء التحليل الثابت

ينبغي إجراء التحليل الثابت في نقاط متعددة، بحيث تخدم كل نقطة غرضًا مختلفًا. إن إجراؤه في نقطة واحدة فقط يُنشئ ثغرات، بينما يؤدي إجراؤه في كل مكان بالتساوي إلى بطء في مسارات العمل، مما يُجبر المطورين على تجاوزها.

مرحلة خط الأنابيبما الذي يجب تشغيله؟ميزانية زمن الوصولالهدف
الالتزام المسبق (محلي)الوبر السريع فقط (ESLint وClippy وrustfmt)أقل من 5 ثانيةأوقف المشاكل الواضحة قبل أن تصل إلى المستودع
طلب سحب / طلب دمجفحص كامل للثغرات الأمنية + تحليل أمان النظام الثابت + فحص SonarQube التزايديأقل من دقيقتينعمليات اندماج الكتل بشأن قضايا حاسمة جديدة
بناء الفرع الرئيسيتحليل كامل يشمل التغطية، والتكرار، والديون التقنيةأقل من دقيقتينتتبع اتجاهات الجودة، وقم بتحديث لوحات المعلومات.
مُجدولة كل ليلةعمليات مسح معمقة، تدقيق التبعيات، فحوصات الامتثاللا ميزانيةاكتشاف مشكلات بطء البناء ومخاطر سلسلة التوريد

تُعدّ مرحلة طلب السحب هي المرحلة الأهم . أما التحليل الذي يُجرى عند دفع التغييرات إلى الفرع الرئيسي، فيتم بعد اتخاذ قرار الدمج. بينما يُجرى التحليل الذي يُجرى على طلب السحب، والذي يُضيف تعليقات مضمنة مع سياق دقيق للملف والسطر، عندما يكون المطور لا يزال يعمل على الكود، وتكون تكلفة الإصلاح في أدنى مستوياتها.

إجراء تحليلات مكثفة قبل كل عملية حفظ يُفسد تجربة المطورين. أدوات التحليل السريع التي تُنجز عملها في أقل من 5 ثوانٍ مكانها في بيئة التطوير المتكاملة. أما باقي الأدوات فمكانها في بيئة التكامل المستمر.

إجراءات GitHub: تكوين عمل كامل

تُعدّ GitHub Actions منصة التكامل المستمر الأكثر استخدامًا. يُشغّل سير العمل التالي مسارًا متعدد الطبقات لضمان الجودة: فحص التنسيق، والتدقيق اللغوي، والبناء، وفحص أمان SAST، وبوابة جودة SonarCloud.

يامل

# .github/workflows/quality.yml
name: Code Quality

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  # ── Layer 1: Fast checks (under 60 seconds) ─────────────────────────────
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - run: npm ci

      - name: Lint (fail on warnings)
        run: npx eslint src/ --max-warnings 0

      - name: Format check
        run: npx prettier --check src/

      - name: TypeScript type check
        run: npx tsc --noEmit

  # ── Layer 2: Security SAST (Semgrep) ────────────────────────────────────
  sast:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4

      - name: Semgrep SAST scan
        uses: semgrep/semgrep-action@v1
        with:
          config: p/javascript p/nodejs p/owasp-top-ten
        env:
          SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

  # ── Layer 3: SonarCloud quality gate ────────────────────────────────────
  sonar:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # full history required for blame data

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - run: npm ci

      - name: Run tests with coverage
        run: npm test -- --coverage --coverageReporters=lcov

      - name: SonarCloud scan
        uses: SonarSource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

HAS

# sonar-project.properties
sonar.projectKey=my-org_my-project
sonar.organization=my-org
sonar.sources=src
sonar.tests=tests
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.coverage.exclusions=**/*.test.js,**/*.spec.js

قرارات التكوين الرئيسية في سير العمل هذا:

  • --max-warnings 0 في ESLint: أي تحذير يُعتبر فشلاً في عملية البناء. الفرق التي تسمح بالتحذيرات تتراكم لديها حتى لا يقرأها أحد.
  • fetch-depth: 0 عند إتمام عملية الشراء: يحتاج SonarCloud إلى سجل git كامل لتحديد المسؤولية عن المشكلات التي تم إدخالها وحساب مقاييس التعليمات البرمجية الجديدة بشكل صحيح.
  • يتم تشغيل Semgrep بعد lint بالتوازي مع Sonar: فحص الأمان والجودة هما أمران مستقلان؛ تشغيلهما بالتوازي يقلل من إجمالي وقت خط الأنابيب.
  • الاختبارات التي تم إجراؤها باستخدام lcov مخرجات التغطية: يقرأ SonarCloud هذا لعرض التغطية لكل ملف وفرض عتبات التغطية في بوابة الجودة.

GitLab CI/CD: خط أنابيب عالي الجودة مع بوابات جودة

يامل

# .gitlab-ci.yml
stages:
  - lint
  - test
  - analyze
  - security

variables:
  SONAR_HOST_URL: "https://sonarcloud.io"

lint:
  stage: lint
  image: node:20
  cache:
    paths: [node_modules/]
  script:
    - npm ci
    - npx eslint src/ --max-warnings 0
    - npx prettier --check src/
    - npx tsc --noEmit
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == "main"

test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm test -- --coverage --coverageReporters=lcov cobertura
  coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

sonarcloud:
  stage: analyze
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
  cache:
    key: "${CI_JOB_NAME}"
    paths: [.sonar/cache]
  script:
    - sonar-scanner
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == "main"

semgrep:
  stage: security
  image: returntocorp/semgrep:latest
  script:
    - semgrep scan --config=p/owasp-top-ten --config=p/javascript
      --sarif --output=semgrep.sarif src/
  artifacts:
    reports:
      sast: semgrep.sarif
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == "main"

استخدم artifacts: reports: sast: تقوم هذه الوحدة بدمج مخرجات SARIF من Semgrep مباشرة في لوحة معلومات الأمان الخاصة بـ GitLab، حيث تظهر النتائج في تقرير أمان طلب الدمج بدلاً من مخرجات سجل CI الخام.

جينكينز: خط أنابيب تصريحي مع سونار كيوب

رائع

// Jenkinsfile
pipeline {
    agent any

    tools {
        nodejs "NodeJS-20"
    }

    environment {
        SONAR_TOKEN = credentials('sonar-token')
    }

    stages {
        stage('Lint') {
            steps {
                sh 'npm ci'
                sh 'npx eslint src/ --max-warnings 0'
                sh 'npx tsc --noEmit'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test -- --coverage --coverageReporters=lcov'
            }
            post {
                always {
                    publishHTML([
                        allowMissing: false,
                        reportDir: 'coverage/lcov-report',
                        reportFiles: 'index.html',
                        reportName: 'Coverage Report'
                    ])
                }
            }
        }

        stage('SonarQube Analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh '''
                        npx sonar-scanner \
                          -Dsonar.projectKey=my-project \
                          -Dsonar.sources=src \
                          -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
                    '''
                }
            }
        }

        stage('Quality Gate') {
            steps {
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
    }

    post {
        failure {
            emailext(
                subject: "Quality Gate FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: "Build failed quality gate. Review: ${env.BUILD_URL}",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }
    }
}

waitForQualityGate abortPipeline: true هذا هو السطر الحرج. فهو يستعلم من SonarQube حتى يكتمل التحليل، ويفشل البناء إذا لم يتم استيفاء معيار الجودة. بدونه، يكتمل خط الأنابيب بينما لا يزال التحليل قيد التشغيل، ولا يتم تطبيق نتيجة معيار الجودة.

تهيئة بوابات الجودة التي تحترمها الفرق بالفعل

يتم تعطيل بوابة الجودة التي تفشل في كل عملية دمج بسبب تحديد عتبات صارمة للغاية. أما البوابة التي لا تفشل أبدًا بسبب تحديد عتبات متساهلة للغاية، فلا فائدة منها. الهدف هو بوابة مُعايرة وفقًا لمستوى المخاطر الفعلي للمشروع.

التكوين الموصى به لبدء تشغيل بوابة الجودة الجديدة في برنامج SonarQube:

متريالحالةعتبة
أخطاء جديدةاعظم من0
ثغرات أمنية جديدةاعظم من0
مراجعة النقاط الأمنية الجديدةأقل من100%
تغطية الكود الجديدأقل من80%
أسطر مكررة جديدةاعظم من3%
روائح جديدة في الكوداعظم من10

طبّق هذه المعايير على الكود الجديد فقط (فترة "الكود الجديد" في SonarQube). لا تُطبّقها على قاعدة الكود الكاملة في مشروع قديم، لأن فشل كل عملية بناء بسبب الديون التقنية المتراكمة على مدى خمس سنوات يدفع الفرق إلى تعطيل هذه المعايير تمامًا. يتيح لك نهج الكود الجديد وقف التراكمات التقنية مع معالجة الديون الموجودة بشكل منفصل.

قم بتعديل عتبات التقييم تدريجيًا. ابدأ بعتبات متحفظة، ثم شددها كل ثلاثة أشهر مع إنجاز الفريق للمهام المتراكمة. يمكن رفع نسبة تغطية بوابة تم اجتيازها اليوم إلى 80% بمجرد أن يصبح المستوى الأساسي أعلى من ذلك بشكل مريح. يُعدّ التضييق التدريجي أكثر استدامة من السعي المباشر نحو الكمال.

معالجة أداء التحليل الثابت في قواعد البيانات الكبيرة

السبب الأكثر شيوعًا لتعطيل فرق العمل للتحليل الثابت أو تجاوزه في التكامل المستمر هو أنه يُبطئ مسارات العمل بشكل كبير. ففحص الجودة الذي يستغرق 15 دقيقة مع كل عملية دفع إلى فرع الميزة يُعيق سير عمل المطورين. هناك عدة استراتيجيات للحفاظ على سرعة التحليل:

التحليل التدريجي (للكود الجديد فقط). يدعم SonarQube ومعظم أدوات التحليل الثابت للمؤسسات تحليل الملفات المتغيرة فقط في طلب السحب بدلاً من قاعدة التعليمات البرمجية الكاملة. قم بالتكوين sonar.pullrequest.base, sonar.pullrequest.branchو sonar.pullrequest.key تتيح المعلمات إمكانية إجراء فحص تدريجي خاص بطلبات السحب. ويستمر إجراء التحليل الكامل عند دمج التغييرات في الفرع الرئيسي؛ ويستغرق فحص طلبات السحب أقل من دقيقتين على معظم قواعد البيانات.

التخزين المؤقت. يُعدّ تنزيل الأداة وتعريفات قواعدها الجزء الأكثر تكلفة في العديد من عمليات التحليل الثابت. لذا، يُنصح بتخزين ملف الماسح الضوئي، وقاعدة بيانات القواعد، وأي تبعيات مُحلّلة مؤقتًا بين عمليات التشغيل.

يامل

# GitHub Actions: cache SonarCloud scanner
- name: Cache SonarCloud packages
  uses: actions/cache@v4
  with:
    path: ~/.sonar/cache
    key: ${{ runner.os }}-sonar
    restore-keys: ${{ runner.os }}-sonar

التوازي. تُعدّ عمليات التدقيق اللغوي، وفحص الأمان، وتحليل بوابات الجودة أمورًا مستقلة. لذا، يُنصح بتشغيلها في مهام متوازية بدلًا من تشغيلها بالتسلسل. يُحدد إجمالي وقت خط الأنابيب بناءً على أبطأ مهمة، وليس مجموع أوقات جميع المهام.

تفعيل الأدوات بشكل انتقائي. ليس من الضروري تشغيل جميع الأدوات على كل فرع. يمكن إجراء فحص أمني كامل وفحوصات امتثال على طلبات السحب والفرع الرئيسي، بينما تُشغّل أدوات فحص الأخطاء السريعة فقط على فروع ما قبل الدمج. استخدم عوامل تصفية الفروع في إعدادات التكامل المستمر لتطبيق ملفات تعريف تحليل مختلفة.

التحليل الثابت في خطوط الأنابيب ذات الأولوية للأمن: تحليل البرمجيات الثابت وفحص التبعيات

تضيف خطوط الأنابيب التي تركز على الأمن طبقتين إضافيتين إلى جانب تحليل الجودة القياسي: اختبار أمان التطبيقات الثابت (SAST) لنقاط ضعف كود التطبيق، وفحص التبعيات بحثًا عن الثغرات الأمنية المعروفة (CVEs) في مكتبات الطرف الثالث.

تقوم أدوات تحليل أمان التطبيقات الثابتة (SAST ) (مثل Semgrep وCodeQL وSnyk Code وCheckmarx) بتحليل كيفية تدفق البيانات غير الموثوقة عبر كود التطبيق للوصول إلى العمليات الحساسة. وتكشف هذه الأدوات عن ثغرات حقن SQL، وهجمات XSS، وحقن الأوامر، وفك التسلسل غير الآمن، وبيانات الاعتماد المضمنة في الكود والتي لا تستطيع أدوات فحص الجودة القياسية اكتشافها.

يامل

# GitHub Actions: CodeQL analysis for deep vulnerability detection
- name: Initialize CodeQL
  uses: github/codeql-action/init@v3
  with:
    languages: javascript-typescript

- name: Perform CodeQL Analysis
  uses: github/codeql-action/analyze@v3
  with:
    category: "/language:javascript-typescript"

مسح التبعية الشيكات package.json, pom.xml, requirements.txtوملفات البيان المكافئة مقابل قواعد بيانات الثغرات الأمنية:

يامل

# Dependency audit in the pipeline
- name: Dependency audit
  run: |
    npm audit --audit-level=high
    # Fail if high or critical vulnerabilities are found

يُطبّق نموذج الأمان متعدد الطبقات فحصًا سريعًا للبرمجيات الثابتة (Semgrep) قائمًا على الأنماط على كل طلب سحب للحصول على ملاحظات فورية من المطورين، وفحصًا دلاليًا عميقًا للبرمجيات الثابتة (CodeQL) بشكل دوري لتغطية شاملة. ويتم فحص التبعيات في كل عملية بناء نظرًا لنشر ثغرات أمنية جديدة يوميًا.

أخطاء التكامل الشائعة وكيفية تجنبها

يُجرى التحليل فقط على الفرع الرئيسي. تكمن أهمية التحليل الثابت في رصد المشكلات قبل دمجها، وليس بعده. أما التحليل الذي يُجرى بعد الدمج فيُعدّ بمثابة تقرير، وليس بوابة.

ضبط بوابات الجودة بحيث تُصدر تحذيرات بدلاً من أن تُسبب فشلاً. التحذير الذي لا يُعيق سير العمل هو إشعار يتجاهله المطورون. البوابات التي لا تُسبب فشلاً لا تُرسخ ثقافة الجودة.

عدم استبعاد ملفات الاختبار من عتبات التغطية. يؤدي اختبار كود اختبار آخر إلى أرقام تغطية مبالغ فيها. لذا، استبعد مجلدات الاختبار من حسابات التغطية للحصول على قياسات دقيقة لتغطية كود الإنتاج.

تجاهل تراكم التحليلات على قواعد البيانات البرمجية القديمة. إن تشغيل SonarQube لأول مرة على قاعدة بيانات برمجية قديمة تضم مليون سطر وظهور 40,000 مشكلة أمرٌ مُحبط وغير مُجدٍ. استخدم نهج خط الأساس للبرمجيات الجديدة: حدد تاريخ بدء "البرمجيات الجديدة"، وطبّق معايير التقييم فقط على البرمجيات المكتوبة بعد ذلك التاريخ، وتعامل مع تراكم المشكلات الحالي كبرنامج منفصل لتقليل الديون التقنية.

عدم ربط النتائج بتعليقات طلب السحب. يتم تجاهل نتائج التحليل المنشورة في لوحة تحكم منفصلة يجب على المطورين زيارتها. أما نتائج التحليل المنشورة كتعليقات مضمنة في الأسطر المحددة التي تسببت في المشكلات، داخل واجهة مراجعة طلبات السحب، فيتم التعامل معها. sonar.pullrequest.* معلمات لتكامل GitHub أو GitLab أو Bitbucket بحيث تظهر النتائج في المكان الذي تتم فيه مراجعة التعليمات البرمجية.

كيفية SMART TS XL يتكامل مع خطوط أنابيب التكامل المستمر/التسليم المستمر

معظم أدوات التحليل الثابت في مسارات التكامل المستمر/التسليم المستمر (CI/CD) تتعامل مع لغة واحدة في كل مرة. فمثلاً، يتعامل ESLint مع JavaScript، بينما يتعامل SonarQube مع Java وPython وJavaScript وC#. لكن لا يتعامل أي منها مع COBOL أو JCL أو RPG، أو مع التبعيات بين اللغات التي تربط برنامج معالجة الدفعات على الحاسوب المركزي بخدمة Java المصغرة التي تستهلك مخرجاته، والتي بدورها تتصل بواجهة JavaScript الأمامية التي تعرضها.

SMART TS XL يتكامل مع مسارات التكامل المستمر/التسليم المستمر كطبقة تحليل ثابتة متعددة اللغات تغطي جميع اللغات في بيئة المؤسسة في آن واحد. عند تعديل خدمة جافا، SMART TS XLالصورة تحليل الأثر يتتبع مخطط التبعية لتحديد برامج COBOL ومخططات قواعد البيانات والخدمات التابعة المتأثرة بهذا التغيير، قبل نشره. عند تعديل ملف نسخ COBOL، يحدد النظام كل برنامج في مجموعة التطبيقات الكاملة التي تتضمن هذا الملف والتي تحتاج إلى التحقق.

إن هذا الوعي بالاعتماد المتبادل بين اللغات هو القدرة التي تجعل SMART TS XLيختلف تكامل CI/CD الخاص بـ SonarQube عن إضافة لغة برمجة أخرى إليه. فهو لا يقتصر على تحليل الكود في الملف المُعدَّل فحسب، بل يتعداه إلى فهم تأثير هذا التغيير على أجزاء أخرى من النظام، وهو ما يُعرف بالتحليل المعماري الذي يُحدد النطاق الحقيقي للتغيير قبل تنفيذه.

بالنسبة لفرق تطوير المؤسسات التي تعمل عبر أنظمة قديمة وحديثة، SMART TS XLالصورة تكامل DevOps تُدمج هذه الإمكانية التحليل الهيكلي في سير عمل مراجعة خط الأنابيب، مما يوفر رؤية معمارية لا تستطيع الأدوات الخاصة بلغات البرمجة المختلفة توفيرها. والنتيجة هي بوابات جودة تُطبّق المعايير ليس فقط ضمن حدود لغة برمجة معينة، بل على مستوى النظام بأكمله، مما يضمن عدم تسبب أي تغيير في أي مكون في حدوث أعطال غير متوقعة في المكونات التي تعتمد عليه.

التحليل الثابت كعنصر أساسي في مسار الإنتاج

الفرق التي تُتقن التحليل الثابت تتعامل معه بنفس طريقة تعاملها مع الاختبار: ليس كمرحلة عابرة، بل كممارسة مستمرة مُدمجة في كل عملية دمج. يُجرى التحليل على كل طلب سحب. تظهر نتائج بوابات الجودة بالتزامن مع مراجعة الكود. وتزداد معايير الجودة صرامةً مع تحسّن قاعدة الكود. وتُضاف فئات تحليل جديدة مع ازدياد نضج الفريق في مجالي الأمن والجودة.

تُعدّ قوالب تهيئة خط الأنابيب المذكورة في هذه المقالة نقاط انطلاق. ينبغي معايرة الأدوات والعتبات وشروط البوابات المحددة بما يتناسب مع مجموعة لغات المشروع، ومستوى المخاطر، ونضج الفريق. أما المبدأ الثابت فهو: التحليل الذي لا يُقيّد عمليات الدمج لا يُغيّر السلوك، والسلوك هو ما تسعى برامج جودة الكود إلى تغييره.