Skip to content

Merge remote README and update GitHub URLs #1

Merge remote README and update GitHub URLs

Merge remote README and update GitHub URLs #1

Workflow file for this run

name: Smart Quiz App - CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# Code Quality and Security Checks
code-quality:
name: Code Quality & Security
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 black bandit safety
pip install -r server/requirements.txt
- name: Run Black code formatter check
run: black --check server/
- name: Run Flake8 linter
run: flake8 server/ --max-line-length=100 --exclude=migrations/
- name: Run Bandit security linter
run: bandit -r server/ -f json -o bandit-report.json || true
- name: Check for security vulnerabilities
run: safety check --json --output safety-report.json || true
- name: Upload security reports
uses: actions/upload-artifact@v3
with:
name: security-reports
path: |
bandit-report.json
safety-report.json
# Backend Testing
backend-tests:
name: Backend Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: test_password
POSTGRES_DB: test_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r server/requirements.txt
- name: Run backend tests
env:
DATABASE_URL: postgresql://postgres:test_password@localhost:5432/test_db
REDIS_HOST: localhost
FLASK_ENV: testing
SECRET_KEY: test-secret-key
JWT_SECRET_KEY: test-jwt-secret
run: |
cd server
python -m pytest tests/ -v --cov=. --cov-report=xml --cov-report=html
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
file: ./server/coverage.xml
flags: backend
name: backend-coverage
# Android Build and Test
android-build:
name: Android Build & Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Run Android lint
run: ./gradlew lintDebug
- name: Run unit tests
run: ./gradlew testDebugUnitTest
- name: Run instrumented tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
script: ./gradlew connectedDebugAndroidTest
- name: Build debug APK
run: ./gradlew assembleDebug
- name: Upload APK
uses: actions/upload-artifact@v3
with:
name: debug-apk
path: app/build/outputs/apk/debug/app-debug.apk
- name: Upload test reports
uses: actions/upload-artifact@v3
if: always()
with:
name: android-test-reports
path: |
app/build/reports/
app/build/test-results/
# Security Scanning
security-scan:
name: Security Scanning
runs-on: ubuntu-latest
needs: [code-quality]
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
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
# Build and Push Docker Images
build-and-push:
name: Build & Push Docker Images
runs-on: ubuntu-latest
needs: [backend-tests, android-build, security-scan]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Deploy to Staging
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: [build-and-push]
if: github.ref == 'refs/heads/develop'
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to staging server
uses: appleboy/[email protected]
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.STAGING_USER }}
key: ${{ secrets.STAGING_SSH_KEY }}
script: |
cd /opt/smartquiz-staging
docker-compose pull
docker-compose up -d
docker system prune -f
- name: Run health check
run: |
sleep 30
curl -f ${{ secrets.STAGING_URL }}/api/v1/health || exit 1
# Deploy to Production
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [build-and-push]
if: github.ref == 'refs/heads/main'
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to production server
uses: appleboy/[email protected]
with:
host: ${{ secrets.PRODUCTION_HOST }}
username: ${{ secrets.PRODUCTION_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
script: |
cd /opt/smartquiz-production
docker-compose pull
docker-compose up -d --no-deps backend
docker system prune -f
- name: Run production health check
run: |
sleep 60
curl -f ${{ secrets.PRODUCTION_URL }}/api/v1/health || exit 1
- name: Notify deployment success
uses: 8398a7/action-slack@v3
with:
status: success
text: 'Smart Quiz App deployed successfully to production! 🚀'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
# Performance Testing
performance-test:
name: Performance Testing
runs-on: ubuntu-latest
needs: [deploy-staging]
if: github.ref == 'refs/heads/develop'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run K6 performance tests
uses: grafana/[email protected]
with:
filename: tests/performance/load-test.js
env:
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
BASE_URL: ${{ secrets.STAGING_URL }}
- name: Upload performance results
uses: actions/upload-artifact@v3
with:
name: performance-results
path: results.json