diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 911e3ece85..50575a1a37 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -114,6 +114,7 @@ const EnvironmentSchema = z.object({ DEPOT_TOKEN: z.string().optional(), DEPOT_PROJECT_ID: z.string().optional(), DEPOT_ORG_ID: z.string().optional(), + DEPOT_REGION: z.string().default("us-east-1"), CONTAINER_REGISTRY_ORIGIN: z.string().optional(), CONTAINER_REGISTRY_USERNAME: z.string().optional(), CONTAINER_REGISTRY_PASSWORD: z.string().optional(), diff --git a/apps/webapp/app/v3/remoteImageBuilder.server.ts b/apps/webapp/app/v3/remoteImageBuilder.server.ts index 8f7992c29a..fb9402ddae 100644 --- a/apps/webapp/app/v3/remoteImageBuilder.server.ts +++ b/apps/webapp/app/v3/remoteImageBuilder.server.ts @@ -1,13 +1,17 @@ import { depot } from "@depot/sdk-node"; +import { Project } from "@trigger.dev/database"; +import { prisma } from "~/db.server"; import { env } from "~/env.server"; -export async function createRemoteImageBuild() { +export async function createRemoteImageBuild(project: Project) { if (!env.DEPOT_TOKEN || !env.DEPOT_PROJECT_ID) { return; } + const builderProjectId = await createBuilderProjectIfNotExists(project); + const result = await depot.build.v1.BuildService.createBuild( - { projectId: env.DEPOT_PROJECT_ID }, + { projectId: builderProjectId }, { headers: { Authorization: `Bearer ${env.DEPOT_TOKEN}`, @@ -16,8 +20,40 @@ export async function createRemoteImageBuild() { ); return { - projectId: env.DEPOT_PROJECT_ID, + projectId: builderProjectId, buildToken: result.buildToken, buildId: result.buildId, }; } + +async function createBuilderProjectIfNotExists(project: Project) { + if (project.builderProjectId) { + return project.builderProjectId; + } + + const result = await depot.core.v1.ProjectService.createProject( + { + name: `${env.APP_ENV} ${project.externalRef}`, + organizationId: env.DEPOT_ORG_ID, + regionId: env.DEPOT_REGION, + }, + { + headers: { + Authorization: `Bearer ${env.DEPOT_TOKEN}`, + }, + } + ); + + if (!result.project) { + throw new Error("Failed to create builder project"); + } + + await prisma.project.update({ + where: { id: project.id }, + data: { + builderProjectId: result.project.projectId, + }, + }); + + return result.project.projectId; +} diff --git a/apps/webapp/app/v3/services/initializeDeployment.server.ts b/apps/webapp/app/v3/services/initializeDeployment.server.ts index 3dfe37ec00..b0ad054d38 100644 --- a/apps/webapp/app/v3/services/initializeDeployment.server.ts +++ b/apps/webapp/app/v3/services/initializeDeployment.server.ts @@ -29,7 +29,7 @@ export class InitializeDeploymentService extends BaseService { const nextVersion = calculateNextBuildVersion(latestDeployment?.version); // Try and create a depot build and get back the external build data - const externalBuildData = await createRemoteImageBuild(); + const externalBuildData = await createRemoteImageBuild(environment.project); const triggeredBy = payload.userId ? await this._prisma.user.findUnique({ diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 64efcde7d8..49e0edebdc 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -45,7 +45,7 @@ "@codemirror/view": "^6.5.0", "@conform-to/react": "^0.6.1", "@conform-to/zod": "^0.6.1", - "@depot/sdk-node": "^0.5.0", + "@depot/sdk-node": "^1.0.0", "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.12", "@internationalized/date": "^3.5.1", diff --git a/packages/database/prisma/migrations/20240905134437_add_builder_project_id_to_projects/migration.sql b/packages/database/prisma/migrations/20240905134437_add_builder_project_id_to_projects/migration.sql new file mode 100644 index 0000000000..33966e7c11 --- /dev/null +++ b/packages/database/prisma/migrations/20240905134437_add_builder_project_id_to_projects/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Project" ADD COLUMN "builderProjectId" TEXT; diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index c8194a39e1..ef7c7c25cf 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -441,6 +441,8 @@ model Project { version ProjectVersion @default(V2) + builderProjectId String? + environments RuntimeEnvironment[] endpoints Endpoint[] jobs Job[] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05a5245594..a2570db9b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -229,8 +229,8 @@ importers: specifier: ^0.6.1 version: 0.6.1(@conform-to/dom@0.6.1)(zod@3.22.3) '@depot/sdk-node': - specifier: ^0.5.0 - version: 0.5.0 + specifier: ^1.0.0 + version: 1.0.0 '@headlessui/react': specifier: ^1.7.8 version: 1.7.8(react-dom@18.2.0)(react@18.2.0) @@ -3828,8 +3828,8 @@ packages: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - /@bufbuild/protobuf@1.7.2: - resolution: {integrity: sha512-i5GE2Dk5ekdlK1TR7SugY4LWRrKSfb5T1Qn4unpIMbfxoeGKERKQ59HG3iYewacGD10SR7UzevfPnh6my4tNmQ==} + /@bufbuild/protobuf@1.10.0: + resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==} dev: false /@bundled-es-modules/cookie@2.0.0: @@ -4315,23 +4315,24 @@ packages: zod: 3.22.3 dev: false - /@connectrpc/connect-node@0.13.2(@bufbuild/protobuf@1.7.2): - resolution: {integrity: sha512-dAoBuQ+fYFw22KYgZXPw1t19i6TRwNmk6c6XsOYLhBl1Y5vzXoMfMX2jm7lmkmLQFIcM9Xc2EYoUKtjNXH5bjw==} + /@connectrpc/connect-node@1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0): + resolution: {integrity: sha512-0ANnrr6SvsjevsWEgdzHy7BaHkluZyS6s4xNoVt7RBHFR5V/kT9lPokoIbYUOU9JHzdRgTaS3x5595mwUsu15g==} engines: {node: '>=16.0.0'} peerDependencies: - '@bufbuild/protobuf': ^1.2.1 + '@bufbuild/protobuf': ^1.4.2 + '@connectrpc/connect': 1.4.0 dependencies: - '@bufbuild/protobuf': 1.7.2 - '@connectrpc/connect': 0.13.2(@bufbuild/protobuf@1.7.2) + '@bufbuild/protobuf': 1.10.0 + '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) undici: 5.28.4 dev: false - /@connectrpc/connect@0.13.2(@bufbuild/protobuf@1.7.2): - resolution: {integrity: sha512-KZg6EH8gYnQZm/d2IXXMVB2mom/A1dCD8+7JScm2tKN9OQyQSeCJOLqtv/M4M5XVS0Y9JM2/VCbiUwfhl9Rqmg==} + /@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0): + resolution: {integrity: sha512-vZeOkKaAjyV4+RH3+rJZIfDFJAfr+7fyYr6sLDKbYX3uuTVszhFe9/YKf5DNqrDb5cKdKVlYkGn6DTDqMitAnA==} peerDependencies: - '@bufbuild/protobuf': ^1.2.1 + '@bufbuild/protobuf': ^1.4.2 dependencies: - '@bufbuild/protobuf': 1.7.2 + '@bufbuild/protobuf': 1.10.0 dev: false /@cspotcode/source-map-support@0.8.1: @@ -4438,12 +4439,12 @@ packages: '@depot/cli-win32-x64': 0.0.1-cli.2.73.0 dev: false - /@depot/sdk-node@0.5.0: - resolution: {integrity: sha512-Pl9Yji00B6uQpMm5xZU4/eZbzaBo72N6c534ZqLI6nbOEIPH0VX27TVF9lFF3Fl3GHFZ+6X9laJtDn2DrLS2DQ==} + /@depot/sdk-node@1.0.0: + resolution: {integrity: sha512-zq1xqesqGhp58Rh0bTXhsjoC8X+L+LwZABLlQh7Rm45770nGtAABa3GtU1n/776YTMI1gIAhzc++Jxae3H0J4w==} dependencies: - '@bufbuild/protobuf': 1.7.2 - '@connectrpc/connect': 0.13.2(@bufbuild/protobuf@1.7.2) - '@connectrpc/connect-node': 0.13.2(@bufbuild/protobuf@1.7.2) + '@bufbuild/protobuf': 1.10.0 + '@connectrpc/connect': 1.4.0(@bufbuild/protobuf@1.10.0) + '@connectrpc/connect-node': 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0) dev: false /@emotion/hash@0.9.0: