From 4dabfca1d599c142cd12f488f173e8d0af9df174 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 19 Aug 2026 13:44:55 +0100 Subject: [PATCH] feat(webapp,cli,core): list production project runtime updates (#4659) --- .changeset/list-project-runtime-updates.md | 6 + .../OrganizationSettingsSideMenu.tsx | 20 ++ .../components/primitives/ClipboardField.tsx | 3 +- .../app/components/primitives/CopyButton.tsx | 2 +- .../app/components/primitives/Label.tsx | 7 +- .../components/primitives/SettingsLayout.tsx | 14 +- apps/webapp/app/routes/[_].$.ts | 24 +- .../RuntimeUpdatesPage.tsx | 212 ++++++++++++++++++ .../route.tsx | 82 +++++++ .../route.tsx | 54 ++++- .../app/routes/api.v1.projects.runtimes.ts | 17 ++ .../services/projectRuntimeUpdates.server.ts | 130 +++++++++++ apps/webapp/app/utils/deeplinkPages.test.ts | 11 + apps/webapp/app/utils/deeplinkPages.ts | 19 +- apps/webapp/app/utils/pathBuilder.ts | 4 + packages/cli-v3/src/apiClient.ts | 14 ++ packages/cli-v3/src/cli/index.ts | 2 + .../cli-v3/src/commands/projects/index.ts | 10 + packages/cli-v3/src/commands/projects/list.ts | 95 ++++++++ packages/core/src/v3/schemas/api-type.test.ts | 21 +- packages/core/src/v3/schemas/api.ts | 47 ++++ 21 files changed, 770 insertions(+), 24 deletions(-) create mode 100644 .changeset/list-project-runtime-updates.md create mode 100644 apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.runtime-updates/RuntimeUpdatesPage.tsx create mode 100644 apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.runtime-updates/route.tsx create mode 100644 apps/webapp/app/routes/api.v1.projects.runtimes.ts create mode 100644 apps/webapp/app/services/projectRuntimeUpdates.server.ts create mode 100644 packages/cli-v3/src/commands/projects/index.ts create mode 100644 packages/cli-v3/src/commands/projects/list.ts diff --git a/.changeset/list-project-runtime-updates.md b/.changeset/list-project-runtime-updates.md new file mode 100644 index 000000000..fe8c74797 --- /dev/null +++ b/.changeset/list-project-runtime-updates.md @@ -0,0 +1,6 @@ +--- +"trigger.dev": patch +"@trigger.dev/core": patch +--- + +List the current Production runtime for every accessible project with `trigger projects list`. Add `--needs-update` to identify projects currently running Node.js 21. diff --git a/apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx b/apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx index 465346ad1..56b988e3e 100644 --- a/apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx +++ b/apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx @@ -2,6 +2,7 @@ import { ArrowLeftIcon } from "@heroicons/react/24/solid"; import { BellIcon } from "~/assets/icons/BellIcon"; import { ChainLinkIcon } from "~/assets/icons/ChainLinkIcon"; import { CreditCardIcon } from "~/assets/icons/CreditCardIcon"; +import { FolderOpenIcon } from "~/assets/icons/FolderOpenIcon"; import { PadlockIcon } from "~/assets/icons/PadlockIcon"; import { UsageIcon } from "~/assets/icons/UsageIcon"; import { RolesIcon } from "~/assets/icons/RolesIcon"; @@ -16,6 +17,7 @@ import { cn } from "~/utils/cn"; import { organizationPath, organizationRolesPath, + organizationRuntimeUpdatesPath, organizationSettingsPath, organizationSlackIntegrationPath, organizationSsoPath, @@ -49,11 +51,13 @@ export function OrganizationSettingsSideMenu({ buildInfo, isUsingPlugin, isSsoUsingPlugin, + hasProjectRuntimeUpdate, }: { organization: MatchedOrganization; buildInfo: BuildInfo; isUsingPlugin: boolean; isSsoUsingPlugin: boolean; + hasProjectRuntimeUpdate: boolean; }) { const { isManagedCloud } = useFeatures(); const featureFlags = useFeatureFlags(); @@ -127,6 +131,22 @@ export function OrganizationSettingsSideMenu({ ) : null} )} + + + Runtime update available. + + ) : undefined + } + /> { diff --git a/apps/webapp/app/components/primitives/CopyButton.tsx b/apps/webapp/app/components/primitives/CopyButton.tsx index 91d47c296..c855d4ad1 100644 --- a/apps/webapp/app/components/primitives/CopyButton.tsx +++ b/apps/webapp/app/components/primitives/CopyButton.tsx @@ -50,7 +50,7 @@ export function CopyButton({ onClick={copy} className={cn( buttonSize, - "flex items-center justify-center rounded border border-border-bright bg-background-hover", + "flex shrink-0 items-center justify-center rounded border border-border-bright bg-background-hover", copied ? "text-green-500" : "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright", diff --git a/apps/webapp/app/components/primitives/Label.tsx b/apps/webapp/app/components/primitives/Label.tsx index 7213d5220..da27dee7e 100644 --- a/apps/webapp/app/components/primitives/Label.tsx +++ b/apps/webapp/app/components/primitives/Label.tsx @@ -2,7 +2,8 @@ import * as React from "react"; import { cn } from "~/utils/cn"; import { InfoIconTooltip } from "./Tooltip"; -const variants = { +// Non-form labels (e.g. settings row titles) share this typography, so it is exported. +export const labelVariants = { small: { text: "font-sans text-[0.8125rem] font-normal text-text-bright leading-tight flex items-center gap-1", }, @@ -17,7 +18,7 @@ const variants = { type LabelProps = React.AllHTMLAttributes & { className?: string; children: React.ReactNode; - variant?: keyof typeof variants; + variant?: keyof typeof labelVariants; required?: boolean; tooltip?: React.ReactNode; }; @@ -30,7 +31,7 @@ export function Label({ tooltip, ...props }: LabelProps) { - const variation = variants[variant]; + const variation = labelVariants[variant]; return (