diff --git a/.changeset/great-pillows-look.md b/.changeset/great-pillows-look.md new file mode 100644 index 0000000000..72a0589b26 --- /dev/null +++ b/.changeset/great-pillows-look.md @@ -0,0 +1,5 @@ +--- +"trigger.dev": minor +--- + +feat(cli): enable zstd compression for deployment images diff --git a/packages/cli-v3/src/commands/deploy.ts b/packages/cli-v3/src/commands/deploy.ts index 818051d68d..f4de03281c 100644 --- a/packages/cli-v3/src/commands/deploy.ts +++ b/packages/cli-v3/src/commands/deploy.ts @@ -71,7 +71,7 @@ const DeployCommandOptions = CommonCommandOptions.extend({ saveLogs: z.boolean().default(false), skipUpdateCheck: z.boolean().default(false), skipPromotion: z.boolean().default(false), - noCache: z.boolean().default(false), + cache: z.boolean().default(true), envFile: z.string().optional(), // Local build options forceLocalBuild: z.boolean().optional(), @@ -83,6 +83,10 @@ const DeployCommandOptions = CommonCommandOptions.extend({ nativeBuildServer: z.boolean().default(false), detach: z.boolean().default(false), plain: z.boolean().default(false), + compression: z.enum(["zstd", "gzip"]).default("zstd"), + cacheCompression: z.enum(["zstd", "gzip"]).default("zstd"), + compressionLevel: z.number().optional(), + forceCompression: z.boolean().default(true), }); type DeployCommandOptions = z.infer; @@ -157,6 +161,40 @@ export function configureDeployCommand(program: Command) { "If provided, will save logs even for successful builds" ).hideHelp() ) + .addOption( + new CommandOption( + "--compression ", + "Compression algorithm for image layers: zstd or gzip (default: zstd)" + ) + .choices(["zstd", "gzip"]) + .hideHelp() + ) + .addOption( + new CommandOption( + "--cache-compression ", + "Compression algorithm for build cache: zstd or gzip (default: zstd)" + ) + .choices(["zstd", "gzip"]) + .hideHelp() + ) + .addOption( + new CommandOption( + "--compression-level ", + "The compression level to use when building the image." + ).hideHelp() + ) + .addOption( + new CommandOption( + "--force-compression", + "Force recompression of all layers. Enabled by default when using zstd." + ).hideHelp() + ) + .addOption( + new CommandOption( + "--no-force-compression", + "Disable forced recompression of layers." + ).hideHelp() + ) // Local build options .addOption( new CommandOption("--force-local-build", "Deprecated alias for --local-build").implies({ @@ -480,7 +518,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) { const buildResult = await buildImage({ isLocalBuild, useRegistryCache: options.useRegistryCache, - noCache: options.noCache, + noCache: !options.cache, deploymentId: deployment.id, deploymentVersion: deployment.version, imageTag: deployment.imageTag, @@ -499,6 +537,10 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) { authAccessToken: authorization.auth.accessToken, compilationPath: destination.path, buildEnvVars: buildManifest.build.env, + compression: options.compression, + cacheCompression: options.cacheCompression, + compressionLevel: options.compressionLevel, + forceCompression: options.forceCompression, onLog: (logMessage) => { if (options.plain || isCI) { console.log(logMessage); diff --git a/packages/cli-v3/src/deploy/buildImage.ts b/packages/cli-v3/src/deploy/buildImage.ts index e325b58d8f..d6957bf973 100644 --- a/packages/cli-v3/src/deploy/buildImage.ts +++ b/packages/cli-v3/src/deploy/buildImage.ts @@ -20,6 +20,10 @@ export interface BuildImageOptions { imagePlatform: string; noCache?: boolean; load?: boolean; + compression?: "zstd" | "gzip"; + cacheCompression?: "zstd" | "gzip"; + compressionLevel?: number; + forceCompression?: boolean; // Local build options push?: boolean; @@ -79,6 +83,10 @@ export async function buildImage(options: BuildImageOptions): Promise; + compression?: "zstd" | "gzip"; + compressionLevel?: number; + forceCompression?: boolean; onLog?: (log: string) => void; } @@ -180,6 +198,14 @@ async function remoteBuildImage(options: DepotBuildImageOptions): Promise value) .flatMap(([key, value]) => ["--build-arg", `${key}=${value}`]); + const outputOptions = getOutputOptions({ + imageTag: undefined, // This is already handled via the --save flag + push: true, // We always push the image to the registry + compression: options.compression, + compressionLevel: options.compressionLevel, + forceCompression: options.forceCompression, + }); + const args = [ "build", "-f", @@ -214,6 +240,8 @@ async function remoteBuildImage(options: DepotBuildImageOptions): Promise void; } async function localBuildImage(options: SelfHostedBuildImageOptions): Promise { - const { builder, imageTag, deploymentId, apiClient, useRegistryCache } = options; + const { + builder, + imageTag, + deploymentId, + apiClient, + useRegistryCache, + compression, + cacheCompression, + compressionLevel, + forceCompression, + } = options; // Ensure multi-platform build is supported on the local machine let builderExists = false; @@ -489,6 +531,14 @@ async function localBuildImage(options: SelfHostedBuildImageOptions): Promise