Some checks failed
Deploy to Test Environment / deploy-to-test (push) Has been cancelled
168 lines
6.6 KiB
YAML
168 lines
6.6 KiB
YAML
# .gitea/workflows/manual-redis-flush-prod.yml
|
|
#
|
|
# DANGER: This workflow is DESTRUCTIVE and intended for manual execution only.
|
|
# It will completely FLUSH the PRODUCTION Redis database (db 0).
|
|
# This will clear all BullMQ queues, sessions, caches, and any other Redis data.
|
|
#
|
|
name: Manual - Flush Production Redis
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
confirmation:
|
|
description: 'DANGER: This will FLUSH production Redis. Type "flush-production-redis" to confirm.'
|
|
required: true
|
|
default: 'do-not-run'
|
|
flush_type:
|
|
description: 'What to flush?'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- 'queues-only'
|
|
- 'entire-database'
|
|
default: 'queues-only'
|
|
|
|
jobs:
|
|
flush-redis:
|
|
runs-on: projectium.com # This job runs on your self-hosted Gitea runner.
|
|
|
|
env:
|
|
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD_PROD }}
|
|
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v3
|
|
with:
|
|
node-version: '20'
|
|
cache: 'npm'
|
|
cache-dependency-path: '**/package-lock.json'
|
|
|
|
- name: Install Dependencies
|
|
run: npm ci
|
|
|
|
- name: Validate Secrets
|
|
run: |
|
|
if [ -z "$REDIS_PASSWORD" ]; then
|
|
echo "ERROR: REDIS_PASSWORD_PROD secret is not set in Gitea repository settings."
|
|
exit 1
|
|
fi
|
|
echo "✅ Redis password secret is present."
|
|
|
|
- name: Verify Confirmation Phrase
|
|
run: |
|
|
if [ "${{ gitea.event.inputs.confirmation }}" != "flush-production-redis" ]; then
|
|
echo "ERROR: Confirmation phrase did not match. Aborting Redis flush."
|
|
exit 1
|
|
fi
|
|
echo "✅ Confirmation accepted. Proceeding with Redis flush."
|
|
|
|
- name: Show Current Redis State
|
|
run: |
|
|
echo "--- Current Redis Database 0 (Production) State ---"
|
|
redis-cli -a "$REDIS_PASSWORD" -n 0 INFO keyspace 2>/dev/null || echo "Could not get keyspace info"
|
|
echo ""
|
|
echo "--- Key Count ---"
|
|
KEY_COUNT=$(redis-cli -a "$REDIS_PASSWORD" -n 0 DBSIZE 2>/dev/null | grep -oE '[0-9]+' || echo "unknown")
|
|
echo "Production Redis (db 0) key count: $KEY_COUNT"
|
|
echo ""
|
|
echo "--- BullMQ Queue Keys ---"
|
|
redis-cli -a "$REDIS_PASSWORD" -n 0 KEYS "bull:*" 2>/dev/null | head -20 || echo "No BullMQ keys found"
|
|
|
|
- name: 🚨 FINAL WARNING & PAUSE 🚨
|
|
run: |
|
|
echo "*********************************************************************"
|
|
echo "WARNING: YOU ARE ABOUT TO FLUSH PRODUCTION REDIS DATA."
|
|
echo "Flush type: ${{ gitea.event.inputs.flush_type }}"
|
|
echo ""
|
|
if [ "${{ gitea.event.inputs.flush_type }}" = "entire-database" ]; then
|
|
echo "This will DELETE ALL Redis data including sessions, caches, and queues!"
|
|
else
|
|
echo "This will DELETE ALL BullMQ queue data (pending jobs, failed jobs, etc.)"
|
|
fi
|
|
echo ""
|
|
echo "This action is IRREVERSIBLE. Press Ctrl+C in the runner terminal NOW to cancel."
|
|
echo "Sleeping for 10 seconds..."
|
|
echo "*********************************************************************"
|
|
sleep 10
|
|
|
|
- name: Flush BullMQ Queues Only
|
|
if: ${{ gitea.event.inputs.flush_type == 'queues-only' }}
|
|
env:
|
|
REDIS_URL: 'redis://localhost:6379/0'
|
|
run: |
|
|
echo "--- Obliterating BullMQ queues using Node.js ---"
|
|
node -e "
|
|
const { Queue } = require('bullmq');
|
|
const IORedis = require('ioredis');
|
|
|
|
const connection = new IORedis(process.env.REDIS_URL, {
|
|
maxRetriesPerRequest: null,
|
|
password: process.env.REDIS_PASSWORD,
|
|
});
|
|
|
|
const queueNames = [
|
|
'flyer-processing',
|
|
'email-sending',
|
|
'analytics-reporting',
|
|
'weekly-analytics-reporting',
|
|
'file-cleanup',
|
|
'token-cleanup'
|
|
];
|
|
|
|
(async () => {
|
|
for (const name of queueNames) {
|
|
try {
|
|
const queue = new Queue(name, { connection });
|
|
const counts = await queue.getJobCounts();
|
|
console.log('Queue \"' + name + '\" before obliterate:', JSON.stringify(counts));
|
|
await queue.obliterate({ force: true });
|
|
console.log('✅ Obliterated queue: ' + name);
|
|
await queue.close();
|
|
} catch (err) {
|
|
console.error('⚠️ Failed to obliterate queue ' + name + ':', err.message);
|
|
}
|
|
}
|
|
await connection.quit();
|
|
console.log('✅ All BullMQ queues obliterated.');
|
|
})();
|
|
"
|
|
|
|
- name: Flush Entire Redis Database
|
|
if: ${{ gitea.event.inputs.flush_type == 'entire-database' }}
|
|
run: |
|
|
echo "--- Flushing entire Redis database 0 (production) ---"
|
|
redis-cli -a "$REDIS_PASSWORD" -n 0 FLUSHDB 2>/dev/null && echo "✅ Redis database 0 flushed successfully." || echo "❌ Redis flush failed"
|
|
|
|
- name: Verify Flush Results
|
|
run: |
|
|
echo "--- Redis Database 0 (Production) State After Flush ---"
|
|
KEY_COUNT=$(redis-cli -a "$REDIS_PASSWORD" -n 0 DBSIZE 2>/dev/null | grep -oE '[0-9]+' || echo "unknown")
|
|
echo "Production Redis (db 0) key count after flush: $KEY_COUNT"
|
|
echo ""
|
|
echo "--- Remaining BullMQ Queue Keys ---"
|
|
BULL_KEYS=$(redis-cli -a "$REDIS_PASSWORD" -n 0 KEYS "bull:*" 2>/dev/null | wc -l || echo "0")
|
|
echo "BullMQ key count: $BULL_KEYS"
|
|
|
|
if [ "${{ gitea.event.inputs.flush_type }}" = "queues-only" ] && [ "$BULL_KEYS" -gt 0 ]; then
|
|
echo "⚠️ Warning: Some BullMQ keys may still exist. This can happen if new jobs were added during the flush."
|
|
fi
|
|
|
|
- name: Summary
|
|
run: |
|
|
echo ""
|
|
echo "=========================================="
|
|
echo "PRODUCTION REDIS FLUSH COMPLETE"
|
|
echo "=========================================="
|
|
echo "Flush type: ${{ gitea.event.inputs.flush_type }}"
|
|
echo "Timestamp: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
|
echo ""
|
|
echo "NOTE: If you flushed queues, any pending jobs (flyer processing,"
|
|
echo "emails, analytics, etc.) have been permanently deleted."
|
|
echo ""
|
|
echo "The production workers will automatically start processing"
|
|
echo "new jobs as they are added to the queues."
|
|
echo "=========================================="
|