# ============================================================================= # CI Pipeline - ERP Construccion # Runs on every push and pull request # ============================================================================= name: CI Pipeline on: push: branches: [main, develop, 'feature/**'] pull_request: branches: [main, develop] env: NODE_VERSION: '20' POSTGRES_USER: test_user POSTGRES_PASSWORD: test_password POSTGRES_DB: test_db jobs: # =========================================================================== # Lint & Type Check # =========================================================================== lint: name: Lint & Type Check runs-on: ubuntu-latest 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 frontend/web/package-lock.json - name: Install Backend Dependencies working-directory: backend run: npm ci - name: Install Frontend Dependencies working-directory: frontend/web run: npm ci - name: Lint Backend working-directory: backend run: npm run lint - name: Lint Frontend working-directory: frontend/web run: npm run lint || true - name: Type Check Backend working-directory: backend run: npm run build -- --noEmit || npm run build # =========================================================================== # Validate Constants (SSOT) # =========================================================================== validate-constants: name: Validate SSOT Constants runs-on: ubuntu-latest 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 working-directory: backend run: npm ci - name: Run Constants Validation working-directory: backend run: npm run validate:constants || echo "Validation script not yet implemented" # =========================================================================== # Unit Tests - Backend # =========================================================================== test-backend: name: Backend Tests runs-on: ubuntu-latest needs: [lint] services: postgres: image: postgis/postgis:15-3.3-alpine env: POSTGRES_USER: ${{ env.POSTGRES_USER }} POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} POSTGRES_DB: ${{ env.POSTGRES_DB }} ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: image: redis:7-alpine ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --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 working-directory: backend run: npm ci - name: Run Unit Tests working-directory: backend run: npm run test -- --coverage --passWithNoTests env: DB_HOST: localhost DB_PORT: 5432 DB_USER: ${{ env.POSTGRES_USER }} DB_PASSWORD: ${{ env.POSTGRES_PASSWORD }} DB_NAME: ${{ env.POSTGRES_DB }} REDIS_HOST: localhost REDIS_PORT: 6379 - name: Upload Coverage Report uses: codecov/codecov-action@v3 if: always() with: files: backend/coverage/lcov.info flags: backend fail_ci_if_error: false # =========================================================================== # Unit Tests - Frontend # =========================================================================== test-frontend: name: Frontend Tests runs-on: ubuntu-latest needs: [lint] 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/web/package-lock.json - name: Install Dependencies working-directory: frontend/web run: npm ci - name: Run Unit Tests working-directory: frontend/web run: npm run test -- --coverage --passWithNoTests || echo "No tests yet" - name: Upload Coverage Report uses: codecov/codecov-action@v3 if: always() with: files: frontend/web/coverage/lcov.info flags: frontend fail_ci_if_error: false # =========================================================================== # Build Check # =========================================================================== build: name: Build runs-on: ubuntu-latest needs: [test-backend, test-frontend] steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Build Backend working-directory: backend run: | npm ci npm run build - name: Build Frontend working-directory: frontend/web run: | npm ci npm run build - name: Upload Backend Artifacts uses: actions/upload-artifact@v3 with: name: backend-dist path: backend/dist retention-days: 7 - name: Upload Frontend Artifacts uses: actions/upload-artifact@v3 with: name: frontend-dist path: frontend/web/dist retention-days: 7 # =========================================================================== # Docker Build (only on main/develop) # =========================================================================== docker: name: Docker Build runs-on: ubuntu-latest needs: [build] if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Backend Docker Image uses: docker/build-push-action@v5 with: context: ./backend file: ./backend/Dockerfile target: production push: false tags: construccion-backend:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max - name: Build Frontend Docker Image uses: docker/build-push-action@v5 with: context: ./frontend/web file: ./frontend/web/Dockerfile target: production push: false tags: construccion-frontend:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max