Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ jobs:
- name: Migrate + boot the API on Bun
run: |
set -e
# The runner must refuse the legacy SQLite migrations on a Postgres target.
if MIGRATIONS_DIR=packages/storage/migrations bun scripts/db-migrate.mjs; then
echo "db-migrate applied SQLite migrations to Postgres" >&2; exit 1
fi
MIGRATIONS_DIR=packages/storage/migrations-pg bun scripts/db-migrate.mjs
PORT=8090 bun services/api/dist/index.js > api.log 2>&1 &
for i in $(seq 1 30); do curl -fsS http://127.0.0.1:8090/api/healthz && break; sleep 1; done
Expand Down
9 changes: 8 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,14 @@ COPY --from=api /out/node_modules /api/node_modules
COPY --from=api /out/package.json /api/package.json
# DB migrations run on boot (start.sh) so schema never drifts from the deploy.
COPY scripts/db-migrate.mjs /api/db-migrate.mjs
COPY packages/storage/migrations /api/migrations
# The API runs on Postgres, so the image carries the Postgres migrations
# (migrations-pg), never the legacy SQLite ones in packages/storage/migrations.
# Fail the build if any shipped file lacks the Postgres-schema header.
COPY packages/storage/migrations-pg /api/migrations-pg
RUN for f in /api/migrations-pg/*.sql; do \
head -1 "$f" | grep -q '^-- TronBrowser Postgres schema:' \
|| { echo "not a Postgres migration: $f" >&2; exit 1; }; \
done
COPY start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]
13 changes: 13 additions & 0 deletions scripts/db-migrate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ if (!url && !filePath) {

const DIR = process.env.MIGRATIONS_DIR || join(ROOT, isPostgres ? 'packages/storage/migrations-pg' : 'packages/storage/migrations');
const files = readdirSync(DIR).filter((f) => f.endsWith('.sql')).sort();
console.log(`[migrate] ${isPostgres ? 'postgres' : 'libsql'} target, reading ${DIR} (${files.length} file(s))`);

// Every Postgres migration starts with this header. A file without it is the
// legacy SQLite schema (packages/storage/migrations), which must never be run
// against the production Postgres; refuse before touching the database.
const PG_HEADER = /^-- TronBrowser Postgres schema:/;
if (isPostgres) {
const bad = files.filter((f) => !PG_HEADER.test(readFileSync(join(DIR, f), 'utf8')));
if (bad.length) {
console.error(`[migrate] refusing: ${DIR} holds non-Postgres migrations (${bad.join(', ')}). Point MIGRATIONS_DIR at packages/storage/migrations-pg.`);
process.exit(1);
}
}

if (isPostgres) {
const { createClient } = await import('@profullstack/libsql-pg');
Expand Down
2 changes: 1 addition & 1 deletion start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
set -e
# Apply any pending DB migrations on boot (idempotent, forward-only). Non-fatal:
# a transient DB hiccup shouldn't block the whole service from starting.
MIGRATIONS_DIR=/api/migrations bun /api/db-migrate.mjs || echo "[migrate] FAILED — continuing"
MIGRATIONS_DIR=/api/migrations-pg bun /api/db-migrate.mjs || echo "[migrate] FAILED — continuing"
PORT=8090 bun /api/dist/index.js &

# --- Tor v3 hidden service ---------------------------------------------------
Expand Down
Loading