managarten/.github/workflows/daily-tests.yml
Wuesteon 2186cb3518 🐛 fix(ci): use db:migrate instead of db:push for test databases
Critical fix based on test failure analysis:
- E2E tests need real migration SQL files to create tables
- db:push is for development schema sync only
- db:migrate runs tracked migrations with advisory locks

This fixes errors:
- relation "credits.balances" does not exist
- relation "referrals.codes" does not exist
- relation "auth.security_events" does not exist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-25 20:44:38 +01:00

319 lines
9.6 KiB
YAML

# Daily Test Execution - Simplified automated testing with Discord notifications
#
# Schedule: Runs daily at 2 AM UTC
# Manual Trigger: workflow_dispatch for on-demand test runs
# Features:
# - Integration tests (E2E flows)
# - mana-core-auth service tests with coverage
# - Database setup/teardown
# - Discord notifications (always sent on success or failure)
name: Daily Tests
on:
# Run daily at 2 AM UTC
schedule:
- cron: '0 2 * * *'
# Allow manual trigger
workflow_dispatch:
inputs:
coverage_threshold:
description: 'Minimum coverage percentage (default: 80)'
required: false
default: '80'
verbose:
description: 'Verbose test output'
type: boolean
required: false
default: false
concurrency:
group: daily-tests-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
PNPM_VERSION: '9.15.0'
COVERAGE_THRESHOLD: ${{ github.event.inputs.coverage_threshold || '80' }}
jobs:
# Job 1: Test mana-core-auth with coverage
test-mana-core-auth:
name: Test mana-core-auth
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: manacore
POSTGRES_PASSWORD: testpassword
POSTGRES_DB: manacore
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
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 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build dependencies
run: pnpm run build:packages
- name: Setup test database
working-directory: services/mana-core-auth
env:
DATABASE_URL: postgresql://manacore:testpassword@localhost:5432/manacore
run: pnpm run db:migrate
- name: Run tests with coverage
working-directory: services/mana-core-auth
env:
DATABASE_URL: postgresql://manacore:testpassword@localhost:5432/manacore
REDIS_URL: redis://localhost:6379
NODE_ENV: test
JWT_ISSUER: manacore
JWT_AUDIENCE: manacore
run: |
if [ "${{ github.event.inputs.verbose }}" = "true" ]; then
pnpm run test:cov --verbose
else
pnpm run test:cov
fi
- name: Upload coverage to artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-mana-core-auth
path: services/mana-core-auth/coverage
retention-days: 30
- name: Check coverage threshold
working-directory: services/mana-core-auth
run: |
if [ -f "coverage/coverage-summary.json" ]; then
COVERAGE=$(node -e "const c = require('./coverage/coverage-summary.json'); console.log(c.total.lines.pct)")
echo "Coverage for mana-core-auth: ${COVERAGE}%"
if (( $(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l) )); then
echo "::error::Coverage ${COVERAGE}% is below threshold ${COVERAGE_THRESHOLD}%"
exit 1
fi
fi
# Job 2: Integration tests (E2E flows)
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: manacore
POSTGRES_PASSWORD: testpassword
POSTGRES_DB: manacore
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
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 pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build dependencies
run: pnpm run build:packages
- name: Setup databases for integration tests
working-directory: services/mana-core-auth
env:
DATABASE_URL: postgresql://manacore:testpassword@localhost:5432/manacore
run: pnpm run db:migrate
- name: Run integration tests
env:
DATABASE_URL: postgresql://manacore:testpassword@localhost:5432/manacore
REDIS_URL: redis://localhost:6379
NODE_ENV: test
JWT_ISSUER: manacore
JWT_AUDIENCE: manacore
run: |
# Run auth integration tests
cd services/mana-core-auth
if [ -d "test/integration" ]; then
pnpm run test:e2e || pnpm run test -- test/integration
fi
- name: Upload integration test results
if: always()
uses: actions/upload-artifact@v4
with:
name: integration-test-results
path: services/mana-core-auth/test-results
retention-days: 30
# Job 3: Always send Discord notification (success or failure)
notify:
name: Discord Notification
needs: [test-mana-core-auth, test-integration]
if: always()
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download coverage summary
uses: actions/download-artifact@v4
with:
name: coverage-mana-core-auth
path: coverage-mana-core-auth
continue-on-error: true
- name: Check test results
id: check
run: |
# Check if both jobs succeeded
AUTH_STATUS="${{ needs.test-mana-core-auth.result }}"
INTEGRATION_STATUS="${{ needs.test-integration.result }}"
if [ "$AUTH_STATUS" = "success" ] && [ "$INTEGRATION_STATUS" = "success" ]; then
echo "success=true" >> $GITHUB_OUTPUT
else
echo "success=false" >> $GITHUB_OUTPUT
fi
- name: Prepare notification data
id: prepare
run: |
# Get workflow run URL
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "run_url=$RUN_URL" >> $GITHUB_OUTPUT
# Get coverage if available
if [ -f "coverage-mana-core-auth/coverage-summary.json" ]; then
COVERAGE=$(node -e "const c = require('./coverage-mana-core-auth/coverage-summary.json'); console.log(c.total.lines.pct)")
echo "coverage=${COVERAGE}%" >> $GITHUB_OUTPUT
else
echo "coverage=N/A" >> $GITHUB_OUTPUT
fi
# Get date
DATE=$(date +%Y-%m-%d)
echo "date=$DATE" >> $GITHUB_OUTPUT
- name: Send Discord notification
if: env.DISCORD_WEBHOOK_URL != ''
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
run: |
if [ "${{ steps.check.outputs.success }}" = "true" ]; then
TITLE="✅ Daily Tests Passed"
DESCRIPTION="All tests completed successfully!"
COLOR=3066993
else
TITLE="❌ Daily Tests Failed"
DESCRIPTION="Some tests failed. Please investigate."
COLOR=15158332
fi
curl -X POST "$DISCORD_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "{
\"username\": \"ManaCore CI/CD\",
\"avatar_url\": \"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png\",
\"embeds\": [{
\"title\": \"$TITLE\",
\"description\": \"$DESCRIPTION\",
\"color\": $COLOR,
\"fields\": [
{
\"name\": \"📅 Date\",
\"value\": \"${{ steps.prepare.outputs.date }}\",
\"inline\": true
},
{
\"name\": \"📊 Coverage\",
\"value\": \"${{ steps.prepare.outputs.coverage }}\",
\"inline\": true
},
{
\"name\": \"🧪 mana-core-auth\",
\"value\": \"${{ needs.test-mana-core-auth.result }}\",
\"inline\": true
},
{
\"name\": \"🔗 Integration Tests\",
\"value\": \"${{ needs.test-integration.result }}\",
\"inline\": true
},
{
\"name\": \"🔗 Workflow Run\",
\"value\": \"[View Details](${{ steps.prepare.outputs.run_url }})\",
\"inline\": false
}
],
\"footer\": {
\"text\": \"ManaCore Monorepo\"
},
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
}]
}"