diff --git a/.github/workflows/production.yaml b/.github/workflows/production.yaml index ac95801..93f8f16 100644 --- a/.github/workflows/production.yaml +++ b/.github/workflows/production.yaml @@ -30,7 +30,7 @@ jobs: DATABASE_URL: ${{ secrets.DATABASE_URL }} - name: Run database migrations - run: npm run db:migrate + run: npm run db:migrate:retry env: DATABASE_URL: ${{ secrets.DATABASE_URL }} diff --git a/.github/workflows/staging.yaml b/.github/workflows/staging.yaml index f38922a..5bcfe95 100644 --- a/.github/workflows/staging.yaml +++ b/.github/workflows/staging.yaml @@ -32,7 +32,7 @@ jobs: DATABASE_URL: ${{ secrets.DATABASE_URL }} - name: Run database migrations - run: npm run db:migrate + run: npm run db:migrate:retry env: DATABASE_URL: ${{ secrets.DATABASE_URL }} diff --git a/package.json b/package.json index 498a043..1f84ca4 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "build": "next build", "db:migrate": "prisma format && prisma migrate dev", + "db:migrate:retry": "prisma format && node scripts/run-migrations.js", "db:reset": "prisma migrate reset", "db:view": "prisma studio", "dev": "next dev", diff --git a/scripts/run-migrations.js b/scripts/run-migrations.js new file mode 100644 index 0000000..31d73ef --- /dev/null +++ b/scripts/run-migrations.js @@ -0,0 +1,46 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { exec } = require('child_process'); + +const MIGRATION_COMMAND = 'npx prisma migrate deploy'; +const MAX_RETRIES = 3; +const INITIAL_DELAY_MS = 2000; + +let attempt = 0; + +function runMigration() { + attempt++; + console.log(`\n🚀 Attempt ${attempt}: Running database migrations...`); + + const child = exec(MIGRATION_COMMAND); + + child.stdout.on('data', (data) => { + process.stdout.write(data); + }); + + child.stderr.on('data', (data) => { + process.stderr.write(data); + }); + + child.on('exit', (code) => { + if (code === 0) { + console.log('\n✅ Database migration successful!'); + process.exit(0); + } else { + console.error( + `\n❌ Attempt ${attempt}: Migration failed with exit code ${code}.` + ); + if (attempt < MAX_RETRIES) { + const delay = INITIAL_DELAY_MS * Math.pow(2, attempt - 1); + console.log(`\n⏳ Retrying in ${delay / 1000} seconds...`); + setTimeout(runMigration, delay); + } else { + console.error( + `\n🚨 All ${MAX_RETRIES} migration attempts failed. Aborting.` + ); + process.exit(1); + } + } + }); +} + +runMigration();