diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7c6ac1..4cf938e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,10 @@ on: pull_request: branches: [main, master, develop] +env: + REGISTRY: ghcr.io + IMAGE_TAG: ${{ github.sha }} + jobs: frontend-check: name: Frontend CI @@ -24,9 +28,14 @@ jobs: - name: Install dependencies run: npm ci - name: Lint - run: npm run lint || echo "Lint warning" + run: npm run lint - name: TypeCheck - run: npx tsc --noEmit || true + run: npx tsc --noEmit + - name: Run unit tests + run: npm test + - name: Security audit + run: npm audit --audit-level=high + continue-on-error: true - name: Build run: npm run build env: @@ -49,6 +58,10 @@ jobs: - name: Install dependencies run: npm ci working-directory: services/${{ matrix.service }} + - name: Security audit + run: npm audit --audit-level=high + continue-on-error: true + working-directory: services/${{ matrix.service }} - name: Syntax check run: node -c index.js working-directory: services/${{ matrix.service }} @@ -77,6 +90,11 @@ jobs: - name: Compile check run: go build -v ./... working-directory: services/${{ matrix.service }} + - name: Security scan + run: | + go install github.com/securego/gosec/v2/cmd/gosec@latest + gosec -no-fail -fmt sarif -out gosec-results.sarif ./... + working-directory: services/${{ matrix.service }} python-services-check: name: Python Services CI @@ -98,11 +116,15 @@ jobs: pip install -r requirements.txt working-directory: services/${{ matrix.service }} - name: Install linting tools - run: pip install flake8 pytest httpx + run: pip install flake8 pytest httpx bandit working-directory: services/${{ matrix.service }} - name: Lint Python run: flake8 . --max-line-length=120 working-directory: services/${{ matrix.service }} + - name: Security scan + run: bandit -r . --severity high + working-directory: services/${{ matrix.service }} + continue-on-error: true - name: Test Python run: pytest -v working-directory: services/${{ matrix.service }} @@ -124,3 +146,73 @@ jobs: - name: Compile and test run: mvn clean test working-directory: services/${{ matrix.service }} + + docker-build: + name: Docker Build + runs-on: ubuntu-latest + strategy: + matrix: + image: + - frontend + - api-gateway-node + - auth-service + - notification-go-service + - attendance-service + - employee-python-service + - analytics-python-service + - payroll-java-service + - leave-service + steps: + - uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + if: github.event_name == 'push' + - name: Determine Docker context + id: context + shell: bash + run: | + if [[ "${{ matrix.image }}" == "frontend" ]]; then + echo "context=frontend" >> $GITHUB_OUTPUT + echo "dockerfile=frontend/Dockerfile" >> $GITHUB_OUTPUT + else + echo "context=services/${{ matrix.image }}" >> $GITHUB_OUTPUT + echo "dockerfile=services/${{ matrix.image }}/Dockerfile" >> $GITHUB_OUTPUT + fi + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: ${{ steps.context.outputs.context }} + dockerfile: ${{ steps.context.outputs.dockerfile }} + push: ${{ github.event_name == 'push' }} + tags: | + ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.image }}:${{ env.IMAGE_TAG }} + ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.image }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + security-scan: + name: Security Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + scan-type: fs + scan-ref: . + format: sarif + output: trivy-results.sarif + severity: HIGH,CRITICAL + exit-code: 1 + continue-on-error: true + - name: Upload Trivy results to GitHub Security + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: trivy-results.sarif + if: always()