Skip to content

Commit 068c024

Browse files
Preview branches (#2086)
* Initial preview migrations * Modified the staging endpoint to create preview environments * Added isBranchableEnvironment to RuntimeEnvironment * Staging = yellow Preview = orange * Changed the env sort order * Set isBranchableEnvironment correctly. Create preview for new projects * Very basic branch menu * Creating branches from the dashboard * Fix for string icons on project delete page * Don’t show branch API keys * WIP on the manage branches page * RuntimeEnvironment added projectId index * Only create the parentEnvironmentId column if it doesn’t exist already * Improved the limit wording * Add search to the branch list * contains in both places * Many style improvements * Branch dropdown and v4 badge * Arching/unarchive branches working in the dashboard * Tidied imports * Change preview slug from `prev` to `preview` * Use correct color for side menu preview branch icon * Upsert the branch and use the shortcode as a unique constraint * Upserting working with nice messages in the dashboard * Better errors when upserting branches * Button shortcut, don’t allow event to propagate * Better duplicate error message * Filter out archived branches from the env selector * Archiving/creating tweaked some more * Add an archived banner to the app, fixes for archived branches and upsells * Fixed pagination * Disable editing schedules, pausing queues, testing tasks * Don’t allow replaying if the env is archived * When deploying detect the correct environment * Get the projectClient when there’s a branch * createGitMeta function, most code from the vercel CLI repo * Deploy, getting the correct environment client * Added git column to WorkerDeployment * Add GitMeta to core schemas * Create branch when deploying * WIP on branch support in the API * Delete old createTaskRunAttempt fn * apiAuth remove export from internal functions * Rename env var to “TRIGGER_PREVIEW_BRANCH” * Add TRIGGER_PREVIEW_BRANCH to resolved env vars for runs * First preview deploy and run working * Set the preview branch in the main SDK * Added git links to the preview branches table * Better errors when replaying/testing archived branches * Don’t dequeue archived environments * Env var resolution with parent environment * Hello world default machine small-2x to save my memory * Fix for more env var functions * Only return non-archived envs * Switch to controlled state for the checkboxes * Uncheck everything when PREVIEW is checked * WIP on branch UI * Show the preview branch label on the env vars list * Fix for overriding env vars * Adding preview branch env vars working * Progress on new env vars * Only allow selecting a single branch * Layout fix when there are errors * Set the defaultValue so there are some fields * Conform fix for team invite page * Archived environments don’t run scheduled tasks * Added Git data to deployments * Added git data to the deployment inspector * Don’t allow upserting schedules when archived * Deduplicate and blacklist some env vars * Fix for wrong conform function being used * Show a better error if all vars were blacklisted * Added environment variable search (by key and value) * Improved preview branch icon * Replay now supports branches * Schedule page render branches properly * Show the env icon in bottom-left of the test page * When editing older schedules (that have multi-env) show preview branches correctly * Fix for incorrect disallowed branch name character * Extract and improve the directory verification code * WIP for CLI preview archive command * Improved the preview branch action buttons * Redirect to the project if we don’t find a matching env * Archiving branch via the CLI working * Fix for archiving branches * Public access token test task * JWTs working are with preview branches * Add branch and git data to the Run ctx * Updated GitMeta functions to work in CI * Added pullRequestState * Archive when deploying if the PR is closed/merged * Fix for the changesets guide * Fix for CLI dev bug introduced * CLI promote now supports preview branches * Add PR title. Reordered them and added tooltips * syncEnvVars working with branches * Added preview branch support to syncVercelEnvVars() * Detect the branch from Vercel env var (set during build) * Allow passing a branch in * Use process.env.VERCEL_TOKEN as well… this used in Vercel CI * Temp delete * Improved regenerate api key modal * Added Accordion component (with styles) * Redesigned the API keys page * Revert "Temp delete" This reverts commit 177b92c. * Changeset * Fixed docs link * The new branch panel closes when a branch is created * Update apps/webapp/app/services/upsertBranch.server.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Removed findUniques from WorkerGroupTokenService * Made the parentEnvironmentId migrations safe * Latest lockfile * Update packages/cli-v3/src/commands/workers/build.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Move isValidGitBranchName to a separate file * Move the sanitize fn too * removeBlacklistedVariables moved to a separate file * Moved deduplicateVariableArray to a separate file… * Fix broken sanitizeBranchName import * Another import fix… * Improved blacklisted error message * SImplified migration to use `ADD COLUMN IF NOT EXISTS "parentEnvironmentId" TEXT` --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent b74c000 commit 068c024

File tree

122 files changed

+4809
-782
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+4809
-782
lines changed

.changeset/silly-cows-serve.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Added support for Preview branches in v4 projects

CHANGESETS.md

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,14 @@ Please follow the best-practice of adding changesets in the same commit as the c
3030

3131
## Snapshot instructions
3232

33-
!MAKE SURE TO UPDATE THE TAG IN THE INSTRUCTIONS BELOW!
33+
1. Delete the `.changeset/pre.json` file (if it exists)
3434

35-
1. Add changesets as usual
35+
2. Do a temporary commit (do NOT push this, you should undo it after)
3636

37-
```sh
38-
pnpm run changeset:add
39-
```
37+
3. Copy the `GITHUB_TOKEN` line from the .env file
4038

41-
2. Create a snapshot version (replace "prerelease" with your tag)
39+
4. Run `GITHUB_TOKEN=github_pat_12345 ./scripts/publish-prerelease.sh re2`
4240

43-
```sh
44-
pnpm exec changeset version --snapshot prerelease
45-
```
41+
Make sure to replace the token with yours. `re2` is the tag that will be used for the pre-release.
4642

47-
3. Build the packages:
48-
49-
```sh
50-
pnpm run build --filter "@trigger.dev/*" --filter "trigger.dev"
51-
```
52-
53-
4. Publish the snapshot (replace "dev" with your tag)
54-
55-
```sh
56-
pnpm exec changeset publish --no-git-tag --snapshot --tag prerelease
57-
```
43+
5. Undo the commit where you deleted the pre.json file.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export function ArchiveIcon({ className }: { className?: string }) {
2+
return (
3+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
4+
<g clipPath="url(#clip0_17398_782)">
5+
<path
6+
d="M19.2293 9C20.1562 9.00001 20.8612 9.83278 20.7088 10.7471L19.2781 19.3291C19.1173 20.2933 18.283 21 17.3055 21H6.69416C5.71662 21 4.88235 20.2933 4.7215 19.3291L3.29084 10.7471C3.13848 9.83289 3.8436 9.00021 4.77033 9H19.2293ZM9.95002 12.5C9.12179 12.5002 8.45002 13.1717 8.45002 14C8.45002 14.8283 9.12179 15.4998 9.95002 15.5H13.95L14.1033 15.4922C14.8597 15.4154 15.45 14.7767 15.45 14C15.45 13.2233 14.8597 12.5846 14.1033 12.5078L13.95 12.5H9.95002Z"
7+
fill="currentColor"
8+
/>
9+
<rect x="2" y="3" width="20" height="4" rx="1" fill="currentColor" />
10+
</g>
11+
<defs>
12+
<clipPath id="clip0_17398_782">
13+
<rect width="24" height="24" fill="currentColor" />
14+
</clipPath>
15+
</defs>
16+
</svg>
17+
);
18+
}
19+
20+
export function UnarchiveIcon({ className }: { className?: string }) {
21+
return (
22+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
23+
<g clipPath="url(#clip0_17398_66731)">
24+
<path
25+
d="M19.2027 10C20.1385 10 20.8456 10.8478 20.6782 11.7686L19.2984 19.3574C19.1254 20.3084 18.2972 21 17.3306 21H6.66945C5.70287 21 4.87458 20.3084 4.70167 19.3574L3.32179 11.7686C3.15438 10.8478 3.86152 10 4.79738 10H10.9995V16C10.9995 16.5521 11.4475 16.9997 11.9995 17C12.5518 17 12.9995 16.5523 12.9995 16V10H19.2027Z"
26+
fill="currentColor"
27+
/>
28+
<rect x="11" y="4" width="2" height="6" fill="currentColor" />
29+
<path
30+
d="M15.5 6.5L12 3L8.5 6.5"
31+
stroke="currentColor"
32+
strokeWidth="2"
33+
strokeLinecap="round"
34+
strokeLinejoin="round"
35+
/>
36+
</g>
37+
<defs>
38+
<clipPath id="clip0_17398_66731">
39+
<rect width="24" height="24" fill="currentColor" />
40+
</clipPath>
41+
</defs>
42+
</svg>
43+
);
44+
}

apps/webapp/app/assets/icons/EnvironmentIcons.tsx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function ProdEnvironmentIcon({ className }: { className?: string }) {
7575
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
7676
<path
7777
d="M12.5037 7.33603C12.3174 6.88799 11.6827 6.88799 11.4963 7.33603L10.4338 9.89064L7.6759 10.1117C7.1922 10.1505 6.99606 10.7542 7.36459 11.0698L9.46583 12.8698L8.82387 15.561C8.71128 16.033 9.22477 16.4061 9.63888 16.1532L12 14.711L14.3612 16.1532C14.7753 16.4061 15.2888 16.0331 15.1762 15.561L14.5343 12.8698L16.6355 11.0698C17.004 10.7542 16.8079 10.1505 16.3242 10.1117L13.5663 9.89064L12.5037 7.33603Z"
78-
fill="white"
78+
fill="currentColor"
7979
/>
8080
<rect
8181
x="3"
@@ -151,3 +151,28 @@ export function DeployedEnvironmentIconSmall({ className }: { className?: string
151151
</svg>
152152
);
153153
}
154+
155+
export function PreviewEnvironmentIconSmall({ className }: { className?: string }) {
156+
return <BranchEnvironmentIconSmall className={className} />;
157+
}
158+
159+
export function BranchEnvironmentIconSmall({ className }: { className?: string }) {
160+
return (
161+
<svg className={className} viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
162+
<path
163+
d="M2.23059 7C1.65409 6.99967 1.30545 6.36259 1.61634 5.87695L3.88489 2.33301C4.17195 1.88466 4.82727 1.88472 5.11438 2.33301L7.38294 5.87695C7.69386 6.36265 7.34531 6.99982 6.76868 7L2.23059 7Z"
164+
fill="currentColor"
165+
/>
166+
<path
167+
d="M3.5 6H5.5V15C5.5 15.5523 5.05228 16 4.5 16C3.94772 16 3.5 15.5523 3.5 15V6Z"
168+
fill="currentColor"
169+
/>
170+
<path
171+
d="M13.5 7V7.5C13.5 9.15685 12.1569 10.5 10.5 10.5H7.5C5.84315 10.5 4.5 11.8431 4.5 13.5V15"
172+
stroke="currentColor"
173+
strokeWidth="2"
174+
/>
175+
<circle cx="13.5" cy="5" r="2" stroke="currentColor" strokeWidth="2" />
176+
</svg>
177+
);
178+
}

apps/webapp/app/assets/icons/IntegrationIcon.tsx

Lines changed: 0 additions & 5 deletions
This file was deleted.

apps/webapp/app/components/BlankStatePanels.tsx

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { useProject } from "~/hooks/useProject";
1818
import { type MinimumEnvironment } from "~/presenters/SelectBestEnvironmentPresenter.server";
1919
import {
2020
docsPath,
21+
v3BillingPath,
2122
v3EnvironmentPath,
2223
v3EnvironmentVariablesPath,
2324
v3NewProjectAlertPath,
@@ -36,6 +37,11 @@ import { TextLink } from "./primitives/TextLink";
3637
import { InitCommandV3, PackageManagerProvider, TriggerDevStepV3 } from "./SetupCommands";
3738
import { StepContentContainer } from "./StepContentContainer";
3839
import { WaitpointTokenIcon } from "~/assets/icons/WaitpointTokenIcon";
40+
import { BranchEnvironmentIconSmall } from "~/assets/icons/EnvironmentIcons";
41+
import { useFeatures } from "~/hooks/useFeatures";
42+
import { DialogContent, DialogTrigger, Dialog } from "./primitives/Dialog";
43+
import { V4Badge } from "./V4Badge";
44+
import { NewBranchPanel } from "~/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route";
3945

4046
export function HasNoTasksDev() {
4147
return (
@@ -431,15 +437,128 @@ export function NoWaitpointTokens() {
431437
);
432438
}
433439

434-
function SwitcherPanel() {
440+
export function BranchesNoBranchableEnvironment() {
441+
const { isManagedCloud } = useFeatures();
442+
const organization = useOrganization();
443+
444+
if (!isManagedCloud) {
445+
return (
446+
<InfoPanel
447+
title="Create a preview environment"
448+
icon={BranchEnvironmentIconSmall}
449+
iconClassName="text-preview"
450+
panelClassName="max-w-full"
451+
>
452+
<Paragraph spacing variant="small">
453+
To add branches you need to have a <InlineCode>RuntimeEnvironment</InlineCode> where{" "}
454+
<InlineCode>isBranchableEnvironment</InlineCode> is true. We recommend creating a
455+
dedicated one using the "PREVIEW" type.
456+
</Paragraph>
457+
</InfoPanel>
458+
);
459+
}
460+
461+
return (
462+
<InfoPanel
463+
title="Upgrade to get preview branches"
464+
icon={BranchEnvironmentIconSmall}
465+
iconClassName="text-preview"
466+
panelClassName="max-w-full"
467+
accessory={
468+
<LinkButton variant="primary/small" to={v3BillingPath(organization)}>
469+
Upgrade
470+
</LinkButton>
471+
}
472+
>
473+
<Paragraph spacing variant="small">
474+
Preview branches in Trigger.dev create isolated environments for testing new features before
475+
production.
476+
</Paragraph>
477+
</InfoPanel>
478+
);
479+
}
480+
481+
export function BranchesNoBranches({
482+
parentEnvironment,
483+
limits,
484+
canUpgrade,
485+
}: {
486+
parentEnvironment: { id: string };
487+
limits: { used: number; limit: number };
488+
canUpgrade: boolean;
489+
}) {
490+
const organization = useOrganization();
491+
492+
if (limits.used >= limits.limit) {
493+
return (
494+
<InfoPanel
495+
title="Upgrade to get preview branches"
496+
icon={BranchEnvironmentIconSmall}
497+
iconClassName="text-preview"
498+
panelClassName="max-w-full"
499+
accessory={
500+
canUpgrade ? (
501+
<LinkButton variant="primary/small" to={v3BillingPath(organization)}>
502+
Upgrade
503+
</LinkButton>
504+
) : (
505+
<Feedback
506+
button={<Button variant="primary/small">Request more</Button>}
507+
defaultValue="help"
508+
/>
509+
)
510+
}
511+
>
512+
<Paragraph spacing variant="small">
513+
You've reached the limit ({limits.used}/{limits.limit}) of branches for your plan. Upgrade
514+
to get branches.
515+
</Paragraph>
516+
</InfoPanel>
517+
);
518+
}
519+
520+
return (
521+
<InfoPanel
522+
title="Create your first branch"
523+
icon={BranchEnvironmentIconSmall}
524+
iconClassName="text-preview"
525+
panelClassName="max-w-full"
526+
accessory={
527+
<NewBranchPanel
528+
button={
529+
<Button
530+
variant="primary/small"
531+
LeadingIcon={PlusIcon}
532+
leadingIconClassName="text-white"
533+
>
534+
New branch
535+
</Button>
536+
}
537+
parentEnvironment={parentEnvironment}
538+
/>
539+
}
540+
>
541+
<Paragraph spacing variant="small">
542+
Branches are a way to test new features in isolation before merging them into the main
543+
environment.
544+
</Paragraph>
545+
<Paragraph spacing variant="small">
546+
Branches are only available when using <V4Badge inline /> or above. Read our{" "}
547+
<TextLink to={docsPath("upgrade-to-v4")}>v4 upgrade guide</TextLink> to learn more.
548+
</Paragraph>
549+
</InfoPanel>
550+
);
551+
}
552+
553+
export function SwitcherPanel({ title = "Switch to a deployed environment" }: { title?: string }) {
435554
const organization = useOrganization();
436555
const project = useProject();
437556
const environment = useEnvironment();
438557

439558
return (
440559
<div className="flex items-center rounded-md border border-grid-bright bg-background-bright p-3">
441560
<Paragraph variant="small" className="grow">
442-
Switch to a deployed environment
561+
{title}
443562
</Paragraph>
444563
<EnvironmentSelector
445564
organization={organization}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { GitPullRequestIcon, GitCommitIcon, GitBranchIcon } from "lucide-react";
2+
import { type GitMetaLinks } from "~/presenters/v3/BranchesPresenter.server";
3+
import { LinkButton } from "./primitives/Buttons";
4+
import { SimpleTooltip } from "./primitives/Tooltip";
5+
6+
export function GitMetadata({ git }: { git?: GitMetaLinks | null }) {
7+
if (!git) return null;
8+
return (
9+
<>
10+
{git.pullRequestUrl && git.pullRequestNumber && <GitMetadataPullRequest git={git} />}
11+
{git.shortSha && <GitMetadataCommit git={git} />}
12+
{git.branchUrl && <GitMetadataBranch git={git} />}
13+
</>
14+
);
15+
}
16+
17+
export function GitMetadataBranch({
18+
git,
19+
}: {
20+
git: Pick<GitMetaLinks, "branchUrl" | "branchName">;
21+
}) {
22+
return (
23+
<SimpleTooltip
24+
button={
25+
<LinkButton
26+
variant="minimal/small"
27+
LeadingIcon={<GitBranchIcon className="size-4" />}
28+
iconSpacing="gap-x-1"
29+
to={git.branchUrl}
30+
className="pl-1"
31+
>
32+
{git.branchName}
33+
</LinkButton>
34+
}
35+
content="Jump to GitHub branch"
36+
/>
37+
);
38+
}
39+
40+
export function GitMetadataCommit({
41+
git,
42+
}: {
43+
git: Pick<GitMetaLinks, "commitUrl" | "shortSha" | "commitMessage">;
44+
}) {
45+
return (
46+
<SimpleTooltip
47+
button={
48+
<LinkButton
49+
variant="minimal/small"
50+
to={git.commitUrl}
51+
LeadingIcon={<GitCommitIcon className="size-4" />}
52+
iconSpacing="gap-x-1"
53+
className="pl-1"
54+
>
55+
{`${git.shortSha} / ${git.commitMessage}`}
56+
</LinkButton>
57+
}
58+
content="Jump to GitHub commit"
59+
/>
60+
);
61+
}
62+
63+
export function GitMetadataPullRequest({
64+
git,
65+
}: {
66+
git: Pick<GitMetaLinks, "pullRequestUrl" | "pullRequestNumber" | "pullRequestTitle">;
67+
}) {
68+
if (!git.pullRequestUrl || !git.pullRequestNumber) return null;
69+
70+
return (
71+
<SimpleTooltip
72+
button={
73+
<LinkButton
74+
variant="minimal/small"
75+
to={git.pullRequestUrl}
76+
LeadingIcon={<GitPullRequestIcon className="size-4" />}
77+
iconSpacing="gap-x-1"
78+
className="pl-1"
79+
>
80+
#{git.pullRequestNumber} {git.pullRequestTitle}
81+
</LinkButton>
82+
}
83+
content="Jump to GitHub pull request"
84+
/>
85+
);
86+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { cn } from "~/utils/cn";
2+
import { Badge } from "./primitives/Badge";
3+
import { SimpleTooltip } from "./primitives/Tooltip";
4+
5+
export function V4Badge({ inline = false, className }: { inline?: boolean; className?: string }) {
6+
return (
7+
<SimpleTooltip
8+
button={
9+
<Badge variant="extra-small" className={cn(inline ? "inline-grid" : "", className)}>
10+
V4
11+
</Badge>
12+
}
13+
content="This feature is only available in V4 and above."
14+
disableHoverableContent
15+
/>
16+
);
17+
}
18+
19+
export function V4Title({ children }: { children: React.ReactNode }) {
20+
return (
21+
<>
22+
<span>{children}</span>
23+
<V4Badge />
24+
</>
25+
);
26+
}

0 commit comments

Comments
 (0)