From 012a69e1303fff5da2a60c69fe0d6a867a01cce9 Mon Sep 17 00:00:00 2001 From: Abdulsamad <100522473+Seermad1@users.noreply.github.com> Date: Tue, 29 Sep 2026 19:16:56 +0100 Subject: [PATCH 1/2] security: Enforce CI gates by removing continue-on-error (#1283) --- .github/workflows/ci.yml | 94 ---------------------------------------- jest.config.cjs | 35 --------------- package.json | 35 +++++++++++++++ 3 files changed, 35 insertions(+), 129 deletions(-) delete mode 100644 .github/workflows/ci.yml delete mode 100644 jest.config.cjs create mode 100644 package.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 716545f7..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: CI Pipeline - -on: - push: - branches: ["main", "develop"] - pull_request: - branches: ["main", "develop"] - -jobs: - migration-policy: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: npm - - name: Install dependencies - run: npm ci - - name: Verify migration layout and schema drift - run: npx tsx scripts/check-migrations.ts - env: - CHECKSUM_CI_SKIP_MISSING: "1" - - build: - runs-on: ubuntu-latest - continue-on-error: true - - strategy: - matrix: - node-version: [20] - - steps: - - name: Checkout repository - continue-on-error: true - uses: actions/checkout@v4 - - - name: Setup Node.js - continue-on-error: true - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "npm" - - - name: Install dependencies - continue-on-error: true - run: npm ci - - - name: Generate Prisma client - continue-on-error: true - run: npx prisma generate - - - name: Run ESLint - continue-on-error: true - run: npm run lint - - - name: Typecheck - continue-on-error: true - run: npm run typecheck - - - name: Run Webhook Dispatch Pipeline Test - continue-on-error: true - run: NODE_ENV=test npm test -- tests/integration/webhook-dispatch-pipeline.test.ts --runInBand - - - name: Build - continue-on-error: true - run: npm run build - - - name: Verify Build Artifacts - continue-on-error: true - run: | - if [ ! -d "dist" ]; then - echo "Build failed: dist directory not found" - exit 1 - fi - if [ ! -f "dist/index.js" ] && [ ! -f "dist/src/index.js" ]; then - echo "Build failed: expected compiled entrypoint not found in dist/" - exit 1 - fi - echo "✅ Build artifacts verified" - - - name: Run Schema Versioning Check - run: npx tsx scripts/check-migrations.ts - env: - CHECKSUM_CI_SKIP_MISSING: "1" - - - name: Check OpenAPI backward compatibility - if: github.event_name == 'pull_request' - run: | - git fetch origin ${{ github.base_ref }} - npx --yes @useoptic/optic diff docs/openapi.json --base origin/${{ github.base_ref }} --check - diff --git a/jest.config.cjs b/jest.config.cjs deleted file mode 100644 index 2b5b7f7f..00000000 --- a/jest.config.cjs +++ /dev/null @@ -1,35 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: "ts-jest", - testEnvironment: "node", - testMatch: ["**/?(*.)+(spec|test).ts"], - testPathIgnorePatterns: ["/node_modules/"], - transformIgnorePatterns: ["/node_modules/(?!.*uuid)"], - transform: { - "^.+\\.ts$": [ - "ts-jest", - { - tsconfig: { - module: "commonjs", - moduleResolution: "node16", - isolatedModules: true, - }, - }, - ], - "^.+\\.js$": [ - "ts-jest", - { - tsconfig: { - module: "commonjs", - moduleResolution: "node16", - isolatedModules: true, - allowJs: true, - }, - }, - ], - }, - setupFiles: ["/jest.env-setup.cjs"], - moduleNameMapper: { - "^(\\.{1,2}/.*)\\.js$": "$1", - }, -}; diff --git a/package.json b/package.json new file mode 100644 index 00000000..e0081c36 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "callora-backend", + "version": "1.0.0", + "description": "Callora Backend API and webhook pipeline", + "main": "dist/index.js", + "scripts": { + "build": "tsc -p tsconfig.build.json", + "lint": "eslint . --ext .js,.js.,ts", + "typecheck": "tsc --noEmit", + "test:unit": "jest --config jest.config.cjs --selectProjects=unit", + "test:integration": "jest --config jest.config.cjs --selectProjects=integration --runInBand", + "test:coverage": "jest --config jest.config.cjs --coVerage --coverageReporters=json-summary,lcov,text", + "test": "npm run test:unit && npm run test:integration" + }, + "dependencies": { + "express": "^4.19.2", + "pgp": "^8.11.5" + }, + "devDependencies": { + "@types/express": "^4.17.20", + "@types/jest": "^29.5.14", + "@types/node": "^20.11.10", + "@typespage": "^8.11.5", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.57.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.5", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "private": true +} From 38ac52375f5d1cbdea490d3aac7beb95201b114b Mon Sep 17 00:00:00 2001 From: Abdulsamad <100522473+Seermad1@users.noreply.github.com> Date: Mon, 5 Oct 2026 13:34:12 +0100 Subject: [PATCH 2/2] fix: restore CI + jest config and remove continue-on-error gates --- .github/workflows/ci.yml | 84 ++++++++++++++++++++++++++++++++++++++++ jest.config.cjs | 35 +++++++++++++++++ package.json | 42 ++++++++------------ 3 files changed, 136 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 jest.config.cjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..caae83c2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,84 @@ +name: CI Pipeline + +on: + push: + branches: ["main", "develop"] + pull_request: + branches: ["main", "develop"] + +jobs: + migration-policy: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + - name: Install dependencies + run: npm ci + - name: Verify migration layout and schema drift + run: npx tsx scripts/check-migrations.ts + env: + CHECKSUM_CI_SKIP_MISSING: "1" + + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Generate Prisma client + run: npx prisma generate + + - name: Run ESLint + run: npm run lint + + - name: Typecheck + run: npm run typecheck + + - name: Run Webhook Dispatch Pipeline Test + run: NODE_ENV=test npm test -- tests/integration/webhook-dispatch-pipeline.test.ts --runInBand + + - name: Build + run: npm run build + + - name: Verify Build Artifacts + run: | + if [ ! -d "dist" ]; then + echo "Build failed: dist directory not found" + exit 1 + fi + if [ ! -f "dist/index.js" ] && [ ! -f "dist/src/index.js" ]; then + echo "Build failed: expected compiled entrypoint not found in dist/" + exit 1 + fi + echo "✅ Build artifacts verified" + + - name: Run Schema Versioning Check + run: npx tsx scripts/check-migrations.ts + env: + CHECKSUM_CI_SKIP_MISSING: "1" + + - name: Check OpenAPI backward compatibility + if: github.event_name == 'pull_request' + run: | + git fetch origin ${{ github.base_ref }} + npx --yes @useoptic/optic diff docs/openapi.json --base origin/${{ github.base_ref }} --check + diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 00000000..2b5b7f7f --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,35 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + testMatch: ["**/?(*.)+(spec|test).ts"], + testPathIgnorePatterns: ["/node_modules/"], + transformIgnorePatterns: ["/node_modules/(?!.*uuid)"], + transform: { + "^.+\\.ts$": [ + "ts-jest", + { + tsconfig: { + module: "commonjs", + moduleResolution: "node16", + isolatedModules: true, + }, + }, + ], + "^.+\\.js$": [ + "ts-jest", + { + tsconfig: { + module: "commonjs", + moduleResolution: "node16", + isolatedModules: true, + allowJs: true, + }, + }, + ], + }, + setupFiles: ["/jest.env-setup.cjs"], + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, +}; diff --git a/package.json b/package.json index e8d51872..15513841 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,13 @@ { "name": "callora-backend", - "version": "1.0.0", - "description": "Callora Backend API and webhook pipeline", + "version": "0.0.1", "type": "module", - "main": "dist/index.js", "scripts": { - "build": "tsc -p tsconfig.build.json", + "build": "tsc", "prebuild": "npm run error-codes:check && npm run validate:openapi", "start": "node dist/index.js", "dev": "tsx watch src/index.ts", - "lint": "eslint . --ext .js,.js.,ts", + "lint": "eslint .", "db:generate": "drizzle-kit generate:sqlite", "db:migrate": "drizzle-kit migrate", "db:studio": "drizzle-kit studio", @@ -21,11 +19,11 @@ "error-codes:generate": "node scripts/generate-error-codes.mjs", "error-codes:check": "node scripts/generate-error-codes.mjs --check", "pretest": "npm run error-codes:check", - "test": "npm run test:unit && npm run test:integration", + "test": "jest --forceExit", "test:serial": "jest --runInBand --forceExit", - "test:unit": "jest --config jest.config.cjs --selectProjects=unit", - "test:integration": "jest --config jest.config.cjs --selectProjects=integration --runInBand", - "test:coverage": "jest --config jest.config.cjs --coVerage --coverageReporters=json-summary,lcov,text" + "test:unit": "jest --runInBand --forceExit --testPathIgnorePatterns tests/integration", + "test:integration": "jest --runInBand --forceExit tests/integration", + "test:coverage": "jest --runInBand --coverage --forceExit --testPathIgnorePatterns tests/integration" }, "dependencies": { "@opentelemetry/api": "^1.9.1", @@ -38,13 +36,12 @@ "cors": "^2.8.6", "dotenv": "^17.3.1", "drizzle-orm": "^0.29.0", - "express": "^4.19.2", + "express": "^4.18.2", "express-openapi-validator": "^5.6.2", "helmet": "^8.1.0", "ip-range-check": "^0.2.0", "jsonwebtoken": "^9.0.3", "pg": "^8.18.0", - "pgp": "^8.11.5", "pino": "^10.3.1", "prisma": "^7.4.1", "prom-client": "^15.1.0", @@ -56,20 +53,19 @@ "@types/bcryptjs": "^2.4.6", "@types/better-sqlite3": "^7.6.8", "@types/cors": "^2.8.19", - "@types/express": "^4.17.20", + "@types/express": "^4.17.21", "@types/helmet": "^0.0.48", - "@types/jest": "^29.5.14", + "@types/jest": "^30.0.0", "@types/jsonwebtoken": "^9.0.10", - "@types/node": "^20.11.10", + "@types/node": "^20.10.0", "@types/pg": "^8.16.0", "@types/supertest": "^6.0.3", "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", - "@typespage": "^8.11.5", + "@typescript-eslint/eslint-plugin": "^8.56.1", + "@typescript-eslint/parser": "^8.56.1", "@useoptic/optic": "^1.0.9", "drizzle-kit": "^0.20.7", - "eslint": "^8.57.0", + "eslint": "^10.0.2", "fast-check": "^3.22.0", "globals": "^17.3.0", "jest": "^29.7.0", @@ -78,16 +74,12 @@ "picomatch": "^2.3.1", "supertest": "^7.2.2", "testcontainers": "^10.10.4", - "ts-jest": "^29.1.5", + "ts-jest": "^29.4.6", "tsx": "^4.7.0", - "typescript": "^5.3.3", + "typescript": "^5.9.3", "typescript-eslint": "^8.56.1" }, - "engines": { - "node": ">=18.0.0" - }, "overrides": { "ajv": "8.17.1" - }, - "private": true + } }