Backend CI #336
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |