name: All Services (Comprehensive) on: workflow_dispatch: inputs: run_frontend: description: 'Run Frontend pipeline' required: false default: true type: boolean run_api_gateway: description: 'Run API Gateway pipeline' required: false default: true type: boolean run_api_docs: description: 'Run API Docs pipeline' required: false default: true type: boolean run_service_adapters: description: 'Run Service Adapters pipeline' required: false default: true type: boolean run_tests_only: description: 'Run tests only (skip build and SonarQube)' required: false default: false type: boolean run_sonar_only: description: 'Run SonarQube analysis only' required: false default: false type: boolean env: REGISTRY: gitea.example.com IMAGE_PREFIX: labfusion jobs: frontend: if: ${{ inputs.run_frontend }} runs-on: [self-hosted] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js 20 uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies working-directory: ./frontend run: npm ci - name: Run tests if: ${{ !inputs.run_sonar_only }} working-directory: ./frontend run: npx vitest run --coverage --reporter=verbose - name: Run linting if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./frontend run: npm run lint - name: Run build if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./frontend run: npm run build - name: Send results to SonarQube if: ${{ !inputs.run_tests_only }} run: | echo "Sending Frontend results to SonarQube..." npm install -g @sonar/scan sonar-scanner \ -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \ -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ -Dsonar.projectKey=labfusion-frontend \ -Dsonar.projectName=LabFusion Frontend \ -Dsonar.sources=frontend/src \ -Dsonar.tests=frontend/src \ -Dsonar.sources.inclusions=**/*.js,**/*.jsx \ -Dsonar.sources.exclusions=**/*.test.js,**/*.test.jsx,**/*.spec.js,**/*.spec.jsx,frontend/src/index.js,frontend/src/setupTests.js \ -Dsonar.tests.inclusions=**/*.test.js,**/*.test.jsx,**/*.spec.js,**/*.spec.jsx \ -Dsonar.coverage.exclusions=**/*.test.js,**/*.test.jsx,**/*.spec.js,**/*.spec.jsx,frontend/src/index.js,frontend/src/setupTests.js \ -Dsonar.javascript.lcov.reportPaths=frontend/coverage/lcov.info api-gateway: if: ${{ inputs.run_api_gateway }} runs-on: [self-hosted] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Cache Maven dependencies uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Run tests if: ${{ !inputs.run_sonar_only }} working-directory: ./services/api-gateway run: ./mvnw test - name: Run SonarQube analysis if: ${{ !inputs.run_tests_only }} working-directory: ./services/api-gateway run: | ./mvnw clean verify sonar:sonar \ -Dsonar.host.url="${{ secrets.SONAR_HOST_URL }}" \ -Dsonar.login="${{ secrets.SONAR_TOKEN }}" \ -Dsonar.projectKey=labfusion-api-gateway \ -Dsonar.projectName=LabFusion-API-Gateway - name: Build application if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./services/api-gateway run: ./mvnw clean package -DskipTests api-docs: if: ${{ inputs.run_api_docs }} runs-on: [self-hosted] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js 20 uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: services/api-docs/package-lock.json - name: Install dependencies working-directory: ./services/api-docs run: npm ci - name: Run tests if: ${{ !inputs.run_sonar_only }} working-directory: ./services/api-docs run: npm test - name: Run linting if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./services/api-docs run: npm run lint - name: Run build if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./services/api-docs run: npm run build - name: Send results to SonarQube if: ${{ !inputs.run_tests_only }} run: | echo "Sending API Docs results to SonarQube..." npm install -g @sonar/scan sonar-scanner \ -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \ -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ -Dsonar.projectKey=labfusion-api-docs \ -Dsonar.projectName=LabFusion API Docs \ -Dsonar.sources=services/api-docs \ -Dsonar.tests=services/api-docs \ -Dsonar.sources.inclusions=**/*.js \ -Dsonar.sources.exclusions=**/*.test.js,**/*.spec.js,services/api-docs/node_modules/** \ -Dsonar.tests.inclusions=**/*.test.js,**/*.spec.js \ -Dsonar.coverage.exclusions=**/*.test.js,**/*.spec.js,services/api-docs/node_modules/** \ -Dsonar.javascript.lcov.reportPaths=services/api-docs/coverage/lcov.info service-adapters: if: ${{ inputs.run_service_adapters }} runs-on: [self-hosted] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.11 uses: actions/setup-python@v4 with: python-version: '3.11' cache: 'pip' cache-dependency-path: services/service-adapters/requirements.txt - name: Install dependencies working-directory: ./services/service-adapters run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests if: ${{ !inputs.run_sonar_only }} working-directory: ./services/service-adapters run: | python -m pytest tests/ -v --cov=. --cov-report=xml --cov-report=html - name: Run linting if: ${{ !inputs.run_tests_only && !inputs.run_sonar_only }} working-directory: ./services/service-adapters run: | flake8 . --max-line-length=150 bandit -r . -f json -o bandit-report.json - name: Send results to SonarQube if: ${{ !inputs.run_tests_only }} run: | echo "Sending Service Adapters results to SonarQube..." pip install sonar-scanner sonar-scanner \ -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \ -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ -Dsonar.projectKey=labfusion-service-adapters \ -Dsonar.projectName=LabFusion Service Adapters \ -Dsonar.sources=services/service-adapters \ -Dsonar.tests=services/service-adapters \ -Dsonar.sources.inclusions=**/*.py \ -Dsonar.sources.exclusions=**/*.test.py,**/*.spec.py,services/service-adapters/tests/** \ -Dsonar.tests.inclusions=**/*.test.py,**/*.spec.py \ -Dsonar.coverage.exclusions=**/*.test.py,**/*.spec.py,services/service-adapters/tests/** \ -Dsonar.python.coverage.reportPaths=services/service-adapters/coverage.xml summary: runs-on: [self-hosted] needs: [frontend, api-gateway, api-docs, service-adapters] if: always() steps: - name: Pipeline Summary run: | echo "=== LabFusion Pipeline Summary ===" echo "Frontend: ${{ needs.frontend.result }}" echo "API Gateway: ${{ needs.api-gateway.result }}" echo "API Docs: ${{ needs.api-docs.result }}" echo "Service Adapters: ${{ needs.service-adapters.result }}" echo "=================================="