-
Notifications
You must be signed in to change notification settings - Fork 0
Claude/elated lamarr #6
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 all commits
3e4ac3e
8add219
df26ff1
e99ccc6
a1a55bf
2534b86
5bd9de3
051c9c1
cc5821a
8a3cd47
d74331e
59516d4
684c6c9
aaf4d9f
4d7bf73
143bdf7
ad6f5f0
588db81
9131353
10fa6f1
8a97319
f53b589
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,125 @@ | ||
| 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" | ||
|
|
||
| - 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' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| 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 }} | ||
| STRICT_ALERT_CHECK: "1" | ||
| run: bash tests/chaos/projection-lag.sh | ||
|
|
||
| - name: Run — network-partition | ||
| if: ${{ github.event.inputs.experiment == 'network-partition' }} | ||
| env: | ||
| NAMESPACE: ${{ env.NAMESPACE }} | ||
| run: chaos run tests/chaos/network-partition.yaml | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| - 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 | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| if-no-files-found: ignore | ||
|
|
||
| - 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 | ||
|
|
||
| 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 }} | ||
|
|
||
| - 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 }} | ||
|
|
||
| - 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,129 @@ | ||
| name: Performance Budget | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master] | ||
| paths: | ||
| - "apps/gateway/**" | ||
| - "apps/bff/**" | ||
| - "scripts/load-tests/**" | ||
|
|
||
| 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 | ||
| ports: | ||
| - 5432:5432 | ||
| 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 | ||
| ports: | ||
| - 6379:6379 | ||
| 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: Install BFF deps | ||
| run: npm ci | ||
| working-directory: apps/bff | ||
|
|
||
| - name: Start gateway in background | ||
| run: npx ts-node src/server.ts & | ||
| working-directory: apps/gateway | ||
| 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: Start BFF in background | ||
| run: npx ts-node src/server.ts & | ||
| working-directory: apps/bff | ||
| env: | ||
| PORT: 4000 | ||
| POSTGRES_HOST: localhost | ||
| POSTGRES_PORT: 5432 | ||
| POSTGRES_USER: grainguard | ||
| POSTGRES_PASSWORD: grainguard | ||
| POSTGRES_DB: grainguard | ||
| REDIS_HOST: localhost | ||
| REDIS_PORT: 6379 | ||
| ELASTICSEARCH_URL: http://localhost:9200 | ||
| CASSANDRA_HOST: localhost | ||
| CASSANDRA_PORT: 9042 | ||
| AUTH0_DOMAIN: placeholder.auth0.com | ||
| AUTH0_AUDIENCE: placeholder | ||
| AUTH0_ORG_CLAIM: org_id | ||
| ALLOWED_ORIGINS: http://localhost:5173 | ||
| JWT_SECRET: dev-secret | ||
|
|
||
|
Comment on lines
+82
to
+102
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. BFF won't boot with this env block.
Suggested fix - name: Start BFF in background
run: npx ts-node src/server.ts &
working-directory: apps/bff
env:
PORT: 4000
+ JWKS_URL: ${{ secrets.PERF_JWKS_URL }}
+ JWT_ISSUER: ${{ secrets.PERF_JWT_ISSUER }}
+ JWT_AUDIENCE: ${{ secrets.PERF_JWT_AUDIENCE }}
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_USER: grainguard
POSTGRES_PASSWORD: grainguard
POSTGRES_DB: grainguard🤖 Prompt for AI Agents |
||
| - name: Wait for gateway | ||
| run: npx wait-on http://localhost:3000/health --timeout 30000 | ||
|
|
||
| - name: Wait for BFF | ||
| run: npx wait-on http://localhost:4000/graphql --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 | ||
|
Comment on lines
+114
to
+119
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. The perf step never exercises the secured endpoints.
Suggested fix - name: Run performance budget
run: |
k6 run \
--env GATEWAY_URL=http://localhost:3000 \
--env BFF_URL=http://localhost:4000 \
+ --env JWT=${{ secrets.PERF_JWT }} \
scripts/load-tests/performance-budget.js🤖 Prompt for AI Agents |
||
| # 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 | ||
| if-no-files-found: ignore | ||
Uh oh!
There was an error while loading. Please reload this page.