Complete 6 Sprint 1 stories for Epic 1 web migration infrastructure. Portfolio Collection: - Add 7 fields: title, slug, url, image, description, websiteType, tags - Configure R2 storage and authenticated access control Categories Collection: - Add nameEn, order, textColor, backgroundColor fields - Add color picker UI configuration Posts Collection: - Add excerpt with 200 char limit and ogImage for social sharing - Add showInFooter checkbox and status select (draft/review/published) Role-Based Access Control: - Add role field to Users collection (admin/editor) - Create adminOnly and authenticated access functions - Apply access rules to Portfolio, Categories, Posts, Users collections Audit Logging System (NFR9): - Create Audit collection with timestamps for 90-day retention - Add auditLogger utility for login/logout/content change tracking - Add auditChange and auditGlobalChange hooks to all collections and globals - Add cleanupAuditLogs job with 90-day retention policy Load Testing Framework (NFR4): - Add k6 load testing with 3 scripts: public-browsing, admin-operations, api-performance - Configure targets: p95 < 500ms, error rate < 1%, 100 concurrent users - Add verification script and comprehensive documentation Other Changes: - Remove unused Form blocks - Add Header/Footer audit hooks - Regenerate Payload TypeScript types
155 lines
4.6 KiB
YAML
155 lines
4.6 KiB
YAML
# K6 Load Testing - GitHub Actions Workflow Example
|
|
# Copy this to .github/workflows/load-tests.yml
|
|
|
|
name: Load Tests
|
|
|
|
on:
|
|
# Run daily at 2 AM UTC
|
|
schedule:
|
|
- cron: '0 2 * * *'
|
|
|
|
# Run on demand
|
|
workflow_dispatch:
|
|
|
|
# Run after deployment to staging
|
|
workflow_run:
|
|
workflows: ["Deploy to Staging"]
|
|
types:
|
|
- completed
|
|
|
|
jobs:
|
|
public-browsing:
|
|
name: Public Browsing (100 users)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup k6
|
|
run: |
|
|
curl https://github.com/grafana/k6/releases/download/v0.51.0/k6-v0.51.0-linux-amd64.tar.gz -L | tar xvz
|
|
sudo mv k6-v0.51.0-linux-amd64/k6 /usr/local/bin/
|
|
|
|
- name: Wait for server
|
|
run: |
|
|
echo "Waiting for server to be ready..."
|
|
timeout 60 bash -c 'until curl -sSf ${{ vars.STAGING_URL }} > /dev/null; do sleep 2; done'
|
|
echo "Server is ready!"
|
|
|
|
- name: Run Public Browsing Test
|
|
run: |
|
|
k6 run \
|
|
--env BASE_URL=${{ vars.STAGING_URL }} \
|
|
--out json=public-browsing-results.json \
|
|
apps/backend/tests/k6/public-browsing.js
|
|
|
|
- name: Upload Results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: public-browsing-results
|
|
path: public-browsing-results.json
|
|
retention-days: 30
|
|
|
|
api-performance:
|
|
name: API Performance (50 users)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup k6
|
|
run: |
|
|
curl https://github.com/grafana/k6/releases/download/v0.51.0/k6-v0.51.0-linux-amd64.tar.gz -L | tar xvz
|
|
sudo mv k6-v0.51.0-linux-amd64/k6 /usr/local/bin/
|
|
|
|
- name: Run API Performance Test
|
|
run: |
|
|
k6 run \
|
|
--env BASE_URL=${{ vars.STAGING_URL }} \
|
|
--out json=api-performance-results.json \
|
|
apps/backend/tests/k6/api-performance.js
|
|
|
|
- name: Upload Results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: api-performance-results
|
|
path: api-performance-results.json
|
|
retention-days: 30
|
|
|
|
admin-operations:
|
|
name: Admin Operations (20 users)
|
|
runs-on: ubuntu-latest
|
|
# Only run on manual trigger or schedule, not on every deployment
|
|
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup k6
|
|
run: |
|
|
curl https://github.com/grafana/k6/releases/download/v0.51.0/k6-v0.51.0-linux-amd64.tar.gz -L | tar xvz
|
|
sudo mv k6-v0.51.0-linux-amd64/k6 /usr/local/bin/
|
|
|
|
- name: Run Admin Operations Test
|
|
run: |
|
|
k6 run \
|
|
--env BASE_URL=${{ vars.STAGING_URL }} \
|
|
--env ADMIN_EMAIL=${{ secrets.TEST_ADMIN_EMAIL }} \
|
|
--env ADMIN_PASSWORD=${{ secrets.TEST_ADMIN_PASSWORD }} \
|
|
--out json=admin-operations-results.json \
|
|
apps/backend/tests/k6/admin-operations.js
|
|
env:
|
|
# Don't log passwords
|
|
K6_NO_LOG_USAGE: true
|
|
|
|
- name: Upload Results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: admin-operations-results
|
|
path: admin-operations-results.json
|
|
retention-days: 30
|
|
|
|
# Optional: Generate and publish HTML reports
|
|
generate-reports:
|
|
name: Generate HTML Reports
|
|
needs: [public-browsing, api-performance]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Download Results
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: results
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Install k6-reporter
|
|
run: npm install -g k6-reporter
|
|
|
|
- name: Generate Reports
|
|
run: |
|
|
mkdir -p reports
|
|
k6-reporter results/public-browsing-results/public-browsing-results.json --output reports/public-browsing.html
|
|
k6-reporter results/api-performance-results/api-performance-results.json --output reports/api-performance.html
|
|
|
|
- name: Upload Reports
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: html-reports
|
|
path: reports/
|
|
retention-days: 30
|
|
|
|
- name: Comment PR with Results
|
|
if: github.event_name == 'pull_request'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
const publicReport = fs.readFileSync('reports/public-browsing.html', 'utf8');
|
|
// Add comment to PR with summary...
|