From 9957b213d6997a6bc1a05e5b2b4dec2a4503c1b7 Mon Sep 17 00:00:00 2001 From: Erick Avila Date: Mon, 23 Feb 2026 22:11:50 -0600 Subject: [PATCH] Add CI quality pipeline with GitHub Actions and SonarCloud Set up 3-job workflow: unit tests with coverage, E2E tests with PostgreSQL service, and SonarCloud analysis. Configure sonar-project properties for org esaban17 and add test:ci script for CI coverage. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ci-quality.yml | 79 ++++++++++++++++++++++++++++++++ .gitignore | 3 +- package.json | 3 +- sonar-project.properties | 37 +++++++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/ci-quality.yml create mode 100644 sonar-project.properties diff --git a/.github/workflows/ci-quality.yml b/.github/workflows/ci-quality.yml new file mode 100644 index 000000000..e3bdd89bc --- /dev/null +++ b/.github/workflows/ci-quality.yml @@ -0,0 +1,79 @@ +name: CI Quality Pipeline + +on: + pull_request: + branches: [master] + push: + branches: [master] + +jobs: + unit-tests: + name: Unit Tests & Coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'npm' + - run: npm ci + - name: Run unit tests with coverage + run: npm run test:ci + env: + NODE_OPTIONS: --experimental-vm-modules + - uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage/lcov.info + retention-days: 1 + + e2e-tests: + name: E2E Tests + runs-on: ubuntu-latest + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: vulnerablenode + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U postgres" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'npm' + - run: npm ci + - name: Run E2E tests + run: npm run test:e2e + env: + NODE_OPTIONS: --experimental-vm-modules + DATABASE_URL: postgres://postgres:postgres@localhost:5432/vulnerablenode + SESSION_SECRET: ci-test-secret-key + + sonarcloud: + name: SonarCloud Analysis + runs-on: ubuntu-latest + needs: [unit-tests] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/download-artifact@v4 + with: + name: coverage-report + path: coverage/ + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@v3 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index f6d6e43bd..17de1a660 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,6 @@ jspm_packages .npm .node_repl_history -# Claude / MCP / GitHub config +# Claude / MCP config .claude/ -.github/ .playwright-mcp/ diff --git a/package.json b/package.json index e77a1c655..328e336de 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "test:unit": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=tests/unit", "test:integration": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=tests/integration", - "test:e2e": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=tests/e2e" + "test:e2e": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=tests/e2e", + "test:ci": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=tests/unit --coverage --coverageReporters=lcov --coverageReporters=text-summary --forceExit" }, "dependencies": { "cookie-parser": "^1.4.7", diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 000000000..2a6740f0f --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,37 @@ +sonar.projectKey=esaban17_vulnerable-node +sonar.organization=esaban17 +sonar.projectName=vulnerable-node-rehabilitated + +sonar.sources=model,routes,src +sonar.tests=tests +sonar.sourceEncoding=UTF-8 +sonar.javascript.file.suffixes=.js + +sonar.javascript.lcov.reportPaths=coverage/lcov.info + +sonar.exclusions=\ + node_modules/**,\ + coverage/**,\ + public/**,\ + views/**,\ + services/**,\ + docs/**,\ + logs/**,\ + dist/**,\ + **/*.min.js,\ + **/*.test.js,\ + **/*.spec.js,\ + dummy.js,\ + bin/** + +sonar.coverage.exclusions=\ + tests/**,\ + dummy.js,\ + config.js,\ + bin/**,\ + model/init_db.js,\ + model/db.js + +sonar.cpd.exclusions=\ + tests/**,\ + public/**