Skip to content

Backend CI

Backend CI #334

Workflow file for this run

name: Backend CI
on:
push:
branches:
- main
- develop
- 'feature/*'
- 'bugfix/*'
pull_request:
branches:
- main
- develop
schedule:
- cron: '0 0 * * *' # Daily at midnight UTC
workflow_call: # Enable workflow reuse
env:
NODE_VERSION: '18.x'
WORKING_DIRECTORY: './src/backend'
COVERAGE_THRESHOLD: '80'
TEST_RETRY_COUNT: '3'
NODE_ENV: 'test'
CI: 'true'
FORCE_COLOR: 'true'
JEST_JUNIT_UNIQUE_OUTPUT_NAME: 'true'
jobs:
lint:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: ${{ env.WORKING_DIRECTORY }}/package-lock.json
- name: Install dependencies
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm ci
- name: Run ESLint
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm run lint -- --max-warnings 0
- name: Check formatting
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm run format -- --check
- name: TypeScript compilation check
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npx tsc --noEmit
test:
name: Tests & Coverage
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: ${{ env.WORKING_DIRECTORY }}/package-lock.json
- name: Restore test cache
uses: actions/cache@v3
with:
path: |
${{ env.WORKING_DIRECTORY }}/coverage
${{ env.WORKING_DIRECTORY }}/.jest-cache
key: ${{ runner.os }}-test-${{ hashFiles('**/jest.config.ts') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-test-${{ hashFiles('**/jest.config.ts') }}-
${{ runner.os }}-test-
- name: Install dependencies
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm ci
- name: Run unit tests
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
npm run test -- \
--ci \
--coverage \
--maxWorkers=2 \
--reporters=default \
--reporters=jest-junit \
--coverageThreshold='{"global":{"branches":${{ env.COVERAGE_THRESHOLD }},"functions":${{ env.COVERAGE_THRESHOLD }},"lines":${{ env.COVERAGE_THRESHOLD }},"statements":${{ env.COVERAGE_THRESHOLD }}}}' \
--cacheDirectory=.jest-cache
env:
JEST_JUNIT_OUTPUT_DIR: './junit'
JEST_JUNIT_OUTPUT_NAME: 'unit-test-results.xml'
- name: Run integration tests
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
npm run test:e2e -- \
--ci \
--maxWorkers=2 \
--reporters=default \
--reporters=jest-junit \
--retries ${{ env.TEST_RETRY_COUNT }}
env:
JEST_JUNIT_OUTPUT_DIR: './junit'
JEST_JUNIT_OUTPUT_NAME: 'integration-test-results.xml'
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: |
${{ env.WORKING_DIRECTORY }}/junit/
${{ env.WORKING_DIRECTORY }}/coverage/
security:
name: Security Scan
runs-on: ubuntu-latest
needs: test
permissions:
security-events: write
actions: read
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript
queries: security-extended,security-and-quality
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: ${{ env.WORKING_DIRECTORY }}/package-lock.json
- name: Install dependencies
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm ci
- name: Run dependency audit
working-directory: ${{ env.WORKING_DIRECTORY }}
run: npm audit --audit-level=high
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:javascript"
upload-database: true
- name: Upload security results
uses: actions/upload-artifact@v3
with:
name: security-results
path: |
${{ env.WORKING_DIRECTORY }}/security-results.sarif
${{ env.WORKING_DIRECTORY }}/npm-audit.json