first commit #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Red Hat Learning Paths CI | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME_BACKEND: ${{ github.repository }}-backend | |
| IMAGE_NAME_FRONTEND: ${{ github.repository }}-frontend | |
| jobs: | |
| test-backend: | |
| name: Test Backend | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:15-alpine | |
| env: | |
| POSTGRES_PASSWORD: password | |
| POSTGRES_USER: postgres | |
| POSTGRES_DB: test_db | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.9' | |
| cache: 'pip' | |
| - name: Install dependencies | |
| working-directory: ./backend | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| pip install pytest-cov pytest-mock | |
| - name: Run tests | |
| working-directory: ./backend | |
| env: | |
| DATABASE_URL: postgresql://postgres:password@localhost:5432/test_db | |
| OLLAMA_BASE_URL: http://localhost:11434 | |
| run: | | |
| python -m pytest test_main.py -v --cov=. --cov-report=xml --cov-report=term-missing | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./backend/coverage.xml | |
| flags: backend | |
| name: backend-coverage | |
| test-frontend: | |
| name: Test Frontend | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: ./frontend/package-lock.json | |
| - name: Install dependencies | |
| working-directory: ./frontend | |
| run: npm ci | |
| - name: Run unit tests | |
| working-directory: ./frontend | |
| run: npm test -- --coverage --watchAll=false | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./frontend/coverage/lcov.info | |
| flags: frontend | |
| name: frontend-coverage | |
| lint-and-format: | |
| name: Lint and Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.9' | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: ./frontend/package-lock.json | |
| - name: Install Python linting tools | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install black flake8 isort mypy | |
| - name: Lint Python code | |
| working-directory: ./backend | |
| run: | | |
| flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | |
| black --check . | |
| isort --check-only . | |
| - name: Install frontend dependencies | |
| working-directory: ./frontend | |
| run: npm ci | |
| - name: Lint frontend code | |
| working-directory: ./frontend | |
| run: npm run lint | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| 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' | |
| - name: Upload Trivy scan results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@v2 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| build-images: | |
| name: Build Container Images | |
| runs-on: ubuntu-latest | |
| needs: [test-backend, test-frontend, lint-and-format] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Podman | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y podman | |
| - name: Log in to Container Registry | |
| uses: redhat-actions/podman-login@v1 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for backend | |
| id: meta-backend | |
| uses: docker/metadata-action@v4 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Extract metadata for frontend | |
| id: meta-frontend | |
| uses: docker/metadata-action@v4 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build backend image | |
| working-directory: ./backend | |
| run: | | |
| podman build \ | |
| --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:latest \ | |
| --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:${{ github.sha }} \ | |
| --file Containerfile . | |
| - name: Build frontend image | |
| working-directory: ./frontend | |
| run: | | |
| podman build \ | |
| --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:latest \ | |
| --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:${{ github.sha }} \ | |
| --file Containerfile . | |
| - name: Push backend image | |
| run: | | |
| podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:latest | |
| podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:${{ github.sha }} | |
| - name: Push frontend image | |
| run: | | |
| podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:latest | |
| podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:${{ github.sha }} | |
| e2e-tests: | |
| name: E2E Tests | |
| runs-on: ubuntu-latest | |
| needs: [build-images] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Podman | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y podman | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v3 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: ./frontend/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: ./frontend | |
| run: npm ci | |
| - name: Install Playwright | |
| working-directory: ./frontend | |
| run: npx playwright install --with-deps | |
| - name: Pull container images | |
| run: | | |
| podman pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:${{ github.sha }} | |
| podman pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:${{ github.sha }} | |
| podman pull docker.io/postgres:15-alpine | |
| podman pull docker.io/ollama/ollama:latest | |
| - name: Tag images for local use | |
| run: | | |
| podman tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:${{ github.sha }} localhost/redhat-learning-paths-backend:latest | |
| podman tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:${{ github.sha }} localhost/redhat-learning-paths-frontend:latest | |
| - name: Start application with Podman | |
| run: | | |
| # Create volumes | |
| podman volume create postgres-data || true | |
| podman volume create ollama-data || true | |
| # Start the pod | |
| podman play kube podman-pod.yaml | |
| # Wait for services to be ready | |
| sleep 30 | |
| # Check health | |
| timeout 60 bash -c 'until curl -f http://localhost:30000/health; do sleep 5; done' | |
| timeout 60 bash -c 'until curl -f http://localhost:30001/health; do sleep 5; done' | |
| - name: Run E2E tests | |
| working-directory: ./frontend | |
| env: | |
| PLAYWRIGHT_BASE_URL: http://localhost:30000 | |
| run: npx playwright test | |
| - name: Upload Playwright report | |
| uses: actions/upload-artifact@v3 | |
| if: always() | |
| with: | |
| name: playwright-report | |
| path: frontend/playwright-report/ | |
| retention-days: 30 | |
| - name: Stop application | |
| if: always() | |
| run: | | |
| podman pod stop redhat-learning-paths || true | |
| podman pod rm redhat-learning-paths || true | |
| deploy-staging: | |
| name: Deploy to Staging | |
| runs-on: ubuntu-latest | |
| needs: [e2e-tests] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: | |
| name: staging | |
| url: https://staging.redhat-learning-paths.example.com | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Deploy to staging | |
| run: | | |
| echo "Deploying to staging environment..." | |
| echo "Image tags: ${{ github.sha }}" | |
| # Add your staging deployment steps here | |
| # This could include updating Kubernetes manifests, | |
| # triggering deployment pipelines, etc. | |
| notification: | |
| name: Notification | |
| runs-on: ubuntu-latest | |
| needs: [test-backend, test-frontend, lint-and-format, security-scan] | |
| if: always() | |
| steps: | |
| - name: Notify on success | |
| if: ${{ needs.test-backend.result == 'success' && needs.test-frontend.result == 'success' && needs.lint-and-format.result == 'success' }} | |
| run: | | |
| echo "✅ All checks passed successfully!" | |
| - name: Notify on failure | |
| if: ${{ needs.test-backend.result == 'failure' || needs.test-frontend.result == 'failure' || needs.lint-and-format.result == 'failure' || needs.security-scan.result == 'failure' }} | |
| run: | | |
| echo "❌ Some checks failed. Please review the logs." | |
| exit 1 |