-
Notifications
You must be signed in to change notification settings - Fork 0
feat: platform features — SSO, billing, plan enforcement, audit log, chaos tests, Redis cluster #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 22 commits
3e4ac3e
8add219
df26ff1
e99ccc6
a1a55bf
2534b86
5bd9de3
051c9c1
cc5821a
8a3cd47
d74331e
59516d4
684c6c9
aaf4d9f
4d7bf73
143bdf7
ad6f5f0
588db81
9131353
1d029d6
2f05a66
4a25f89
b9b80f8
3760621
96f2d63
cad477d
6cdbc10
7b23185
21e79c0
3c997c6
dd513d2
e18f67b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| name: Chaos Tests | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| experiment: | ||
| description: 'Experiment to run' | ||
| required: true | ||
| default: all | ||
| type: choice | ||
| options: | ||
| - all | ||
| - pod-kill | ||
| - kafka-consumer-pause | ||
| - redis-outage | ||
| - projection-lag | ||
| - network-partition | ||
| namespace: | ||
| description: 'Target namespace' | ||
| required: true | ||
| default: grainguard-dev | ||
| schedule: | ||
| # Run full suite every Saturday at 02:00 UTC (off-peak) | ||
| - cron: '0 2 * * 6' | ||
|
|
||
| env: | ||
| NAMESPACE: ${{ github.event.inputs.namespace || 'grainguard-dev' }} | ||
|
|
||
| jobs: | ||
| chaos: | ||
| name: Chaos — ${{ github.event.inputs.experiment || 'all' }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Configure kubectl | ||
| uses: azure/setup-kubectl@v3 | ||
| with: | ||
| version: 'v1.29.0' | ||
|
|
||
| - name: Set kubeconfig | ||
| run: | | ||
| mkdir -p $HOME/.kube | ||
| echo "${{ secrets.KUBECONFIG_DEV }}" | base64 -d > $HOME/.kube/config | ||
| chmod 600 $HOME/.kube/config | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| - name: Install Chaos Toolkit | ||
| run: | | ||
| pip install --quiet \ | ||
| chaostoolkit==1.19.0 \ | ||
| chaostoolkit-kubernetes==0.26.4 \ | ||
| chaostoolkit-verification==0.3.0 | ||
|
|
||
| - name: Make scripts executable | ||
| run: chmod +x tests/chaos/*.sh | ||
|
|
||
| - name: Run — all experiments | ||
| if: ${{ github.event.inputs.experiment == 'all' || github.event_name == 'schedule' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| KAFKA_BOOTSTRAP: kafka:9092 | ||
| GATEWAY_URL: ${{ secrets.CHAOS_GATEWAY_URL }} | ||
| PROMETHEUS_URL: ${{ secrets.CHAOS_PROMETHEUS_URL }} | ||
| TEST_JWT: ${{ secrets.CHAOS_TEST_JWT }} | ||
| run: bash tests/chaos/run-all.sh | ||
|
|
||
| - name: Run — pod-kill | ||
| if: ${{ github.event.inputs.experiment == 'pod-kill' }} | ||
| run: chaos run tests/chaos/pod-kill.yaml | ||
|
|
||
| - name: Run — kafka-consumer-pause | ||
| if: ${{ github.event.inputs.experiment == 'kafka-consumer-pause' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| KAFKA_BOOTSTRAP: kafka:9092 | ||
| run: bash tests/chaos/kafka-consumer-pause.sh | ||
|
|
||
| - name: Run — redis-outage | ||
| if: ${{ github.event.inputs.experiment == 'redis-outage' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| GATEWAY_URL: ${{ secrets.CHAOS_GATEWAY_URL }} | ||
| TEST_JWT: ${{ secrets.CHAOS_TEST_JWT }} | ||
| run: bash tests/chaos/redis-outage.sh | ||
|
|
||
| - name: Run — projection-lag | ||
| if: ${{ github.event.inputs.experiment == 'projection-lag' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| KAFKA_BOOTSTRAP: kafka:9092 | ||
| PROMETHEUS_URL: ${{ secrets.CHAOS_PROMETHEUS_URL }} | ||
| run: bash tests/chaos/projection-lag.sh | ||
|
|
||
| - name: Run — network-partition | ||
| if: ${{ github.event.inputs.experiment == 'network-partition' }} | ||
| run: chaos run tests/chaos/network-partition.yaml | ||
|
|
||
| - name: Upload chaos logs | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: chaos-results-${{ github.run_number }} | ||
| path: tests/chaos/results/ | ||
| retention-days: 30 | ||
|
|
||
| - name: Notify Slack on failure | ||
| if: failure() | ||
| uses: slackapi/slack-github-action@v1.26.0 | ||
| with: | ||
| payload: | | ||
| { | ||
| "text": ":fire: Chaos experiment *${{ github.event.inputs.experiment || 'all' }}* FAILED on `${{ env.NAMESPACE }}` — <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>" | ||
| } | ||
| env: | ||
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CHAOS_WEBHOOK }} | ||
| SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,74 @@ | ||||||||||||||||||||||||||||||||||||||
| name: E2E Tests | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||
| branches: [master] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||
| e2e: | ||||||||||||||||||||||||||||||||||||||
| name: Playwright E2E | ||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||
| timeout-minutes: 20 | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+12
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find .github -name "e2e.yml" -o -name "e2e.yaml" | head -20Repository: pahuldeepp/GrainGuard- Length of output: 91 🏁 Script executed: cat -n .github/workflows/e2e.ymlRepository: pahuldeepp/GrainGuard- Length of output: 2840 Skip this job when required secrets are missing. This job runs on every 💡 Suggested fix jobs:
e2e:
name: Playwright E2E
runs-on: ubuntu-latest
timeout-minutes: 20
+ if: ${{ secrets.VITE_AUTH0_DOMAIN != '' && secrets.VITE_AUTH0_CLIENT_ID != '' && secrets.VITE_AUTH0_AUDIENCE != '' && secrets.E2E_BFF_URL != '' && secrets.E2E_GATEWAY_URL != '' }}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Set up Node.js | ||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v4 | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| node-version: "20" | ||||||||||||||||||||||||||||||||||||||
| cache: npm | ||||||||||||||||||||||||||||||||||||||
| cache-dependency-path: apps/dashboard/package-lock.json | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Install dashboard deps | ||||||||||||||||||||||||||||||||||||||
| run: npm ci | ||||||||||||||||||||||||||||||||||||||
| working-directory: apps/dashboard | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Install E2E deps | ||||||||||||||||||||||||||||||||||||||
| run: npm install --save-dev @playwright/test typescript ts-node | ||||||||||||||||||||||||||||||||||||||
| working-directory: tests/e2e | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Install Playwright browsers | ||||||||||||||||||||||||||||||||||||||
| run: npx playwright install --with-deps chromium firefox | ||||||||||||||||||||||||||||||||||||||
| working-directory: tests/e2e | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Build dashboard | ||||||||||||||||||||||||||||||||||||||
| run: npm run build | ||||||||||||||||||||||||||||||||||||||
| working-directory: apps/dashboard | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| VITE_AUTH0_DOMAIN: ${{ secrets.VITE_AUTH0_DOMAIN }} | ||||||||||||||||||||||||||||||||||||||
| VITE_AUTH0_CLIENT_ID: ${{ secrets.VITE_AUTH0_CLIENT_ID }} | ||||||||||||||||||||||||||||||||||||||
| VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }} | ||||||||||||||||||||||||||||||||||||||
| VITE_BFF_URL: ${{ secrets.E2E_BFF_URL }} | ||||||||||||||||||||||||||||||||||||||
| VITE_GATEWAY_URL: ${{ secrets.E2E_GATEWAY_URL }} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Fix YAML formatting: extra spaces after colons. YAMLlint reports formatting errors on lines 43-47. While this doesn't affect functionality, it violates YAML style conventions. ♻️ Proposed fix - name: Build dashboard
run: npm run build
working-directory: apps/dashboard
env:
- VITE_AUTH0_DOMAIN: ${{ secrets.VITE_AUTH0_DOMAIN }}
- VITE_AUTH0_CLIENT_ID: ${{ secrets.VITE_AUTH0_CLIENT_ID }}
- VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }}
- VITE_BFF_URL: ${{ secrets.E2E_BFF_URL }}
- VITE_GATEWAY_URL: ${{ secrets.E2E_GATEWAY_URL }}
+ VITE_AUTH0_DOMAIN: ${{ secrets.VITE_AUTH0_DOMAIN }}
+ VITE_AUTH0_CLIENT_ID: ${{ secrets.VITE_AUTH0_CLIENT_ID }}
+ VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }}
+ VITE_BFF_URL: ${{ secrets.E2E_BFF_URL }}
+ VITE_GATEWAY_URL: ${{ secrets.E2E_GATEWAY_URL }}📝 Committable suggestion
Suggested change
🧰 Tools🪛 YAMLlint (1.38.0)[error] 43-43: too many spaces after colon (colons) [error] 45-45: too many spaces after colon (colons) [error] 46-46: too many spaces after colon (colons) [error] 47-47: too many spaces after colon (colons) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| - name: Serve dashboard | ||||||||||||||||||||||||||||||||||||||
| run: npx serve -s dist -l 5173 & | ||||||||||||||||||||||||||||||||||||||
| working-directory: apps/dashboard | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Wait for server | ||||||||||||||||||||||||||||||||||||||
| run: npx wait-on http://localhost:5173 --timeout 30000 | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Run Playwright tests | ||||||||||||||||||||||||||||||||||||||
| run: npx playwright test --config playwright.config.ts | ||||||||||||||||||||||||||||||||||||||
| working-directory: tests/e2e | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| E2E_BASE_URL: http://localhost:5173 | ||||||||||||||||||||||||||||||||||||||
| VITE_AUTH0_CLIENT_ID: ${{ secrets.VITE_AUTH0_CLIENT_ID }} | ||||||||||||||||||||||||||||||||||||||
| VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+56
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Fix YAML formatting in test step environment variables. ♻️ Proposed fix - name: Run Playwright tests
run: npx playwright test --config playwright.config.ts
working-directory: tests/e2e
env:
- E2E_BASE_URL: http://localhost:5173
+ E2E_BASE_URL: http://localhost:5173
VITE_AUTH0_CLIENT_ID: ${{ secrets.VITE_AUTH0_CLIENT_ID }}
- VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }}
+ VITE_AUTH0_AUDIENCE: ${{ secrets.VITE_AUTH0_AUDIENCE }}📝 Committable suggestion
Suggested change
🧰 Tools🪛 YAMLlint (1.38.0)[error] 60-60: too many spaces after colon (colons) [error] 62-62: too many spaces after colon (colons) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| - name: Upload Playwright report | ||||||||||||||||||||||||||||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| name: playwright-report-${{ github.run_number }} | ||||||||||||||||||||||||||||||||||||||
| path: tests/e2e/playwright-report/ | ||||||||||||||||||||||||||||||||||||||
| retention-days: 14 | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Upload test results (JUnit) | ||||||||||||||||||||||||||||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| name: playwright-results-${{ github.run_number }} | ||||||||||||||||||||||||||||||||||||||
| path: tests/e2e/playwright-results.xml | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| name: Performance Budget | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master] | ||
| paths: | ||
| - "apps/gateway/**" | ||
| - "apps/bff/**" | ||
| - "scripts/load-tests/**" | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| jobs: | ||
| perf: | ||
| name: k6 Performance Budget | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
|
|
||
| services: | ||
| # Spin up the gateway and BFF as Docker Compose services | ||
| # so k6 can hit them without needing a live cluster | ||
| postgres: | ||
| image: postgres:16-alpine | ||
| env: | ||
| POSTGRES_USER: grainguard | ||
| POSTGRES_PASSWORD: grainguard | ||
| POSTGRES_DB: grainguard | ||
| options: >- | ||
| --health-cmd pg_isready | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 | ||
|
|
||
| redis: | ||
| image: redis:7-alpine | ||
| options: >- | ||
| --health-cmd "redis-cli ping" | ||
| --health-interval 10s | ||
| --health-retries 5 | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
| cache: npm | ||
| cache-dependency-path: apps/gateway/package-lock.json | ||
|
|
||
| - name: Install gateway deps | ||
| run: npm ci | ||
| working-directory: apps/gateway | ||
|
|
||
| - name: Start gateway in background | ||
| run: npx ts-node src/server.ts & | ||
| working-directory: apps/gateway | ||
|
Comment on lines
+67
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Background processes lack explicit cleanup, but acceptable for CI. Both the gateway and BFF are started with Consider adding a cleanup step or using a process manager like Also applies to: 98-100 🤖 Prompt for AI Agents |
||
| env: | ||
| PORT: 3000 | ||
| DATABASE_URL: postgres://grainguard:grainguard@localhost:5432/grainguard | ||
| REDIS_URL: redis://localhost:6379 | ||
| JWKS_URL: ${{ secrets.PERF_JWKS_URL }} | ||
| JWT_ISSUER: ${{ secrets.PERF_JWT_ISSUER }} | ||
| JWT_AUDIENCE: ${{ secrets.PERF_JWT_AUDIENCE }} | ||
| ALLOWED_ORIGINS: http://localhost:5173 | ||
| STRIPE_SECRET_KEY: sk_test_placeholder | ||
| STRIPE_WEBHOOK_SECRET: whsec_placeholder | ||
| STRIPE_PRICE_STARTER: price_placeholder | ||
| STRIPE_PRICE_PROFESSIONAL: price_placeholder | ||
| STRIPE_PRICE_ENTERPRISE: price_placeholder | ||
| DASHBOARD_URL: http://localhost:5173 | ||
| AUTH0_DOMAIN: placeholder.auth0.com | ||
| AUTH0_MANAGEMENT_CLIENT_ID: placeholder | ||
| AUTH0_MANAGEMENT_CLIENT_SECRET: placeholder | ||
|
|
||
| - name: Wait for gateway | ||
| run: npx wait-on http://localhost:3000/health --timeout 30000 | ||
|
|
||
| - name: Install k6 | ||
| run: | | ||
| curl -L https://github.com/grafana/k6/releases/download/v0.51.0/k6-v0.51.0-linux-amd64.tar.gz | tar xz | ||
| sudo mv k6-v0.51.0-linux-amd64/k6 /usr/local/bin/k6 | ||
|
|
||
| - name: Run performance budget | ||
| run: | | ||
| k6 run \ | ||
| --env GATEWAY_URL=http://localhost:3000 \ | ||
| --env BFF_URL=http://localhost:4000 \ | ||
| scripts/load-tests/performance-budget.js | ||
| # k6 exits 99 if thresholds are breached — this step fails and blocks the PR | ||
|
|
||
| - name: Upload performance results | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: perf-results-${{ github.run_number }} | ||
| path: scripts/load-tests/results/ | ||
| retention-days: 30 | ||
Uh oh!
There was an error while loading. Please reload this page.