diff --git a/apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts b/apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
index ea59c65722..bc494c118a 100644
--- a/apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
+++ b/apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
@@ -156,6 +156,7 @@ export class DeploymentPresenter {
},
},
buildServerMetadata: true,
+ triggeredVia: true,
},
});
@@ -225,6 +226,7 @@ export class DeploymentPresenter {
isBuilt: !!deployment.builtAt,
type: deployment.type,
git: gitMetadata,
+ triggeredVia: deployment.triggeredVia,
},
};
}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
index aebc934ba3..9d32d89fd5 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
@@ -3,7 +3,16 @@ import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { useEffect, useState, useRef, useCallback } from "react";
import { S2, S2Error } from "@s2-dev/streamstore";
-import { Clipboard, ClipboardCheck, ChevronDown, ChevronUp } from "lucide-react";
+import {
+ Clipboard,
+ ClipboardCheck,
+ ChevronDown,
+ ChevronUp,
+ TerminalSquareIcon,
+ LayoutDashboardIcon,
+ GitBranchIcon,
+ ServerIcon,
+} from "lucide-react";
import { ExitIcon } from "~/assets/icons/ExitIcon";
import { GitMetadata } from "~/components/GitMetadata";
import { RuntimeIcon } from "~/components/RuntimeIcon";
@@ -73,6 +82,90 @@ type LogEntry = {
level: "info" | "error" | "warn" | "debug";
};
+function getTriggeredViaDisplay(triggeredVia: string | null | undefined): {
+ icon: React.ReactNode;
+ label: string;
+} | null {
+ if (!triggeredVia) return null;
+
+ const iconClass = "size-4 text-text-dimmed";
+
+ switch (triggeredVia) {
+ case "cli:manual":
+ return {
+ icon: ,
+ label: "CLI (Manual)",
+ };
+ case "cli:github_actions":
+ return {
+ icon: ,
+ label: "CLI (GitHub Actions)",
+ };
+ case "cli:gitlab_ci":
+ return {
+ icon: ,
+ label: "CLI (GitLab CI)",
+ };
+ case "cli:circleci":
+ return {
+ icon: ,
+ label: "CLI (CircleCI)",
+ };
+ case "cli:jenkins":
+ return {
+ icon: ,
+ label: "CLI (Jenkins)",
+ };
+ case "cli:azure_pipelines":
+ return {
+ icon: ,
+ label: "CLI (Azure Pipelines)",
+ };
+ case "cli:bitbucket_pipelines":
+ return {
+ icon: ,
+ label: "CLI (Bitbucket Pipelines)",
+ };
+ case "cli:travis_ci":
+ return {
+ icon: ,
+ label: "CLI (Travis CI)",
+ };
+ case "cli:buildkite":
+ return {
+ icon: ,
+ label: "CLI (Buildkite)",
+ };
+ case "cli:ci_other":
+ return {
+ icon: ,
+ label: "CLI (CI)",
+ };
+ case "git_integration:github":
+ return {
+ icon: ,
+ label: "GitHub Integration",
+ };
+ case "dashboard":
+ return {
+ icon: ,
+ label: "Dashboard",
+ };
+ default:
+ // Handle any unknown values gracefully
+ if (triggeredVia.startsWith("cli:")) {
+ return {
+ icon: ,
+ label: `CLI (${triggeredVia.replace("cli:", "")})`,
+ };
+ }
+ return {
+ icon: ,
+ label: triggeredVia,
+ };
+ }
+}
+
export default function Page() {
const { deployment, eventStream } = useTypedLoaderData();
const organization = useOrganization();
@@ -408,6 +501,21 @@ export default function Page() {
)}
+
+ Triggered via
+
+ {(() => {
+ const display = getTriggeredViaDisplay(deployment.triggeredVia);
+ if (!display) return "–";
+ return (
+
+ {display.icon}
+ {display.label}
+
+ );
+ })()}
+
+