);
diff --git a/apps/webapp/app/routes/storybook.tabs/route.tsx b/apps/webapp/app/routes/storybook.tabs/route.tsx
index fc0c8003a..f3389f2af 100644
--- a/apps/webapp/app/routes/storybook.tabs/route.tsx
+++ b/apps/webapp/app/routes/storybook.tabs/route.tsx
@@ -1,18 +1,188 @@
import { Outlet } from "@remix-run/react";
+import {
+ ClientTabs,
+ ClientTabsContent,
+ ClientTabsList,
+ ClientTabsTrigger,
+} from "~/components/primitives/ClientTabs";
+import { Header1 } from "~/components/primitives/Headers";
+import { Paragraph } from "~/components/primitives/Paragraph";
import { Tabs } from "~/components/primitives/Tabs";
export default function Story() {
return (
-
-
-
+
+
+
+
+
{""} (updates the URL)
+
Variant="underline"
+
+
+
+
+
+
Variant="pipe-divider"
+
+
+
+
+
Variant="segmented"
+
+
+
+
+
+
+
+
{""}
+
Variant="underline"
+
+
+
+
+
+ First tab
+
+
+ Second tab
+
+
+ Third tab
+
+
+
+
+
+
1
+
+
+
+
+
2
+
+
+
+
+
3
+
+
+
+
+
+
+
Variant="pipe-divider"
+
+
+
+
+ First tab
+
+
+ Second tab
+
+
+ Third tab
+
+
+
+
+
+
1
+
+
+
+
+
2
+
+
+
+
+
3
+
+
+
+
+
+
Variant="segmented"
+
+
+
+ First tab
+
+
+ Second tab
+
+
+ Third tab
+
+
+
+
+
1
+
+
+
+
+
2
+
+
+
+
+
3
+
+
+
+
+
);
}
diff --git a/apps/webapp/app/services/apiRateLimit.server.ts b/apps/webapp/app/services/apiRateLimit.server.ts
index 416d7834e..4cf27450a 100644
--- a/apps/webapp/app/services/apiRateLimit.server.ts
+++ b/apps/webapp/app/services/apiRateLimit.server.ts
@@ -61,6 +61,7 @@ export const apiRateLimiter = authorizationRateLimitMiddleware({
"/api/v1/auth/jwt/claims",
/^\/api\/v1\/runs\/[^\/]+\/attempts$/, // /api/v1/runs/$runFriendlyId/attempts
/^\/api\/v1\/waitpoints\/tokens\/[^\/]+\/callback\/[^\/]+$/, // /api/v1/waitpoints/tokens/$waitpointFriendlyId/callback/$hash
+ /^\/api\/v1\/deployments/, // /api/v1/deployments/*
],
log: {
rejections: env.API_RATE_LIMIT_REJECTION_LOGS_ENABLED === "1",
diff --git a/apps/webapp/app/utils/pathBuilder.ts b/apps/webapp/app/utils/pathBuilder.ts
index f82165ae9..3061082ed 100644
--- a/apps/webapp/app/utils/pathBuilder.ts
+++ b/apps/webapp/app/utils/pathBuilder.ts
@@ -288,15 +288,17 @@ export function v3RunPath(
organization: OrgForPath,
project: ProjectForPath,
environment: EnvironmentForPath,
- run: v3RunForPath
+ run: v3RunForPath,
+ searchParams?: URLSearchParams
) {
- return `${v3RunsPath(organization, project, environment)}/${run.friendlyId}`;
+ const query = searchParams ? `?${searchParams.toString()}` : "";
+ return `${v3RunsPath(organization, project, environment)}/${run.friendlyId}${query}`;
}
export function v3RunRedirectPath(
organization: OrgForPath,
project: ProjectForPath,
- run: v3RunForPath
+ run: v3RunForPath,
) {
return `${v3ProjectPath(organization, project)}/runs/${run.friendlyId}`;
}
@@ -310,9 +312,12 @@ export function v3RunSpanPath(
project: ProjectForPath,
environment: EnvironmentForPath,
run: v3RunForPath,
- span: v3SpanForPath
+ span: v3SpanForPath,
+ searchParams?: URLSearchParams
) {
- return `${v3RunPath(organization, project, environment, run)}?span=${span.spanId}`;
+ searchParams = searchParams ?? new URLSearchParams();
+ searchParams.set("span", span.spanId);
+ return `${v3RunPath(organization, project, environment, run, searchParams)}`;
}
export function v3RunStreamingPath(
diff --git a/docs/self-hosting/kubernetes.mdx b/docs/self-hosting/kubernetes.mdx
index f3a827701..4506d6da9 100644
--- a/docs/self-hosting/kubernetes.mdx
+++ b/docs/self-hosting/kubernetes.mdx
@@ -61,7 +61,7 @@ webapp:
```bash
helm upgrade -n trigger --install trigger \
oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "~4.0.0-beta" \
+ --version "~4.0.0" \
--create-namespace
```
@@ -107,11 +107,11 @@ The following commands will display the default values:
```bash
# Specific version
helm show values oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "4.0.0-beta.5"
+ --version "4.0.5"
-# Latest v4 beta
+# Latest v4
helm show values oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "~4.0.0-beta"
+ --version "~4.0.0"
```
### Custom values
@@ -171,7 +171,7 @@ Deploy with your custom values:
```bash
helm upgrade -n trigger --install trigger \
oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "~4.0.0-beta" \
+ --version "~4.0.0" \
--create-namespace \
-f values-custom.yaml
```
@@ -489,14 +489,14 @@ You can lock versions in two ways:
# Pin to a specific version for production
helm upgrade -n trigger --install trigger \
oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "4.0.0-beta.5"
+ --version "4.0.5"
# The app version will be different from the chart version
# This is the version of the Trigger.dev webapp and supervisor
# ..and should always match your Trigger.dev CLI version
helm show chart \
oci://ghcr.io/triggerdotdev/charts/trigger \
- --version "4.0.0-beta.5" | grep appVersion
+ --version "4.0.5" | grep appVersion
```
**Specific image tags:**
diff --git a/packages/cli-v3/src/commands/deploy.ts b/packages/cli-v3/src/commands/deploy.ts
index 818051d68..f4de03281 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 f060ce030..2225d7db0 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,15 @@ 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
+ load: options.load,
+ compression: options.compression,
+ compressionLevel: options.compressionLevel,
+ forceCompression: options.forceCompression,
+ });
+
const args = [
"build",
"-f",
@@ -187,7 +214,6 @@ 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;
@@ -491,6 +531,15 @@ async function localBuildImage(options: SelfHostedBuildImageOptions): Promise