add support for docker image push #36
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: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main ] | |
| env: | |
| NODE_VERSION: '20' | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| # Code Quality Checks | |
| quality: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run linter | |
| run: npm run lint | |
| - name: Run type check | |
| run: npm run typecheck | |
| - name: Run format check | |
| run: npm run format:check || true | |
| # Security Scanning | |
| security: | |
| 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 results to GitHub Security | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| # Unit Tests | |
| test: | |
| name: Unit Tests | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: testpassword | |
| POSTGRES_DB: snapdocs_test | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| mongodb: | |
| image: mongo:7.0 | |
| env: | |
| MONGO_INITDB_ROOT_USERNAME: admin | |
| MONGO_INITDB_ROOT_PASSWORD: testpassword | |
| MONGO_INITDB_DATABASE: snapdocs_test | |
| options: >- | |
| --health-cmd "echo 'db.runCommand(\"ping\").ok' | mongosh localhost:27017/test --quiet" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 27017:27017 | |
| redis: | |
| image: redis:7-alpine | |
| 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: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Setup test environment | |
| run: | | |
| cp .env.example .env.test | |
| echo "DATABASE_URL=postgresql://postgres:testpassword@localhost:5432/snapdocs_test" >> .env.test | |
| echo "MONGODB_URI=mongodb://admin:testpassword@localhost:27017/snapdocs_test?authSource=admin" >> .env.test | |
| echo "REDIS_URL=redis://localhost:6379" >> .env.test | |
| - name: Run Prisma migrations | |
| run: npx prisma migrate deploy | |
| env: | |
| DATABASE_URL: postgresql://postgres:testpassword@localhost:5432/snapdocs_test | |
| - name: Run tests | |
| run: npm test -- --passWithNoTests | |
| env: | |
| NODE_ENV: test | |
| DATABASE_URL: postgresql://postgres:testpassword@localhost:5432/snapdocs_test | |
| MONGODB_URI: mongodb://admin:testpassword@localhost:27017/snapdocs_test?authSource=admin | |
| REDIS_URL: redis://localhost:6379 | |
| # Build Docker Image | |
| build: | |
| name: Build Docker Image | |
| runs-on: ubuntu-latest | |
| needs: [quality, security, test] | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') | |
| 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 GitHub 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=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| 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 | |
| build-args: | | |
| BUILDKIT_CONTEXT_KEEP_GIT_DIR=true | |
| # Deploy to Staging | |
| deploy-staging: | |
| name: Deploy to Staging | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.ref == 'refs/heads/develop' | |
| environment: | |
| name: staging | |
| url: https://staging.snapdocs.app | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Deploy to staging server | |
| run: | | |
| echo "Deploying to staging environment" | |
| # Add your deployment script here | |
| # Example: SSH to server and run docker-compose | |
| # Or trigger webhook to deployment service | |
| # Deploy to Production | |
| deploy-production: | |
| name: Deploy to Production | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.ref == 'refs/heads/main' | |
| environment: | |
| name: production | |
| url: https://snapdocs.app | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Deploy to production server | |
| run: | | |
| echo "Deploying to production environment" | |
| # Add your deployment script here | |
| # Example: SSH to server and run docker-compose | |
| # Or trigger webhook to deployment service | |
| # Notify on Success | |
| notify-success: | |
| name: Notify Success | |
| runs-on: ubuntu-latest | |
| needs: [deploy-staging, deploy-production] | |
| if: always() && (needs.deploy-staging.result == 'success' || needs.deploy-production.result == 'success') | |
| steps: | |
| - name: Send success notification | |
| run: | | |
| echo "Deployment successful!" | |
| # Add notification logic here (Slack, Discord, email, etc.) |