From fbd6b8933dd0d42a292731b4193df10369b870d1 Mon Sep 17 00:00:00 2001 From: SaelixCode Date: Sun, 22 Mar 2026 00:48:49 -0400 Subject: [PATCH] ci: restructure pipeline into parallel jobs with E2E, Docker validation, and auditing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split serial build-and-test job into parallel backend, frontend, docker-validate, and e2e jobs - backend job: build → test → lint (new ESLint) → npm audit --audit-level=high - frontend job: build → lint → npm audit --audit-level=high - docker-validate job: builds image on every PR without pushing; Trivy scans for CRITICAL/HIGH CVEs (informational) - e2e job: runs full Playwright suite against live dev servers after backend+frontend pass - Add backend/eslint.config.mjs and lint script to backend/package.json --- .github/workflows/ci.yml | 147 +++++++++++++++++++++++++++++++++----- backend/eslint.config.mjs | 15 ++++ backend/package.json | 8 ++- 3 files changed, 152 insertions(+), 18 deletions(-) create mode 100644 backend/eslint.config.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7dd343e..bf294710 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: [ develop ] jobs: - build-and-test: + backend: runs-on: ubuntu-latest steps: - name: Checkout Code @@ -18,30 +18,145 @@ jobs: with: node-version: '20' cache: 'npm' - cache-dependency-path: | - backend/package-lock.json - frontend/package-lock.json + cache-dependency-path: backend/package-lock.json - - name: Install Backend Dependencies + - name: Install Dependencies working-directory: ./backend run: npm ci - - name: Build Backend (TypeScript) + - name: Build (TypeScript) working-directory: ./backend run: npm run build - - name: Install Frontend Dependencies - working-directory: ./frontend - run: npm ci - - - name: Build Frontend (Vite/React) - working-directory: ./frontend - run: npm run build - - - name: Run Backend Unit Tests (Vitest) + - name: Unit Tests (Vitest) working-directory: ./backend run: npm test - - name: Lint Frontend (ESLint) + - name: Lint (ESLint) + working-directory: ./backend + run: npm run lint + + - name: Audit Dependencies + working-directory: ./backend + run: npm audit --audit-level=high + + frontend: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install Dependencies + working-directory: ./frontend + run: npm ci + + - name: Build (Vite/React) + working-directory: ./frontend + run: npm run build + + - name: Lint (ESLint) working-directory: ./frontend run: npm run lint + + - name: Audit Dependencies + working-directory: ./frontend + run: npm audit --audit-level=high + + docker-validate: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image (validation only) + uses: docker/build-push-action@v5 + with: + context: . + push: false + tags: sencho:pr-test + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Scan image for vulnerabilities (Trivy) + uses: aquasecurity/trivy-action@master + with: + image-ref: sencho:pr-test + exit-code: '0' + severity: 'CRITICAL,HIGH' + format: 'table' + continue-on-error: true + + e2e: + runs-on: ubuntu-latest + needs: [ backend, frontend ] + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install root dependencies (Playwright) + run: npm ci + + - name: Install backend dependencies + working-directory: ./backend + run: npm ci + + - name: Build backend + working-directory: ./backend + run: npm run build + + - name: Install frontend dependencies + working-directory: ./frontend + run: npm ci + + - name: Create compose directory + run: mkdir -p /tmp/compose + + - name: Start backend + working-directory: ./backend + run: node dist/index.js & + env: + JWT_SECRET: ci-test-secret-key-not-for-production + COMPOSE_DIR: /tmp/compose + PORT: 3000 + NODE_ENV: test + + - name: Start frontend dev server + working-directory: ./frontend + run: npm run dev & + + - name: Wait for services to be ready + run: npx wait-on http://localhost:3000/api/health http://localhost:5173 --timeout 30000 + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Run E2E tests + run: npx playwright test + env: + E2E_USERNAME: admin + E2E_PASSWORD: password123 + + - name: Upload E2E report + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: | + e2e/report/ + test-results/ + retention-days: 7 diff --git a/backend/eslint.config.mjs b/backend/eslint.config.mjs new file mode 100644 index 00000000..5e51e519 --- /dev/null +++ b/backend/eslint.config.mjs @@ -0,0 +1,15 @@ +import js from '@eslint/js' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + files: ['src/**/*.ts'], + extends: [js.configs.recommended, ...tseslint.configs.recommended], + languageOptions: { ecmaVersion: 2022 }, + rules: { + '@typescript-eslint/no-explicit-any': 'warn', + 'no-console': 'off', + }, + }, +) diff --git a/backend/package.json b/backend/package.json index 6fe739ad..09920b91 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,7 +7,8 @@ "build": "tsc", "start": "node dist/index.js", "dev": "nodemon --watch src --ext ts,json --exec ts-node src/index.ts", - "test": "vitest run" + "test": "vitest run", + "lint": "eslint src" }, "keywords": [], "author": "", @@ -26,7 +27,10 @@ "supertest": "^7.2.2", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "vitest": "^4.1.0" + "vitest": "^4.1.0", + "@eslint/js": "^9.0.0", + "eslint": "^9.0.0", + "typescript-eslint": "^8.0.0" }, "dependencies": { "@types/cors": "^2.8.19",