Merge pull request #123 from christianlouis/copilot/setup-codecov-integration
feat(ci): Add Codecov integration with frontend Jest coverage
This commit is contained in:
@@ -123,12 +123,37 @@ jobs:
|
|||||||
cd backend
|
cd backend
|
||||||
pytest tests/ -v --cov=app --cov-report=xml --cov-report=term
|
pytest tests/ -v --cov=app --cov-report=xml --cov-report=term
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v6
|
||||||
|
with:
|
||||||
|
node-version: '20.19.0'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: npm ci
|
||||||
|
working-directory: frontend
|
||||||
|
|
||||||
|
- name: Run frontend tests with coverage
|
||||||
|
run: npm run test:ci
|
||||||
|
working-directory: frontend
|
||||||
|
|
||||||
|
- name: Upload backend coverage to Codecov
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v5
|
||||||
with:
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
files: ./backend/coverage.xml
|
files: ./backend/coverage.xml
|
||||||
flags: unittests
|
flags: backend
|
||||||
name: codecov-umbrella
|
name: backend-coverage
|
||||||
|
fail_ci_if_error: false
|
||||||
|
|
||||||
|
- name: Upload frontend coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v5
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
files: ./frontend/coverage/lcov.info
|
||||||
|
flags: frontend
|
||||||
|
name: frontend-coverage
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
|
|
||||||
# ── Phase 3: Security ──────────────────────────────────────────────────
|
# ── Phase 3: Security ──────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Codecov integration: frontend Jest test coverage (lcov) and backend pytest-cov (XML) are now uploaded to Codecov with `CODECOV_TOKEN` authentication and separate `frontend`/`backend` flags.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- CI: replaced `safety scan --json` (requires interactive login in Safety CLI v3) with `pip-audit` to fix EOF error in the security scan job
|
- CI: replaced `safety scan --json` (requires interactive login in Safety CLI v3) with `pip-audit` to fix EOF error in the security scan job
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Comprehensive task breakdown for repository improvements and production readines
|
|||||||
|
|
||||||
## ✅ Recently Completed
|
## ✅ Recently Completed
|
||||||
|
|
||||||
|
- [x] **Codecov integration**: Added Codecov coverage reporting with `CODECOV_TOKEN` authentication. Set up Jest for frontend tests with lcov coverage, updated CI to collect and upload both backend (XML via pytest-cov) and frontend (lcov via Jest) coverage reports to Codecov with separate `backend` and `frontend` flags.
|
||||||
- [x] **IMAP: fix all emails appearing empty** — `aioimaplib` stores RFC822 literal data as `bytearray`, not `bytes`. The extraction loop was checking `isinstance(line, bytes)` which returns `False` for `bytearray`, so every email body was silently skipped. Fixed to accept both types and convert to `bytes`. Affected T-Online, GMX, and all IMAP accounts.
|
- [x] **IMAP: fix all emails appearing empty** — `aioimaplib` stores RFC822 literal data as `bytearray`, not `bytes`. The extraction loop was checking `isinstance(line, bytes)` which returns `False` for `bytearray`, so every email body was silently skipped. Fixed to accept both types and convert to `bytes`. Affected T-Online, GMX, and all IMAP accounts.
|
||||||
- [x] **CI: fix safety scan EOF error** — replaced `safety scan --json` (Safety CLI v3 requires interactive login) with `pip-audit` (no auth required, maintained by PyPA).
|
- [x] **CI: fix safety scan EOF error** — replaced `safety scan --json` (Safety CLI v3 requires interactive login) with `pip-audit` (no auth required, maintained by PyPA).
|
||||||
- [x] **Security: upgrade fastapi/starlette and fix safety CI command** — Upgraded `fastapi` to `0.135.2` (pulls in `starlette>=1.0.0`) fixing 4 DoS CVEs in `starlette<=0.35.1`; replaced deprecated `safety check` with `safety scan`; added `.safety-policy.yml` to suppress unfixable `ecdsa` side-channel CVEs (maintainers won't fix).
|
- [x] **Security: upgrade fastapi/starlette and fix safety CI command** — Upgraded `fastapi` to `0.135.2` (pulls in `starlette>=1.0.0`) fixing 4 DoS CVEs in `starlette<=0.35.1`; replaced deprecated `safety check` with `safety scan`; added `.safety-policy.yml` to suppress unfixable `ecdsa` side-channel CVEs (maintainers won't fix).
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const nextJest = require('next/jest');
|
||||||
|
|
||||||
|
const createJestConfig = nextJest({
|
||||||
|
dir: './',
|
||||||
|
});
|
||||||
|
|
||||||
|
const customJestConfig = {
|
||||||
|
testEnvironment: 'jest-environment-jsdom',
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^@/(.*)$': '<rootDir>/src/$1',
|
||||||
|
},
|
||||||
|
testMatch: ['**/*.test.(ts|tsx|js|jsx)', '**/*.test.ts', '**/*.test.tsx'],
|
||||||
|
collectCoverageFrom: [
|
||||||
|
'src/**/*.{ts,tsx}',
|
||||||
|
'!src/**/*.d.ts',
|
||||||
|
'!src/**/layout.tsx',
|
||||||
|
'!src/**/page.tsx',
|
||||||
|
'!src/instrumentation.ts',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = createJestConfig(customJestConfig);
|
||||||
Generated
+3869
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,9 @@
|
|||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint"
|
"lint": "eslint",
|
||||||
|
"test": "jest",
|
||||||
|
"test:ci": "jest --coverage --coverageReporters=lcov --passWithNoTests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-query": "^5.95.0",
|
"@tanstack/react-query": "^5.95.0",
|
||||||
@@ -19,11 +21,14 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
|
"@types/jest": "^30.0.0",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "16.2.1",
|
"eslint-config-next": "16.2.1",
|
||||||
|
"jest": "^30.3.0",
|
||||||
|
"jest-environment-jsdom": "^30.3.0",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { describe, it, expect, beforeEach } from 'bun:test';
|
|
||||||
|
|
||||||
// Mock localStorage
|
// Mock localStorage
|
||||||
const localStorageMock = (() => {
|
const localStorageMock = (() => {
|
||||||
let store: Record<string, string> = {};
|
let store: Record<string, string> = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user