diff --git a/.changeset/friendly-brooms-cry.md b/.changeset/friendly-brooms-cry.md new file mode 100644 index 000000000..aa7fff9a7 --- /dev/null +++ b/.changeset/friendly-brooms-cry.md @@ -0,0 +1,6 @@ +--- +"trigger.dev": patch +"@trigger.dev/build": patch +--- + +prismaExtension fixes for #1325 and #1327 diff --git a/.vscode/launch.json b/.vscode/launch.json index 1e7cf8eb0..8fd69a9b4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -36,6 +36,14 @@ "cwd": "${workspaceFolder}/references/v3-catalog", "sourceMaps": true }, + { + "type": "node-terminal", + "request": "launch", + "name": "Debug prisma-catalog deploy CLI", + "command": "pnpm exec trigger deploy --self-hosted --load-image", + "cwd": "${workspaceFolder}/references/prisma-catalog", + "sourceMaps": true + }, { "type": "node-terminal", "request": "launch", diff --git a/docs/config/config-file.mdx b/docs/config/config-file.mdx index 7c898e494..661331410 100644 --- a/docs/config/config-file.mdx +++ b/docs/config/config-file.mdx @@ -444,12 +444,9 @@ export default defineConfig({ ``` - The `prismaExtension` will inject the `DATABASE_URL` environment variable into the build process - when running the `deploy` command. This means the CLI needs to have `process.env.DATABASE_URL` set - at the time of calling the `deploy` command. You can do this via a `.env` file and passing the - `--env-file .env` option to the deploy command or via shell environment variables. This goes for direct database URLs as well. + The `prismaExtension` will inject the `DATABASE_URL` environment variable into the build process. Learn more about setting environment variables for deploying in our [Environment Variables](/deploy-environment-variables) guide. -These environment variables are only used during the build process and are not embedded in the final image. +These environment variables are only used during the build process and are not embedded in the final container image. diff --git a/packages/build/src/extensions/prisma.ts b/packages/build/src/extensions/prisma.ts index 26d5253d6..b67adc7ef 100644 --- a/packages/build/src/extensions/prisma.ts +++ b/packages/build/src/extensions/prisma.ts @@ -127,8 +127,9 @@ export class PrismaExtension implements BuildExtension { if (this.options.typedSql) { generatorFlags.push(`--sql`); - const schemaDir = dirname(this._resolvedSchemaPath); - const prismaDir = dirname(schemaDir); + const prismaDir = usingSchemaFolder + ? dirname(dirname(this._resolvedSchemaPath)) + : dirname(this._resolvedSchemaPath); context.logger.debug(`Using typedSql`); @@ -226,15 +227,29 @@ export class PrismaExtension implements BuildExtension { commands.push( `${binaryForRuntime(manifest.runtime)} node_modules/prisma/build/index.js migrate deploy` ); + } - env.DATABASE_URL = manifest.deploy.env?.DATABASE_URL; + env.DATABASE_URL = manifest.deploy.env?.DATABASE_URL; - if (this.options.directUrlEnvVarName) { - env[this.options.directUrlEnvVarName] = - manifest.deploy.env?.[this.options.directUrlEnvVarName]; - } else { - env.DIRECT_URL = manifest.deploy.env?.DIRECT_URL; + if (this.options.directUrlEnvVarName) { + env[this.options.directUrlEnvVarName] = + manifest.deploy.env?.[this.options.directUrlEnvVarName] ?? + process.env[this.options.directUrlEnvVarName]; + + if (!env[this.options.directUrlEnvVarName]) { + context.logger.warn( + `prismaExtension could not resolve the ${this.options.directUrlEnvVarName} environment variable. Make sure you add it to your environment variables or provide it as an environment variable to the deploy CLI command. See our docs for more info: https://trigger.dev/docs/deploy-environment-variables` + ); } + } else { + env.DIRECT_URL = manifest.deploy.env?.DIRECT_URL; + env.DIRECT_DATABASE_URL = manifest.deploy.env?.DIRECT_DATABASE_URL; + } + + if (!env.DATABASE_URL) { + context.logger.warn( + `prismaExtension could not resolve the DATABASE_URL environment variable. Make sure you add it to your environment variables. See our docs for more info: https://trigger.dev/docs/deploy-environment-variables` + ); } context.logger.debug(`Adding the prisma layer with the following commands`, { diff --git a/packages/cli-v3/src/deploy/buildImage.ts b/packages/cli-v3/src/deploy/buildImage.ts index a5fed62b6..db933fa5b 100644 --- a/packages/cli-v3/src/deploy/buildImage.ts +++ b/packages/cli-v3/src/deploy/buildImage.ts @@ -492,7 +492,7 @@ COPY --chown=bun:bun . . ${postInstallCommands} -from build as indexer +FROM build AS indexer USER bun WORKDIR /app @@ -601,7 +601,7 @@ COPY --chown=node:node . . ${postInstallCommands} -from build as indexer +FROM build AS indexer USER node WORKDIR /app diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f1c6e2b3..6d4af21c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1360,6 +1360,28 @@ importers: specifier: workspace:* version: link:../../packages/cli-v3 + references/prisma-catalog: + dependencies: + '@prisma/client': + specifier: 5.19.0 + version: 5.19.0(prisma@5.19.0) + '@trigger.dev/sdk': + specifier: workspace:* + version: link:../../packages/trigger-sdk + devDependencies: + '@trigger.dev/build': + specifier: workspace:* + version: link:../../packages/build + prisma: + specifier: 5.19.0 + version: 5.19.0 + trigger.dev: + specifier: workspace:* + version: link:../../packages/cli-v3 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + references/v3-catalog: dependencies: '@infisical/sdk': diff --git a/references/prisma-catalog/package.json b/references/prisma-catalog/package.json new file mode 100644 index 000000000..74f9f3943 --- /dev/null +++ b/references/prisma-catalog/package.json @@ -0,0 +1,18 @@ +{ + "name": "references-prisma-catalog", + "private": true, + "type": "module", + "devDependencies": { + "trigger.dev": "workspace:*", + "@trigger.dev/build": "workspace:*", + "typescript": "^5.5.4", + "prisma": "5.19.0" + }, + "dependencies": { + "@trigger.dev/sdk": "workspace:*", + "@prisma/client": "5.19.0" + }, + "scripts": { + "generate:prisma": "prisma generate --sql" + } +} \ No newline at end of file diff --git a/references/prisma-catalog/prisma/migrations/20240919122925_add_initial_schema/migration.sql b/references/prisma-catalog/prisma/migrations/20240919122925_add_initial_schema/migration.sql new file mode 100644 index 000000000..4af85373f --- /dev/null +++ b/references/prisma-catalog/prisma/migrations/20240919122925_add_initial_schema/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Post" ( + "id" SERIAL NOT NULL, + "title" TEXT NOT NULL, + "content" TEXT NOT NULL, + "authorId" INTEGER NOT NULL, + + CONSTRAINT "Post_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/references/prisma-catalog/prisma/migrations/migration_lock.toml b/references/prisma-catalog/prisma/migrations/migration_lock.toml new file mode 100644 index 000000000..fbffa92c2 --- /dev/null +++ b/references/prisma-catalog/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/references/prisma-catalog/prisma/schema.prisma b/references/prisma-catalog/prisma/schema.prisma new file mode 100644 index 000000000..b05278b72 --- /dev/null +++ b/references/prisma-catalog/prisma/schema.prisma @@ -0,0 +1,26 @@ +generator client { + provider = "prisma-client-js" + previewFeatures = ["typedSql"] +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") + directUrl = env("DIRECT_DATABASE_URL") +} + +// user.prisma +model User { + id Int @id @default(autoincrement()) + name String + posts Post[] +} + +// post.prisma +model Post { + id Int @id @default(autoincrement()) + title String + content String + authorId Int + author User @relation(fields: [authorId], references: [id]) +} diff --git a/references/prisma-catalog/prisma/sql/getUsersWithPosts.sql b/references/prisma-catalog/prisma/sql/getUsersWithPosts.sql new file mode 100644 index 000000000..8f0cb3576 --- /dev/null +++ b/references/prisma-catalog/prisma/sql/getUsersWithPosts.sql @@ -0,0 +1,10 @@ +SELECT + u.id, + u.name, + COUNT(p.id) as "postCount" +FROM + "User" u + LEFT JOIN "Post" p ON u.id = p."authorId" +GROUP BY + u.id, + u.name; \ No newline at end of file diff --git a/references/prisma-catalog/src/db.ts b/references/prisma-catalog/src/db.ts new file mode 100644 index 000000000..5e029ca06 --- /dev/null +++ b/references/prisma-catalog/src/db.ts @@ -0,0 +1,6 @@ +import { PrismaClient } from "@prisma/client"; +import { getUsersWithPosts } from "@prisma/client/sql"; + +export const prisma = new PrismaClient(); + +export { getUsersWithPosts }; diff --git a/references/prisma-catalog/src/trigger/dbTasks.ts b/references/prisma-catalog/src/trigger/dbTasks.ts new file mode 100644 index 000000000..7edb46601 --- /dev/null +++ b/references/prisma-catalog/src/trigger/dbTasks.ts @@ -0,0 +1,21 @@ +import { getUsersWithPosts, prisma } from "../db.js"; +import { logger, task } from "@trigger.dev/sdk/v3"; + +export const prismaTask = task({ + id: "prisma-task", + run: async () => { + const users = await prisma.user.findMany(); + + await prisma.user.create({ + data: { + name: "Alice", + }, + }); + + const usersWithPosts = await prisma.$queryRawTyped(getUsersWithPosts()); + + logger.info("Users with posts", { usersWithPosts }); + + return users; + }, +}); diff --git a/references/prisma-catalog/trigger.config.ts b/references/prisma-catalog/trigger.config.ts new file mode 100644 index 000000000..1bbf0eb2c --- /dev/null +++ b/references/prisma-catalog/trigger.config.ts @@ -0,0 +1,26 @@ +import { prismaExtension } from "@trigger.dev/build/extensions/prisma"; +import { defineConfig } from "@trigger.dev/sdk/v3"; + +export default defineConfig({ + runtime: "node", + project: "proj_mpzmrzygzbvmfjnnpcsk", + retries: { + enabledInDev: false, + default: { + maxAttempts: 3, + minTimeoutInMs: 5_000, + maxTimeoutInMs: 30_000, + factor: 2, + randomize: true, + }, + }, + build: { + extensions: [ + prismaExtension({ + schema: "prisma/schema.prisma", + directUrlEnvVarName: "DIRECT_DATABASE_URL", + typedSql: true, + }), + ], + }, +}); diff --git a/references/prisma-catalog/tsconfig.json b/references/prisma-catalog/tsconfig.json new file mode 100644 index 000000000..9a5ee0b9d --- /dev/null +++ b/references/prisma-catalog/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "customConditions": ["@triggerdotdev/source"], + "jsx": "preserve", + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +}