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
7 changes: 7 additions & 0 deletions packages/wb/src/commands/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ const resetCommand: CommandModule<unknown, InferredOptionTypes<typeof builder>>
for (const project of prepareForRunningCommand('prisma reset', allProjects)) {
await runWithSpawn(prismaScripts.reset(project, unknownOptions), project, argv);
}
// Force to reset test database
if (process.env.WB_ENV !== 'test') {
process.env.WB_ENV = 'test';
for (const project of prepareForRunningCommand('WB_ENV=test prisma reset', await findPrismaProjects(argv))) {
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling await findPrismaProjects(argv) again inside the handler after already calling it at line 135 introduces redundant work. The function performs file system operations to find projects, which is unnecessary since the projects list is already available in allProjects. Consider reusing the allProjects variable instead of calling findPrismaProjects again.

Suggested change
for (const project of prepareForRunningCommand('WB_ENV=test prisma reset', await findPrismaProjects(argv))) {
for (const project of prepareForRunningCommand('WB_ENV=test prisma reset', allProjects)) {

Copilot uses AI. Check for mistakes.
await runWithSpawn(prismaScripts.reset(project, unknownOptions), project, argv);
Comment on lines +142 to +144
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating process.env.WB_ENV at runtime in a command handler has potential side effects that could affect other parts of the application. This creates a stateful change that persists beyond this command execution. Consider using environment variable passing through the command execution instead of mutating the global process.env object, or document this side effect clearly if it's intentional.

Suggested change
process.env.WB_ENV = 'test';
for (const project of prepareForRunningCommand('WB_ENV=test prisma reset', await findPrismaProjects(argv))) {
await runWithSpawn(prismaScripts.reset(project, unknownOptions), project, argv);
const testEnv = { ...process.env, WB_ENV: 'test' };
for (const project of prepareForRunningCommand('WB_ENV=test prisma reset', await findPrismaProjects(argv))) {
await runWithSpawn(prismaScripts.reset(project, unknownOptions), project, argv, { env: testEnv });

Copilot uses AI. Check for mistakes.
}
}
},
};

Expand Down
22 changes: 8 additions & 14 deletions packages/wb/src/scripts/prismaScripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class PrismaScripts {

deployForce(project: Project): string {
const dirPath = getDatabaseDirPath(project);
// `prisma migrate reset` sometimes fails if the existing database schema, so we remove it first.
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment has a grammatical error. It should read "if the existing database schema exists" or "with the existing database schema".

Suggested change
// `prisma migrate reset` sometimes fails if the existing database schema, so we remove it first.
// `prisma migrate reset` sometimes fails if the existing database schema exists, so we remove it first.

Copilot uses AI. Check for mistakes.
// Don't skip "migrate deploy" because restored database may be older than the current schema.
return `PRISMA migrate reset --force --skip-seed && rm -Rf ${dirPath}/prod.sqlite3*
return `rm -Rf ${dirPath}/prod.sqlite3*; PRISMA migrate reset --force --skip-seed && rm -Rf ${dirPath}/prod.sqlite3*
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the security concern in the removeSqliteArtifacts method, using rm -Rf ${dirPath}/prod.sqlite3* with a wildcard could be dangerous if dirPath is empty or misconfigured. While getDatabaseDirPath returns fixed paths, consider adding validation or using more explicit file patterns to prevent accidental deletion of unintended files.

Copilot uses AI. Check for mistakes.
&& litestream restore -config litestream.yml -o ${dirPath}/prod.sqlite3 ${dirPath}/prod.sqlite3 && ls -ahl ${dirPath}/prod.sqlite3 && ALLOW_TO_SKIP_SEED=0 PRISMA migrate deploy`;
}

Expand All @@ -43,18 +44,16 @@ class PrismaScripts {

reset(project: Project, additionalOptions = ''): string {
// cf. https://www.prisma.io/docs/guides/database/seed-database#integrated-seeding-with-prisma-migrate
const resetOptions = additionalOptions.trim();
const baseReset = `PRISMA migrate reset --force ${resetOptions}`;
const resetCommand = project.packageJson.dependencies?.blitz ? `${baseReset} && ${this.seed(project)}` : baseReset;
const resetCommandForTest = project.packageJson.dependencies?.blitz
? String.raw`find db \( -name "test.db*" -o -name "test.sqlite*" \) -delete`
: String.raw`find prisma \( -name "test.db*" -o -name "test.sqlite*" \) -delete`;
return `${resetCommand} && ${resetCommandForTest}`;
if (project.packageJson.dependencies?.blitz) {
// Blitz does not trigger seed automatically, so we need to run it manually.
return `PRISMA migrate reset --force ${additionalOptions} && ${this.seed(project)}`;
}
return `PRISMA migrate reset --force ${additionalOptions}`;
}

restore(project: Project, outputPath: string): string {
const dirPath = getDatabaseDirPath(project);
return `${this.removeSqliteArtifacts(outputPath)}; litestream restore -config litestream.yml -o ${outputPath} ${dirPath}/prod.sqlite3`;
return `rm -Rf ${outputPath}*; litestream restore -config litestream.yml -o ${outputPath} ${dirPath}/prod.sqlite3`;
}

seed(project: Project, scriptPath?: string): string {
Expand Down Expand Up @@ -117,11 +116,6 @@ const prisma = new PrismaClient();
}
return `${prefix}PRISMA studio ${additionalOptions}`;
}

private removeSqliteArtifacts(sqlitePath: string): string {
// Litestream requires removing WAL/SHM and Litestream sidecar files when recreating databases.
return `rm -Rf ${sqlitePath} ${sqlitePath}-shm ${sqlitePath}-wal ${sqlitePath}-litestream`;
}
}

function getDatabaseDirPath(project: Project): string {
Expand Down