erp-construccion/.github/workflows/ci.yml

264 lines
7.4 KiB
YAML

# =============================================================================
# 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