diff --git a/.gitea/workflows/all-services.yml b/.gitea/workflows/all-services.yml new file mode 100644 index 0000000..6707da1 --- /dev/null +++ b/.gitea/workflows/all-services.yml @@ -0,0 +1,247 @@ +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 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 "==================================" diff --git a/.gitea/workflows/api-docs.yml b/.gitea/workflows/api-docs.yml index 0095c0d..1831e86 100644 --- a/.gitea/workflows/api-docs.yml +++ b/.gitea/workflows/api-docs.yml @@ -8,6 +8,28 @@ on: pull_request: paths: - 'services/api-docs/**' + workflow_dispatch: + inputs: + run_tests: + description: 'Run tests' + required: false + default: true + type: boolean + run_lint: + description: 'Run linting' + required: false + default: true + type: boolean + run_build: + description: 'Run build' + required: false + default: true + type: boolean + run_sonar: + description: 'Run SonarQube analysis' + required: false + default: true + type: boolean env: REGISTRY: gitea.example.com diff --git a/.gitea/workflows/api-gateway.yml b/.gitea/workflows/api-gateway.yml index 10badb0..571abc4 100644 --- a/.gitea/workflows/api-gateway.yml +++ b/.gitea/workflows/api-gateway.yml @@ -8,6 +8,28 @@ on: pull_request: paths: - 'services/api-gateway/**' + workflow_dispatch: + inputs: + run_tests: + description: 'Run tests' + required: false + default: true + type: boolean + run_lint: + description: 'Run linting' + required: false + default: true + type: boolean + run_build: + description: 'Run build' + required: false + default: true + type: boolean + run_sonar: + description: 'Run SonarQube analysis' + required: false + default: true + type: boolean env: REGISTRY: gitea.example.com diff --git a/.gitea/workflows/frontend.yml b/.gitea/workflows/frontend.yml index 4ead62d..4bd0184 100644 --- a/.gitea/workflows/frontend.yml +++ b/.gitea/workflows/frontend.yml @@ -8,6 +8,28 @@ on: pull_request: paths: - 'frontend/**' + workflow_dispatch: + inputs: + run_tests: + description: 'Run tests' + required: false + default: true + type: boolean + run_lint: + description: 'Run linting' + required: false + default: true + type: boolean + run_build: + description: 'Run build' + required: false + default: true + type: boolean + run_sonar: + description: 'Run SonarQube analysis' + required: false + default: true + type: boolean env: REGISTRY: gitea.example.com diff --git a/.gitea/workflows/service-adapters.yml b/.gitea/workflows/service-adapters.yml index 1771d0a..4c5ffed 100644 --- a/.gitea/workflows/service-adapters.yml +++ b/.gitea/workflows/service-adapters.yml @@ -8,10 +8,32 @@ on: pull_request: paths: - 'services/service-adapters/**' + workflow_dispatch: + inputs: + run_tests: + description: 'Run tests' + required: false + default: true + type: boolean + run_lint: + description: 'Run linting' + required: false + default: true + type: boolean + run_build: + description: 'Run build' + required: false + default: true + type: boolean + run_sonar: + description: 'Run SonarQube analysis' + required: false + default: true + type: boolean env: REGISTRY: gitea.example.com - IMAGE_PREFIX: labfusion + IMAGE_PREFIX: labusion SERVICE_NAME: service-adapters jobs: