diff --git a/.changeset/warm-falcons-joke.md b/.changeset/warm-falcons-joke.md new file mode 100644 index 00000000000..845473c1aa2 --- /dev/null +++ b/.changeset/warm-falcons-joke.md @@ -0,0 +1,5 @@ +--- +"@trigger.dev/build": patch +--- + +Add syncSupabaseEnvVars to pull database connection strings and save them as trigger.dev environment variables diff --git a/apps/webapp/app/components/integrations/VercelBuildSettings.tsx b/apps/webapp/app/components/integrations/VercelBuildSettings.tsx index fb6410507c3..3a2da69d7ee 100644 --- a/apps/webapp/app/components/integrations/VercelBuildSettings.tsx +++ b/apps/webapp/app/components/integrations/VercelBuildSettings.tsx @@ -2,6 +2,7 @@ import { Switch } from "~/components/primitives/Switch"; import { Label } from "~/components/primitives/Label"; import { Hint } from "~/components/primitives/Hint"; import { TextLink } from "~/components/primitives/TextLink"; +import { SimpleTooltip } from "~/components/primitives/Tooltip"; import { EnvironmentIcon, environmentFullTitle, @@ -18,6 +19,8 @@ type BuildSettingsFieldsProps = { atomicBuilds: EnvSlug[]; onAtomicBuildsChange: (slugs: EnvSlug[]) => void; envVarsConfigLink?: string; + /** Slugs that should be forced off and disabled, with tooltip reason. */ + disabledEnvSlugs?: Partial>; }; export function BuildSettingsFields({ @@ -29,7 +32,11 @@ export function BuildSettingsFields({ atomicBuilds, onAtomicBuildsChange, envVarsConfigLink, + disabledEnvSlugs, }: BuildSettingsFieldsProps) { + const isSlugDisabled = (slug: EnvSlug) => !!disabledEnvSlugs?.[slug]; + const enabledSlugs = availableEnvSlugs.filter((s) => !isSlugDisabled(s)); + return ( <> {/* Pull env vars before build */} @@ -41,11 +48,11 @@ export function BuildSettingsFields({ 0 && - availableEnvSlugs.every((s) => pullEnvVarsBeforeBuild.includes(s)) + enabledSlugs.length > 0 && + enabledSlugs.every((s) => pullEnvVarsBeforeBuild.includes(s)) } onCheckedChange={(checked) => { - onPullEnvVarsChange(checked ? [...availableEnvSlugs] : []); + onPullEnvVarsChange(checked ? [...enabledSlugs] : []); }} /> )} @@ -63,8 +70,13 @@ export function BuildSettingsFields({
{availableEnvSlugs.map((slug) => { const envType = envSlugToType(slug); - return ( -
+ const disabled = isSlugDisabled(slug); + const disabledReason = disabledEnvSlugs?.[slug]; + const row = ( +
@@ -73,7 +85,8 @@ export function BuildSettingsFields({
{ onPullEnvVarsChange( checked @@ -84,6 +97,12 @@ export function BuildSettingsFields({ />
); + if (disabled && disabledReason) { + return ( + + ); + } + return row; })}
@@ -97,17 +116,17 @@ export function BuildSettingsFields({ 0 && - availableEnvSlugs.every( + enabledSlugs.length > 0 && + enabledSlugs.every( (s) => discoverEnvVars.includes(s) || !pullEnvVarsBeforeBuild.includes(s) ) && - availableEnvSlugs.some((s) => discoverEnvVars.includes(s)) + enabledSlugs.some((s) => discoverEnvVars.includes(s)) } - disabled={!availableEnvSlugs.some((s) => pullEnvVarsBeforeBuild.includes(s))} + disabled={!enabledSlugs.some((s) => pullEnvVarsBeforeBuild.includes(s))} onCheckedChange={(checked) => { onDiscoverEnvVarsChange( checked - ? availableEnvSlugs.filter((s) => pullEnvVarsBeforeBuild.includes(s)) + ? enabledSlugs.filter((s) => pullEnvVarsBeforeBuild.includes(s)) : [] ); }} @@ -122,11 +141,13 @@ export function BuildSettingsFields({
{availableEnvSlugs.map((slug) => { const envType = envSlugToType(slug); + const disabled = isSlugDisabled(slug); + const disabledReason = disabledEnvSlugs?.[slug]; const isPullDisabled = !pullEnvVarsBeforeBuild.includes(slug); - return ( + const row = (
@@ -136,8 +157,8 @@ export function BuildSettingsFields({
{ onDiscoverEnvVarsChange( checked @@ -148,6 +169,12 @@ export function BuildSettingsFields({ />
); + if (disabled && disabledReason) { + return ( + + ); + } + return row; })}
diff --git a/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx b/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx index 6c3e0e3b4df..28bfe5672c6 100644 --- a/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx +++ b/apps/webapp/app/components/integrations/VercelOnboardingModal.tsx @@ -48,6 +48,7 @@ import { vercelAppInstallPath, v3ProjectSettingsIntegrationsPath, githubAppInsta import type { loader } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.vercel"; import { useEffect, useState, useCallback, useRef } from "react"; import { usePostHogTracking } from "~/hooks/usePostHog"; +import { TextLink } from "../primitives/TextLink"; function safeRedirectUrl(url: string): string | null { try { @@ -224,9 +225,10 @@ export function VercelOnboardingModal({ () => availableEnvSlugsForOnboardingBuildSettings ); - // Sync pullEnvVarsBeforeBuild and discoverEnvVars when hasStagingEnvironment becomes true (once) + // Sync pullEnvVarsBeforeBuild and discoverEnvVars when hasStagingEnvironment becomes true + // AND a custom Vercel environment is mapped (once) useEffect(() => { - if (hasStagingEnvironment && !hasSyncedStagingRef.current) { + if (hasStagingEnvironment && vercelStagingEnvironment && !hasSyncedStagingRef.current) { hasSyncedStagingRef.current = true; setPullEnvVarsBeforeBuild((prev) => { if (!prev.includes("stg")) { @@ -241,7 +243,15 @@ export function VercelOnboardingModal({ return prev; }); } - }, [hasStagingEnvironment]); + }, [hasStagingEnvironment, vercelStagingEnvironment]); + + // Strip "stg" from build settings when the staging environment mapping is cleared + useEffect(() => { + if (!vercelStagingEnvironment) { + setPullEnvVarsBeforeBuild((prev) => prev.filter((s) => s !== "stg")); + setDiscoverEnvVars((prev) => prev.filter((s) => s !== "stg")); + } + }, [vercelStagingEnvironment]); // Sync pullEnvVarsBeforeBuild and discoverEnvVars when hasPreviewEnvironment becomes true (once) useEffect(() => { @@ -670,6 +680,11 @@ export function VercelOnboardingModal({ const showBuildSettings = state === "build-settings"; const showGitHubConnection = state === "github-connection"; + const disabledEnvSlugsForBuildSettings = + hasStagingEnvironment && !vercelStagingEnvironment + ? ({ stg: "Map a custom Vercel environment to Staging to enable this" } as Partial>) + : undefined; + return ( { if (!open && !fromMarketplaceContext) { @@ -731,7 +746,7 @@ export function VercelOnboardingModal({ )} - Once connected, your TRIGGER_SECRET_KEY will be + Once connected, your TRIGGER_SECRET_KEY will be automatically synced to Vercel for each environment. @@ -775,6 +790,10 @@ export function VercelOnboardingModal({ Select which custom Vercel environment should map to Trigger.dev's Staging environment. Production and Preview environments are mapped automatically. + If you skip this step, the{" "} + TRIGGER_SECRET_KEY{" "} + will not be installed for the staging environment in Vercel. You can configure this later in + project settings.