Skip to content

Commit dcb1b56

Browse files
authored
Merge pull request #20266 from mozilla/mysql-patcher-add
chore(db-migrations): vendor mysql-patcher
2 parents d144d21 + 1300e6e commit dcb1b56

25 files changed

Lines changed: 1021 additions & 98 deletions

_scripts/check-db-patcher.sh

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,24 @@
11
#!/bin/bash
2-
NAME="patcher.mjs" # nodejs script's name here
32
RETRY=60
43

54
echo -e "\nChecking for DB patches..."
65

7-
# Wait for patcher process to appear
8-
echo "⏳ Waiting for patcher process to start..."
9-
for i in $(seq 1 $RETRY); do
10-
PATCHER_PID=$(pgrep -f "$NAME")
11-
if [[ -n "$PATCHER_PID" ]]; then
12-
echo "🔄 Patcher process found (PID: $PATCHER_PID)"
13-
break
14-
fi
15-
if [[ $i -eq $RETRY ]]; then
16-
echo "❌ Timeout: Patcher process did not start in time"
17-
exit 1
18-
fi
19-
sleep 1
20-
done
21-
22-
# Confirm the process is running
23-
if ! ps -p "$PATCHER_PID" > /dev/null; then
24-
echo "⚠️ DB patcher process ($NAME, PID $PATCHER_PID) is not running. Skipping wait."
25-
exit 0
26-
fi
6+
# Strategy: poll PM2 logs for the patcher outcome. This avoids the race
7+
# condition where the patcher starts and finishes before we can pgrep it
8+
# (common when all DBs are already at target level).
279

10+
echo "⏳ Waiting for DB patches to complete..."
2811
for i in $(seq 1 $RETRY); do
29-
if ps -p "$PATCHER_PID" > /dev/null; then
30-
sleep 0.5
31-
else
32-
# Show patch summary from PM2 logs (deduplicated)
33-
echo "📋 Patch Summary:"
34-
if command -v pm2 >/dev/null 2>&1; then
35-
pm2 logs mysql --lines 50 --nostream 2>/dev/null | \
12+
if command -v pm2 >/dev/null 2>&1; then
13+
LOG_OUTPUT=$(pm2 logs mysql --lines 100 --nostream 2>/dev/null)
14+
15+
# Check for failure first
16+
if echo "$LOG_OUTPUT" | grep -qE "Failed to patch|Error:.*patch"; then
17+
echo "📋 Patch Summary:"
18+
echo "$LOG_OUTPUT" | \
3619
grep -E "(Successfully patched|Error:|Failed to patch)" | \
37-
sed 's/.*|mysql[[:space:]]*|//' | \
38-
sort -u | \
39-
tail -20 | \
20+
sed 's/.*|mysql[[:space:]]*|[[:space:]]*//' | sed 's/\x1b\[[0-9;]*m//g' | \
21+
sort -u | tail -20 | \
4022
while read line; do
4123
if [[ $line =~ ^Successfully ]]; then
4224
echo "$line"
@@ -46,24 +28,28 @@ for i in $(seq 1 $RETRY); do
4628
echo " 💥 $line"
4729
fi
4830
done
31+
echo "❌ DB patches failed"
32+
exit 1
4933
fi
5034

51-
# Check if there were any errors in the logs
52-
has_errors=$(pm2 logs mysql --lines 50 --nostream 2>/dev/null | grep -c "Error:\|Failed to patch" 2>/dev/null || echo "0")
53-
54-
if [[ ! "$has_errors" =~ ^[0-9]+$ ]]; then
55-
has_errors=0
56-
fi
57-
58-
if [[ $has_errors -eq 0 ]]; then
35+
# Check for success — need all 4 databases
36+
SUCCESS_COUNT=$(echo "$LOG_OUTPUT" | grep -c "Successfully patched" 2>/dev/null || echo "0")
37+
if [[ "$SUCCESS_COUNT" -ge 4 ]]; then
38+
echo "📋 Patch Summary:"
39+
echo "$LOG_OUTPUT" | \
40+
grep -E "Successfully patched" | \
41+
sed 's/.*|mysql[[:space:]]*|[[:space:]]*//' | sed 's/\x1b\[[0-9;]*m//g' | \
42+
sort -u | tail -20 | \
43+
while read line; do
44+
echo "$line"
45+
done
5946
echo "✅ DB patches applied successfully"
6047
exit 0
61-
else
62-
echo "❌ DB patches failed"
63-
exit 1
6448
fi
6549
fi
50+
51+
sleep 1
6652
done
6753

68-
echo "❌ Timeout: DB patches did not finish in time."
54+
echo "❌ Timeout: DB patches did not complete in 60 seconds."
6955
exit 1
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": ["../../.eslintrc.json"],
3+
"root": true,
4+
"ignorePatterns": ["dist", "databases", "contentful"],
5+
"overrides": [
6+
{
7+
"files": ["**/*.spec.js"],
8+
"env": {
9+
"jest": true
10+
}
11+
}
12+
]
13+
}

packages/db-migrations/bin/patcher.mjs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import { promisify } from 'util';
65
import fs from 'fs/promises';
76
import path from 'path';
87
import mysql from 'mysql';
9-
import patcher from 'mysql-patcher';
8+
import Patcher from '../lib/mysql-patcher.js';
109
import convict from 'convict';
1110
import { makeMySQLConfig } from 'fxa-shared/db/config';
12-
const patch = promisify(patcher.patch);
1311

1412
const conf = convict({
1513
fxa: makeMySQLConfig('AUTH', 'fxa'),
@@ -43,7 +41,7 @@ for (const db of databases) {
4341
try {
4442
const cfg = conf.get(db);
4543
console.log(`Patching ${db} to ${level}`);
46-
let results = await patch({
44+
await Patcher.patch({
4745
user: cfg.user,
4846
password: cfg.password,
4947
host: cfg.host,
@@ -57,7 +55,6 @@ for (const db of databases) {
5755
reversePatchAllowed: false,
5856
database: cfg.database,
5957
});
60-
console.log(`Results: ${results}`);
6158
console.log(`Successfully patched ${db} to ${level}`);
6259
} catch (error) {
6360
// fyi these logs show up in `pm2 logs mysql`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
/** @type {import('jest').Config} */
6+
export default {
7+
displayName: 'db-migrations',
8+
testEnvironment: 'node',
9+
moduleFileExtensions: ['js', 'json'],
10+
coverageDirectory: '../../coverage/packages/db-migrations',
11+
reporters: [
12+
'default',
13+
[
14+
'jest-junit',
15+
{
16+
outputDirectory: 'artifacts/tests/db-migrations',
17+
outputName: 'db-migrations-jest-results.xml',
18+
},
19+
],
20+
],
21+
}

0 commit comments

Comments
 (0)