|
| 1 | +# name: Reflect CI/CD Pipeline |
| 2 | + |
| 3 | +# on: |
| 4 | +# push: |
| 5 | +# branches: [main, develop] |
| 6 | +# pull_request: |
| 7 | +# branches: [main, develop] |
| 8 | + |
| 9 | +# env: |
| 10 | +# REGISTRY: ghcr.io |
| 11 | +# IMAGE_NAME: ${{ github.repository }} |
| 12 | + |
| 13 | +# jobs: |
| 14 | +# # Backend Testing & Linting |
| 15 | +# backend-test: |
| 16 | +# runs-on: ubuntu-latest |
| 17 | +# defaults: |
| 18 | +# run: |
| 19 | +# working-directory: ./ |
| 20 | + |
| 21 | +# steps: |
| 22 | +# - uses: actions/checkout@v4 |
| 23 | + |
| 24 | +# - name: Set up Python 3.12 |
| 25 | +# uses: actions/setup-python@v4 |
| 26 | +# with: |
| 27 | +# python-version: '3.12' |
| 28 | + |
| 29 | +# - name: Install UV |
| 30 | +# run: pip install uv |
| 31 | + |
| 32 | +# - name: Install dependencies |
| 33 | +# run: uv sync --frozen |
| 34 | + |
| 35 | +# - name: Lint with Ruff |
| 36 | +# run: uv run ruff check . |
| 37 | +# continue-on-error: true |
| 38 | + |
| 39 | +# - name: Format check with Ruff |
| 40 | +# run: uv run ruff format --check . |
| 41 | +# continue-on-error: true |
| 42 | + |
| 43 | +# - name: Type checking with Mypy |
| 44 | +# run: uv run mypy app --ignore-missing-imports |
| 45 | +# continue-on-error: true |
| 46 | + |
| 47 | +# - name: Run pytest |
| 48 | +# run: uv run pytest tests/ -v --cov=app --cov-report=xml |
| 49 | +# continue-on-error: true |
| 50 | + |
| 51 | +# - name: Upload coverage reports |
| 52 | +# uses: codecov/codecov-action@v3 |
| 53 | +# with: |
| 54 | +# file: ./coverage.xml |
| 55 | +# fail_ci_if_error: false |
| 56 | + |
| 57 | +# # Frontend Testing & Build |
| 58 | +# frontend-test: |
| 59 | +# runs-on: ubuntu-latest |
| 60 | +# defaults: |
| 61 | +# run: |
| 62 | +# working-directory: ./frontend |
| 63 | + |
| 64 | +# steps: |
| 65 | +# - uses: actions/checkout@v4 |
| 66 | + |
| 67 | +# - name: Set up Node.js |
| 68 | +# uses: actions/setup-node@v4 |
| 69 | +# with: |
| 70 | +# node-version: '18' |
| 71 | +# cache: 'npm' |
| 72 | + |
| 73 | +# - name: Install dependencies |
| 74 | +# run: npm ci |
| 75 | + |
| 76 | +# - name: Lint with ESLint |
| 77 | +# run: npm run lint |
| 78 | +# continue-on-error: true |
| 79 | + |
| 80 | +# - name: Build PWA |
| 81 | +# run: npm run build |
| 82 | + |
| 83 | +# - name: Run Vitest |
| 84 | +# run: npm run test |
| 85 | +# continue-on-error: true |
| 86 | + |
| 87 | +# - name: Check PWA bundle size |
| 88 | +# run: | |
| 89 | +# SIZE=$(du -sh dist/ | cut -f1) |
| 90 | +# echo "PWA Bundle Size: $SIZE" |
| 91 | +# if [ $(du -s dist/ | cut -f1) -gt 1024 ]; then |
| 92 | +# echo "Warning: Bundle size exceeds 1MB" |
| 93 | +# fi |
| 94 | + |
| 95 | +# # Security Scanning |
| 96 | +# security-scan: |
| 97 | +# runs-on: ubuntu-latest |
| 98 | + |
| 99 | +# steps: |
| 100 | +# - uses: actions/checkout@v4 |
| 101 | + |
| 102 | +# - name: Run Trivy vulnerability scan |
| 103 | +# uses: aquasecurity/trivy-action@master |
| 104 | +# with: |
| 105 | +# scan-type: 'fs' |
| 106 | +# scan-ref: '.' |
| 107 | +# format: 'sarif' |
| 108 | +# output: 'trivy-results.sarif' |
| 109 | + |
| 110 | +# - name: Upload Trivy results |
| 111 | +# uses: github/codeql-action/upload-sarif@v2 |
| 112 | +# with: |
| 113 | +# sarif_file: 'trivy-results.sarif' |
| 114 | + |
| 115 | +# # Docker Build & Test |
| 116 | +# docker-build: |
| 117 | +# needs: [backend-test, frontend-test, security-scan] |
| 118 | +# runs-on: ubuntu-latest |
| 119 | + |
| 120 | +# permissions: |
| 121 | +# contents: read |
| 122 | +# packages: write |
| 123 | + |
| 124 | +# steps: |
| 125 | +# - uses: actions/checkout@v4 |
| 126 | + |
| 127 | +# - name: Set up Docker Buildx |
| 128 | +# uses: docker/setup-buildx-action@v2 |
| 129 | + |
| 130 | +# - name: Log in to Container Registry |
| 131 | +# uses: docker/login-action@v2 |
| 132 | +# with: |
| 133 | +# registry: ${{ env.REGISTRY }} |
| 134 | +# username: ${{ github.actor }} |
| 135 | +# password: ${{ secrets.GITHUB_TOKEN }} |
| 136 | + |
| 137 | +# - name: Extract metadata |
| 138 | +# id: meta |
| 139 | +# uses: docker/metadata-action@v4 |
| 140 | +# with: |
| 141 | +# images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} |
| 142 | +# tags: | |
| 143 | +# type=ref,event=branch |
| 144 | +# type=semver,pattern={{version}} |
| 145 | +# type=semver,pattern={{major}}.{{minor}} |
| 146 | +# type=sha |
| 147 | + |
| 148 | +# - name: Build and push Docker image |
| 149 | +# uses: docker/build-push-action@v4 |
| 150 | +# with: |
| 151 | +# context: . |
| 152 | +# push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} |
| 153 | +# tags: ${{ steps.meta.outputs.tags }} |
| 154 | +# labels: ${{ steps.meta.outputs.labels }} |
| 155 | +# cache-from: type=gha |
| 156 | +# cache-to: type=gha,mode=max |
| 157 | + |
| 158 | +# - name: Test Docker image |
| 159 | +# run: | |
| 160 | +# docker build -t reflect:test . |
| 161 | +# docker run --rm reflect:test python --version |
| 162 | +# docker run --rm reflect:test uv --version |
| 163 | + |
| 164 | +# # Integration Tests |
| 165 | +# integration-test: |
| 166 | +# needs: docker-build |
| 167 | +# runs-on: ubuntu-latest |
| 168 | + |
| 169 | +# services: |
| 170 | +# backend: |
| 171 | +# image: reflect:test |
| 172 | +# options: >- |
| 173 | +# --health-cmd="curl -f http://localhost:8000/health || exit 1" |
| 174 | +# --health-interval=10s |
| 175 | +# --health-timeout=5s |
| 176 | +# --health-retries=5 |
| 177 | +# ports: |
| 178 | +# - 8000:8000 |
| 179 | + |
| 180 | +# steps: |
| 181 | +# - uses: actions/checkout@v4 |
| 182 | + |
| 183 | +# - name: Wait for backend to be ready |
| 184 | +# run: | |
| 185 | +# for i in {1..30}; do |
| 186 | +# curl -f http://localhost:8000/health && break |
| 187 | +# echo "Waiting for backend..." |
| 188 | +# sleep 2 |
| 189 | +# done |
| 190 | + |
| 191 | +# - name: Run E2E tests with Cypress |
| 192 | +# uses: cypress-io/github-action@v5 |
| 193 | +# with: |
| 194 | +# spec: cypress/e2e/**/*.cy.js |
| 195 | +# config-file: cypress.config.js |
| 196 | +# continue-on-error: true |
| 197 | + |
| 198 | +# # Deploy to Render (Main branch only) |
| 199 | +# deploy: |
| 200 | +# needs: [backend-test, frontend-test, docker-build, integration-test] |
| 201 | +# runs-on: ubuntu-latest |
| 202 | +# if: github.ref == 'refs/heads/main' && github.event_name == 'push' |
| 203 | + |
| 204 | +# steps: |
| 205 | +# - uses: actions/checkout@v4 |
| 206 | + |
| 207 | +# - name: Trigger Render deployment |
| 208 | +# run: | |
| 209 | +# curl --request POST \ |
| 210 | +# --url https://api.render.com/deploy/srv-${{ secrets.RENDER_SERVICE_ID }}?key=${{ secrets.RENDER_API_KEY }} \ |
| 211 | +# --header 'Content-Type: application/json' |
| 212 | + |
| 213 | +# - name: Notify deployment |
| 214 | +# run: | |
| 215 | +# echo "✅ Deployment triggered to Render" |
| 216 | +# echo "Monitor at: https://dashboard.render.com" |
| 217 | + |
| 218 | +# # Create GitHub Release (on tag) |
| 219 | +# release: |
| 220 | +# needs: deploy |
| 221 | +# runs-on: ubuntu-latest |
| 222 | +# if: startsWith(github.ref, 'refs/tags/') |
| 223 | + |
| 224 | +# steps: |
| 225 | +# - uses: actions/checkout@v4 |
| 226 | + |
| 227 | +# - name: Create Release |
| 228 | +# uses: actions/create-release@v1 |
| 229 | +# env: |
| 230 | +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 231 | +# with: |
| 232 | +# tag_name: ${{ github.ref }} |
| 233 | +# release_name: Release ${{ github.ref }} |
| 234 | +# body: | |
| 235 | +# Changes in this Release |
| 236 | +# - See commit history for details |
| 237 | +# draft: false |
| 238 | +# prerelease: false |
| 239 | + |
| 240 | +# # Notification |
| 241 | +# notify: |
| 242 | +# needs: [backend-test, frontend-test, docker-build, deploy] |
| 243 | +# runs-on: ubuntu-latest |
| 244 | +# if: always() |
| 245 | + |
| 246 | +# steps: |
| 247 | +# - name: Send Slack notification |
| 248 | +# uses: slackapi/slack-github-action@v1 |
| 249 | +# if: always() |
| 250 | +# with: |
| 251 | +# payload: | |
| 252 | +# { |
| 253 | +# "text": "Reflect CI/CD Pipeline: ${{ job.status }}", |
| 254 | +# "blocks": [ |
| 255 | +# { |
| 256 | +# "type": "section", |
| 257 | +# "text": { |
| 258 | +# "type": "mrkdwn", |
| 259 | +# "text": "*Reflect Deployment*\nBranch: ${{ github.ref }}\nStatus: ${{ job.status }}\nCommit: ${{ github.sha }}" |
| 260 | +# } |
| 261 | +# } |
| 262 | +# ] |
| 263 | +# } |
| 264 | +# env: |
| 265 | +# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} |
0 commit comments