name: ERP Core CI on: push: branches: [main, develop, 'feature/*'] pull_request: branches: [main, develop] env: NODE_VERSION: '20.x' POSTGRES_DB: erp_generic_test POSTGRES_USER: erp_admin POSTGRES_PASSWORD: test_secret_2024 POSTGRES_HOST: localhost POSTGRES_PORT: 5432 jobs: # ========================================== # Backend Tests # ========================================== backend-lint: name: Backend Lint runs-on: ubuntu-latest defaults: run: working-directory: backend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: backend/package-lock.json - name: Install dependencies run: npm ci - name: Run ESLint run: npm run lint backend-unit-tests: name: Backend Unit Tests runs-on: ubuntu-latest defaults: run: working-directory: backend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: backend/package-lock.json - name: Install dependencies run: npm ci - name: Run unit tests run: npm test -- --testPathIgnorePatterns=integration - name: Upload coverage report uses: codecov/codecov-action@v4 if: always() with: directory: backend/coverage flags: backend-unit fail_ci_if_error: false backend-integration-tests: name: Backend Integration Tests runs-on: ubuntu-latest defaults: run: working-directory: backend services: postgres: image: postgres:16 env: POSTGRES_DB: ${{ env.POSTGRES_DB }} POSTGRES_USER: ${{ env.POSTGRES_USER }} POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: backend/package-lock.json - name: Install dependencies run: npm ci - name: Wait for PostgreSQL run: | until pg_isready -h ${{ env.POSTGRES_HOST }} -p ${{ env.POSTGRES_PORT }}; do echo "Waiting for PostgreSQL..." sleep 2 done - name: Setup test database run: | cd ../database chmod +x scripts/create-test-database.sh TEST_DB_NAME=${{ env.POSTGRES_DB }} \ POSTGRES_USER=${{ env.POSTGRES_USER }} \ POSTGRES_PASSWORD=${{ env.POSTGRES_PASSWORD }} \ POSTGRES_HOST=${{ env.POSTGRES_HOST }} \ POSTGRES_PORT=${{ env.POSTGRES_PORT }} \ ./scripts/create-test-database.sh - name: Run integration tests run: npm test -- --testPathPattern=integration env: TEST_DB_HOST: ${{ env.POSTGRES_HOST }} TEST_DB_PORT: ${{ env.POSTGRES_PORT }} TEST_DB_NAME: ${{ env.POSTGRES_DB }} TEST_DB_USER: ${{ env.POSTGRES_USER }} TEST_DB_PASSWORD: ${{ env.POSTGRES_PASSWORD }} backend-build: name: Backend Build runs-on: ubuntu-latest needs: [backend-lint, backend-unit-tests] defaults: run: working-directory: backend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: backend/package-lock.json - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: backend-dist path: backend/dist # ========================================== # Frontend Tests # ========================================== frontend-lint: name: Frontend Lint runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm ci - name: Run ESLint run: npm run lint frontend-unit-tests: name: Frontend Unit Tests runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm ci - name: Run unit tests run: npm test -- --run - name: Upload coverage report uses: codecov/codecov-action@v4 if: always() with: directory: frontend/coverage flags: frontend-unit fail_ci_if_error: false frontend-e2e-tests: name: Frontend E2E Tests runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm ci - name: Install Playwright browsers run: npx playwright install --with-deps chromium - name: Run E2E tests run: npm run test:e2e - name: Upload Playwright report uses: actions/upload-artifact@v4 if: always() with: name: playwright-report path: frontend/playwright-report retention-days: 7 frontend-build: name: Frontend Build runs-on: ubuntu-latest needs: [frontend-lint, frontend-unit-tests] defaults: run: working-directory: frontend steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: frontend-dist path: frontend/dist # ========================================== # Database Validation # ========================================== database-validation: name: Database DDL Validation runs-on: ubuntu-latest defaults: run: working-directory: database services: postgres: image: postgres:16 env: POSTGRES_DB: erp_ddl_test POSTGRES_USER: ${{ env.POSTGRES_USER }} POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v4 - name: Wait for PostgreSQL run: | until pg_isready -h localhost -p 5432; do echo "Waiting for PostgreSQL..." sleep 2 done - name: Validate DDL files can be executed run: | export PGPASSWORD=${{ env.POSTGRES_PASSWORD }} # Execute DDL files in order for ddl_file in ddl/*.sql; do echo "Executing $ddl_file..." psql -h localhost -p 5432 -U ${{ env.POSTGRES_USER }} -d erp_ddl_test -f "$ddl_file" || exit 1 done echo "All DDL files executed successfully!" - name: Check for schema objects run: | export PGPASSWORD=${{ env.POSTGRES_PASSWORD }} psql -h localhost -p 5432 -U ${{ env.POSTGRES_USER }} -d erp_ddl_test -c " SELECT schemaname, COUNT(*) as tables FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY schemaname ORDER BY schemaname; " # ========================================== # Summary Job # ========================================== ci-success: name: CI Success runs-on: ubuntu-latest needs: - backend-build - backend-integration-tests - frontend-build - frontend-e2e-tests - database-validation if: always() steps: - name: Check all jobs status run: | if [ "${{ needs.backend-build.result }}" != "success" ] || \ [ "${{ needs.backend-integration-tests.result }}" != "success" ] || \ [ "${{ needs.frontend-build.result }}" != "success" ] || \ [ "${{ needs.frontend-e2e-tests.result }}" != "success" ] || \ [ "${{ needs.database-validation.result }}" != "success" ]; then echo "One or more jobs failed" exit 1 fi echo "All CI jobs passed successfully!"