diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml index 3b54c2937..e7077b1b1 100644 --- a/.github/codeql/codeql-config.yml +++ b/.github/codeql/codeql-config.yml @@ -1,8 +1,6 @@ name: 'Pixelated Empathy Security Analysis' - # Keep default queries enabled disable-default-queries: false - # Define query filters to focus on security and quality query-filters: - include: @@ -11,13 +9,11 @@ query-filters: - path-problem - exclude: tags contain: experimental - # Specify which paths to analyze paths: - src - ai - scripts - # Exclude generated code, dependencies, and test files paths-ignore: - '**/node_modules' @@ -41,7 +37,6 @@ paths-ignore: - '**/*.pyc' - '**/playwright-report' - '**/test-results' - # Include custom queries for HIPAA/FHIR/EHR security queries: - name: FHIR Security Checks diff --git a/.github/codeql/custom-queries/qlpack.yml b/.github/codeql/custom-queries/qlpack.yml index a616097e1..55739dc65 100644 --- a/.github/codeql/custom-queries/qlpack.yml +++ b/.github/codeql/custom-queries/qlpack.yml @@ -6,11 +6,8 @@ groups: - fhir - ehr - healthcare - dependencies: codeql/javascript-all: '*' codeql/javascript-queries: '*' - # Extend the JavaScript query pack extractor: javascript - diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 765ef1501..57b7a74ce 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,5 @@ # Dependabot configuration for security updates and version management # Documentation: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - version: 2 updates: # GitHub Actions - Check for security updates weekly @@ -22,7 +21,6 @@ updates: labels: - 'dependencies' - 'github-actions' - # NPM/Node.js - Aggressive security update schedule - package-ecosystem: 'npm' directory: '/' @@ -63,7 +61,6 @@ updates: major-updates: update-types: - 'major' - # Python - Daily security updates # Uses requirements.txt generated by uv (uv pip compile) - package-ecosystem: 'pip' diff --git a/.github/workflows/ai-validation.yml b/.github/workflows/ai-validation.yml index e98423e1e..56785297b 100644 --- a/.github/workflows/ai-validation.yml +++ b/.github/workflows/ai-validation.yml @@ -1,5 +1,4 @@ name: AI Model Validation Pipeline - permissions: contents: read actions: read @@ -7,7 +6,6 @@ permissions: pull-requests: read security-events: write issues: write - on: schedule: - cron: 0 0 * * * @@ -17,23 +15,19 @@ on: description: "Environment name (staging, production, etc)" required: false default: "staging" - jobs: validate-ai-models: name: AI Model Validation runs-on: ubuntu-latest env: ENV_NAME: ${{ inputs.ENV_NAME || 'staging' }} - steps: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Node.js uses: actions/setup-node@v4.4.0 with: node-version: 24.14.0 - - name: Generate validation token id: generate-token run: | @@ -50,22 +44,18 @@ jobs: echo "token=${VALIDATION_TOKEN}" >> $GITHUB_OUTPUT env: AI_VALIDATION_SECRET: ${{ secrets.AI_VALIDATION_SECRET }} - - name: Enable Corepack run: corepack enable - - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4 with: version: 10.32.1 run_install: false - - name: Get pnpm store directory id: pnpm-cache shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache uses: actions/cache@v4.2.3 with: @@ -73,53 +63,45 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies run: pnpm install --no-frozen-lockfile - - name: Install system tools (jq, bc) run: | sudo apt-get update # Ensure TLS root certs and openssl are present for curl/openssl diagnostics sudo apt-get install -y jq bc ca-certificates openssl sudo update-ca-certificates || true - - name: Set environment variables run: | # Default environment if not provided if [[ -z "${ENV_NAME}" ]]; then echo "ENV_NAME=staging" >> $GITHUB_ENV fi - APP_URL="${{ secrets.APP_URL }}" if [[ -z "${APP_URL}" ]]; then APP_URL="https://pixelatedempathy.com" echo "::notice::APP_URL not configured; defaulting to ${APP_URL}" fi echo "APP_URL=${APP_URL}" >> $GITHUB_ENV - - name: Run model validation id: validation run: | # Generate webhook validation token WEBHOOK_TOKEN=$(openssl rand -base64 32) echo "WEBHOOK_TOKEN=${WEBHOOK_TOKEN}" >> $GITHUB_ENV - # Trigger validation via webhook echo "Triggering validation via webhook..." # Disable 'exit on error' just for this call to capture curl failures without aborting the step set +e - STATUS_CODE=$( - curl --http1.1 -4 --tlsv1.2 --retry 3 --retry-all-errors --max-time 30 -sS \ - -o response.json -w "%{http_code}" \ - -X POST "${APP_URL}/api/ai/validation/webhook" \ - -H "Content-Type: application/json" \ - -H "x-github-event: workflow_dispatch" \ - -H "x-hub-signature-256: ${WEBHOOK_TOKEN}" \ - -d '{"action":"validate","environment":"'"${ENV_NAME}"'"}') + STATUS_CODE=$( curl --http1.1 -4 --tlsv1.2 --retry 3 --retry-all-errors --max-time 30 -sS \ + -o response.json -w "%{http_code}" \ + -X POST "${APP_URL}/api/ai/validation/webhook" \ + -H "Content-Type: application/json" \ + -H "x-github-event: workflow_dispatch" \ + -H "x-hub-signature-256: ${WEBHOOK_TOKEN}" \ + -d '{"action":"validate","environment":"'"${ENV_NAME}"'"}') CURL_EXIT=$? set -e - if [[ ${CURL_EXIT} -ne 0 ]]; then echo "success=false" >> "$GITHUB_OUTPUT" echo "Validation trigger request failed (curl exit ${CURL_EXIT})." @@ -150,20 +132,17 @@ jobs: cat response.json # Continue the workflow anyway, don't fail the build fi - - name: Wait for validation to complete if: steps.validation.outputs.success == 'true' run: | echo "Waiting for validation to complete (120 seconds)..." sleep 120 - - name: Fetch validation results if: steps.validation.outputs.success == 'true' id: results run: | # Use the generated token from previous step VALIDATION_TOKEN="${{ steps.generate-token.outputs.token }}" - # Get validation history and results set +e STATUS_CODE=$(curl --http1.1 -4 --tlsv1.2 --retry 3 --retry-all-errors --max-time 30 -sS -o validation_history.json -w "%{http_code}" \ @@ -171,7 +150,6 @@ jobs: -H "Authorization: Bearer ${VALIDATION_TOKEN}") CURL_EXIT=$? set -e - if [[ ${CURL_EXIT} -ne 0 ]]; then echo "success=false" >> "$GITHUB_OUTPUT" echo "Failed to fetch validation results (curl exit ${CURL_EXIT})" @@ -189,12 +167,10 @@ jobs: RUN_ID=$(jq -r '.history[0].runId' validation_history.json) RUN_SUCCESS=$(jq -r '.history[0].success' validation_history.json) echo "Last validation run: ${RUN_ID}, Success: ${RUN_SUCCESS}, Pass rate: ${PASS_RATE}%" - # Store metrics for the summary echo "PASS_RATE=${PASS_RATE}" >> $GITHUB_ENV echo "RUN_ID=${RUN_ID}" >> $GITHUB_ENV echo "RUN_SUCCESS=${RUN_SUCCESS}" >> $GITHUB_ENV - # Check if pass rate is below threshold for alerting if (( $(echo "${PASS_RATE} < 85" | bc -l) )); then echo "needs_alert=true" >> "$GITHUB_OUTPUT" @@ -206,12 +182,10 @@ jobs: echo "needs_alert=false" >> "$GITHUB_OUTPUT" echo "Failed to fetch validation results (HTTP ${STATUS_CODE})" fi - - name: Create summary run: | echo "# AI Model Validation Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY - if [[ "${{ steps.validation.outputs.success }}" == "true" && "${{ steps.results.outputs.success }}" == "true" ]]; then echo "✅ **Validation completed successfully**" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY @@ -226,30 +200,22 @@ jobs: echo "Please check the validation pipeline manually to verify model accuracy." >> $GITHUB_STEP_SUMMARY echo "[AI Validation Dashboard](${APP_URL}/admin/ai/validation-pipeline)" >> $GITHUB_STEP_SUMMARY fi - - name: Send notification on validation issues if: ${{ steps.results.outputs.needs_alert == 'true' }} uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { repo, owner } = context.repo; - github.rest.issues.create({ - owner, - repo, - title: `⚠️ AI Model Validation Alert: ${process.env.PASS_RATE}% success rate`, - body: ` - # AI Model Validation Alert - - A recent validation run found potential issues with AI model accuracy. - - - **Environment:** ${process.env.ENV_NAME} - - **Run ID:** ${process.env.RUN_ID} - - **Success Rate:** ${process.env.PASS_RATE}% - - **Threshold:** 85% - - Please investigate this issue by checking the [AI Validation Dashboard](${process.env.APP_URL}/admin/ai/validation-pipeline). - - This issue was automatically created by the AI validation pipeline. - ` - }); + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { repo, owner } = context.repo; + github.rest.issues.create({ + owner, + repo, + title: `⚠️ AI Model Validation Alert: ${process.env.PASS_RATE}% success rate`, + body: ` # AI Model Validation Alert +A recent validation run found potential issues with AI model accuracy. +- **Environment:** ${process.env.ENV_NAME} +- **Run ID:** ${process.env.RUN_ID} +- **Success Rate:** ${process.env.PASS_RATE}% +- **Threshold:** 85% +Please investigate this issue by checking the [AI Validation Dashboard](${process.env.APP_URL}/admin/ai/validation-pipeline). +This issue was automatically created by the AI validation pipeline. +`); \ No newline at end of file diff --git a/.github/workflows/bias-detection-ci.yml b/.github/workflows/bias-detection-ci.yml index 825bbf166..1624af17f 100644 --- a/.github/workflows/bias-detection-ci.yml +++ b/.github/workflows/bias-detection-ci.yml @@ -10,7 +10,9 @@ permissions: on: push: - branches: [main, staging] + branches: + - main + - staging paths: - src/lib/ai/bias-detection/** - src/components/admin/bias-detection/** @@ -18,7 +20,9 @@ on: - tests/**/*bias-detection* - .github/workflows/bias-detection-ci.yml pull_request: - branches: [main, staging] + branches: + - main + - staging paths: - src/lib/ai/bias-detection/** - src/components/admin/bias-detection/** @@ -38,7 +42,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4.2.2 - - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@0.30.0 with: @@ -46,38 +49,27 @@ jobs: scan-ref: . format: sarif output: trivy-results.sarif - - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v3.29.1 - if: always() with: sarif_file: trivy-results.sarif - - name: Initialize CodeQL uses: github/codeql-action/init@v3.29.1 with: languages: javascript,typescript - - name: Setup Node.js for CodeQL uses: actions/setup-node@v4.4.0 with: node-version: ${{ env.NODE_VERSION }} - - name: Enable Corepack for CodeQL run: corepack enable - - name: Setup pnpm for CodeQL - uses: pnpm/action-setup@v4.1.0 - with: - version: ${{ env.PNPM_VERSION }} - run_install: false - + uses: pnpm/action-setup@v4 - name: Get pnpm store directory for CodeQL id: pnpm-cache-codeql shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache for CodeQL uses: actions/cache@v4.2.3 with: @@ -85,44 +77,32 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies for CodeQL run: pnpm install --no-frozen-lockfile - - name: Build for CodeQL run: pnpm build - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3.29.1 - # Code quality and linting code-quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4.2.2 - - name: Setup Node.js uses: actions/setup-node@v4.4.0 with: node-version: ${{ env.NODE_VERSION }} - - name: Enable Corepack run: corepack enable - - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 - with: - version: ${{ env.PNPM_VERSION }} - run_install: false - + uses: pnpm/action-setup@v4 - name: Get pnpm store directory id: pnpm-cache shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache uses: actions/cache@v4.2.3 with: @@ -130,23 +110,21 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies run: pnpm install --no-frozen-lockfile - - name: Run ESLint run: pnpm lint - - name: Run TypeScript compiler run: pnpm typecheck - - name: Check formatting run: pnpm format:check typescript-tests: name: TypeScript Tests runs-on: ubuntu-latest - needs: [security-scan, code-quality] + needs: + - security-scan + - code-quality if: ${{ needs.security-scan.result == 'success' && needs.code-quality.result == 'success' }} services: postgres: @@ -156,39 +134,37 @@ jobs: POSTGRES_DB: test_db POSTGRES_HOST_AUTH_METHOD: trust options: >- - --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 ports: - 5432:5432 redis: image: redis:7 options: >- - --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 ports: - 6379:6379 steps: - name: Checkout code uses: actions/checkout@v4.2.2 - - name: Setup Node.js uses: actions/setup-node@v4.4.0 with: node-version: ${{ env.NODE_VERSION }} - - name: Enable Corepack run: corepack enable - - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 - with: - version: ${{ env.PNPM_VERSION }} - run_install: false - + uses: pnpm/action-setup@v4 - name: Get pnpm store directory id: pnpm-cache shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache uses: actions/cache@v4.2.3 with: @@ -196,10 +172,8 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies run: pnpm install --no-frozen-lockfile - - name: Setup test environment run: | if [ -f .env.example ]; then @@ -211,17 +185,14 @@ jobs: echo "REDIS_URL=redis://localhost:6379" >> .env.test env: POSTGRES_USER: postgres - - name: Run unit tests run: pnpm test:unit env: NODE_ENV: test - - name: Run integration tests run: pnpm test:integration env: NODE_ENV: test - - name: Upload coverage reports uses: codecov/codecov-action@v5 with: @@ -232,17 +203,15 @@ jobs: python-tests: name: Python ML Tests runs-on: ubuntu-latest - needs: [security-scan] - + needs: + - security-scan steps: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Python ${{ env.PYTHON_VERSION }} uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Ensure `uv` shim is available run: | if ! command -v uv >/dev/null 2>&1; then @@ -252,13 +221,11 @@ jobs: else echo "uv already installed" fi - - name: Prepare uv venv id: prepare-uv uses: ./.github/actions/prepare-uv-venv with: service-dir: src/lib/ai/bias-detection/python-service - - name: Cache pip dependencies uses: actions/cache@v4.2.3 with: @@ -266,7 +233,6 @@ jobs: key: ${{ runner.os }}-pip-${{ env.PYTHON_VERSION }}-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip-${{ env.PYTHON_VERSION }}- - - name: Install Python dependencies run: | if [ ! -d "src/lib/ai/bias-detection/python-service" ]; then @@ -274,20 +240,16 @@ jobs: ls -la src/lib/ai/bias-detection/ exit 1 fi - # Prepare uv venv using the composite action, then use its output # NOTE: composite actions run as steps, so this shell block only performs installs after the action has run. cd src/lib/ai/bias-detection/python-service - # Use the use-system output if set USE_SYSTEM="${{ steps.prepare-uv.outputs.use-system }}" - uv pip install ${USE_SYSTEM} --upgrade pip setuptools wheel # Constrain numpy/pandas to compatible binaries to avoid ABI mismatch uv pip install ${USE_SYSTEM} --only-binary=:all: -c constraints-ci.txt numpy pandas uv pip install ${USE_SYSTEM} -r requirements.txt -c constraints-ci.txt uv pip install ${USE_SYSTEM} pytest pytest-cov pytest-asyncio httpx - - name: Run Python linting run: | cd src/lib/ai/bias-detection/python-service @@ -298,7 +260,6 @@ jobs: uv isort --check-only --diff . # Run flake8 for code quality uv flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - - name: Run Python tests run: | cd src/lib/ai/bias-detection/python-service @@ -307,7 +268,6 @@ jobs: ENV: ci FLASK_SECRET_KEY: test-flask-secret JWT_SECRET_KEY: test-jwt-secret - - name: Upload Python coverage uses: codecov/codecov-action@v5 with: @@ -318,8 +278,9 @@ jobs: e2e-tests: name: E2E Tests runs-on: ubuntu-latest - needs: [typescript-tests, python-tests] - + needs: + - typescript-tests + - python-tests services: postgres: image: postgres:15 @@ -328,33 +289,28 @@ jobs: POSTGRES_DB: test_db POSTGRES_HOST_AUTH_METHOD: trust options: >- - --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 ports: - 5432:5432 steps: - name: Checkout code uses: actions/checkout@v4.2.2 - - name: Setup Node.js uses: actions/setup-node@v4.4.0 with: node-version: ${{ env.NODE_VERSION }} - - name: Enable Corepack run: corepack enable - - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 - with: - version: ${{ env.PNPM_VERSION }} - run_install: false - + uses: pnpm/action-setup@v4 - name: Get pnpm store directory id: pnpm-cache shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache uses: actions/cache@v4.2.3 with: @@ -362,15 +318,12 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies run: pnpm install --no-frozen-lockfile - - name: Setup Python for ML service uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - name: Ensure `uv` shim is available run: | if ! command -v uv >/dev/null 2>&1; then @@ -380,24 +333,19 @@ jobs: else echo "uv already installed" fi - - name: Prepare uv venv id: prepare-uv uses: ./.github/actions/prepare-uv-venv with: service-dir: src/lib/ai/bias-detection/python-service - - name: Install Python ML dependencies run: | cd src/lib/ai/bias-detection/python-service - USE_SYSTEM="${{ steps.prepare-uv.outputs.use-system }}" - uv pip install ${USE_SYSTEM} --upgrade pip setuptools wheel # Constrain numpy/pandas to compatible binaries to avoid ABI mismatch uv pip install ${USE_SYSTEM} --only-binary=:all: -c constraints-ci.txt numpy pandas uv pip install ${USE_SYSTEM} -r requirements.txt -c constraints-ci.txt - - name: Setup test database run: | if [ -f .env.example ]; then @@ -408,13 +356,10 @@ jobs: echo "DATABASE_URL=postgresql://${POSTGRES_USER}@localhost:5432/test_db" >> .env.test env: POSTGRES_USER: postgres - - name: Ensure Playwright report directory exists run: mkdir -p playwright-report-browser-compat - - name: Install Playwright browsers run: pnpm exec playwright install --with-deps - - name: Start Python ML service run: | cd src/lib/ai/bias-detection/python-service @@ -434,28 +379,22 @@ jobs: ENV: ci FLASK_SECRET_KEY: test-flask-secret JWT_SECRET_KEY: test-jwt-secret - - name: Build application run: pnpm build - - name: Start application run: | pnpm start & sleep 30 env: NODE_ENV: test - - name: Run Playwright tests run: pnpm test:e2e --project=chromium env: NODE_ENV: test - - name: Upload E2E test results uses: actions/upload-artifact@v4 - if: failure() with: name: e2e-test-results path: | test-results/ - playwright-report/ - + playwright-report/ \ No newline at end of file diff --git a/.github/workflows/browser-tests.yml b/.github/workflows/browser-tests.yml index 50d7f9a66..43d1ca76d 100644 --- a/.github/workflows/browser-tests.yml +++ b/.github/workflows/browser-tests.yml @@ -1,58 +1,42 @@ name: Browser Compatibility Tests - permissions: contents: read actions: write - on: push: branches: [main, staging] pull_request: branches: [main, staging] workflow_dispatch: - env: NODE_VERSION: 24.14.0 PNPM_VERSION: 10.32.1 NODE_ENV: test DISABLE_AUTH: "true" - jobs: browser-tests: name: Run Browser Tests runs-on: ubuntu-latest timeout-minutes: 60 - steps: - uses: actions/checkout@v5 - - name: Setup Node.js uses: actions/setup-node@v4 - with: node-version: ${{ env.NODE_VERSION }} - - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 - with: - version: 10.32.1 - + uses: pnpm/action-setup@v4 - name: Setup pnpm cache uses: actions/cache@v4 - with: path: ~/.pnpm-store key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - name: Install dependencies run: pnpm install --no-frozen-lockfile - - name: Install Playwright browsers run: pnpm exec playwright install --with-deps - - name: Build project run: pnpm run build - - name: Run browser tests run: | # Set test environment variables @@ -60,16 +44,13 @@ jobs: export DISABLE_AUTH=true export DISABLE_WEB_FONTS=true export SKIP_MSW=true - # Run tests with built-in web server, only essential tests pnpm exec playwright test tests/browser/auth.spec.ts tests/browser/cross-browser-compatibility.spec.ts tests/browser/mobile-compatibility.spec.ts --config=playwright.config.ci.ts --max-failures=10 --workers=1 env: CI: true - - name: Upload test results if: always() uses: actions/upload-artifact@v4 - with: name: browser-test-results-${{ github.run_id }} path: | playwright-report/ @@ -77,23 +58,18 @@ jobs: retention-days: 30 if-no-files-found: warn compression-level: 6 - generate-report: name: Generate Test Report runs-on: ubuntu-latest needs: [browser-tests] if: always() - steps: - uses: actions/checkout@v5 - - name: Download all test artifacts uses: actions/download-artifact@v5 - with: path: all-test-results pattern: "*-test-results-*" merge-multiple: true - - name: Generate comprehensive HTML report id: generate_report run: | @@ -123,17 +99,14 @@ jobs:
Workflow Run: ${{ github.run_id }}
EOF - # Count issues and generate summary ISSUE_COUNT=0 TOTAL_TESTS=0 PASSED_TESTS=0 - # Process test results if available if find all-test-results -name "*.json" -type f | head -1 > /dev/null 2>&1; then echo 'Total Tests: $TOTAL_TESTS
" >> report.html echo "Passed: $PASSED_TESTS
" >> report.html echo "Failed: $ISSUE_COUNT
" >> report.html @@ -161,7 +132,6 @@ jobs: echo 'No test result files were found in the artifacts.
' >> report.html echo 'No compatibility issues detected. Great work!
' >> report.html echo '