mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-02 18:20:39 +08:00
027d163921
fix #14894 #### PR Dependency Tree * **PR #14895** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Improved database initialization for self-hosted deployments with automatic creation and repair of embedding tables and indexes, applied only when related base tables and extensions are present. * Updated pre-deploy process to run Prisma migrations, perform embedding-table maintenance, and execute additional data migrations as part of setup. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
114 lines
2.9 KiB
JavaScript
114 lines
2.9 KiB
JavaScript
import { execSync } from 'node:child_process';
|
|
import { generateKeyPairSync } from 'node:crypto';
|
|
import fs from 'node:fs';
|
|
import { homedir } from 'node:os';
|
|
import path from 'node:path';
|
|
|
|
const SELF_HOST_CONFIG_DIR = `${homedir()}/.affine/config`;
|
|
|
|
function generatePrivateKey() {
|
|
const key = generateKeyPairSync('ec', {
|
|
namedCurve: 'prime256v1',
|
|
}).privateKey.export({
|
|
type: 'sec1',
|
|
format: 'pem',
|
|
});
|
|
|
|
if (key instanceof Buffer) {
|
|
return key.toString('utf-8');
|
|
}
|
|
|
|
return key;
|
|
}
|
|
|
|
/**
|
|
* @type {Array<{ to: string; generator: () => string }>}
|
|
*/
|
|
const files = [{ to: 'private.key', generator: generatePrivateKey }];
|
|
|
|
function prepare() {
|
|
fs.mkdirSync(SELF_HOST_CONFIG_DIR, { recursive: true });
|
|
|
|
for (const { to, generator } of files) {
|
|
const targetFilePath = path.join(SELF_HOST_CONFIG_DIR, to);
|
|
if (!fs.existsSync(targetFilePath)) {
|
|
console.log(`creating config file [${targetFilePath}].`);
|
|
fs.writeFileSync(targetFilePath, generator(), 'utf-8');
|
|
}
|
|
}
|
|
}
|
|
|
|
function runPrismaMigrations() {
|
|
console.log('running prisma migrations.');
|
|
execSync('yarn prisma migrate deploy', {
|
|
encoding: 'utf-8',
|
|
env: process.env,
|
|
stdio: 'inherit',
|
|
});
|
|
}
|
|
|
|
function repairPgvectorEmbeddingTables() {
|
|
console.log('repairing copilot pgvector embedding tables.');
|
|
const sql = fs.readFileSync(
|
|
path.join(import.meta.dirname, 'repair-pgvector-embedding-tables.sql'),
|
|
'utf-8'
|
|
);
|
|
execSync('yarn prisma db execute --stdin --schema schema.prisma', {
|
|
encoding: 'utf-8',
|
|
env: process.env,
|
|
input: sql,
|
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
});
|
|
}
|
|
|
|
function runDataMigrations() {
|
|
console.log('running data migrations.');
|
|
execSync('yarn cli run', {
|
|
encoding: 'utf-8',
|
|
env: process.env,
|
|
stdio: 'inherit',
|
|
});
|
|
}
|
|
|
|
function fixFailedMigrations() {
|
|
console.log('fixing failed migrations.');
|
|
const maybeFailedMigrations = [
|
|
'20250521083048_fix_workspace_embedding_chunk_primary_key',
|
|
];
|
|
for (const migration of maybeFailedMigrations) {
|
|
try {
|
|
execSync(`yarn prisma migrate resolve --rolled-back ${migration}`, {
|
|
encoding: 'utf-8',
|
|
env: process.env,
|
|
stdio: 'pipe',
|
|
});
|
|
console.log(`migration [${migration}] has been rolled back.`);
|
|
} catch (err) {
|
|
if (
|
|
err.message.includes(
|
|
'cannot be rolled back because it is not in a failed state'
|
|
) ||
|
|
err.message.includes(
|
|
'cannot be rolled back because it was never applied'
|
|
) ||
|
|
err.message.includes(
|
|
'called markMigrationRolledBack on a database without migrations table'
|
|
)
|
|
) {
|
|
// migration has been rolled back, skip it
|
|
continue;
|
|
}
|
|
// ignore other errors
|
|
console.log(
|
|
`migration [${migration}] rolled back failed. ${err.message}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
prepare();
|
|
fixFailedMigrations();
|
|
runPrismaMigrations();
|
|
repairPgvectorEmbeddingTables();
|
|
runDataMigrations();
|