Skip to content

Commit 465529a

Browse files
committed
Merge remote-tracking branch 'origin/main' into kapa-ai-widget
2 parents 3877019 + 4a83032 commit 465529a

File tree

105 files changed

+4365
-2115
lines changed

Some content is hidden

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

105 files changed

+4365
-2115
lines changed

.changeset/green-lions-relate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/sdk": patch
3+
---
4+
5+
The envvars.list() and retrieve() functions receive isSecret for each value. Secret values are always redacted.

.changeset/pre.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"changesets": [
2020
"breezy-turtles-talk",
2121
"four-needles-add",
22+
"green-lions-relate",
2223
"honest-files-decide",
2324
"late-chairs-ring",
2425
"moody-squids-count",
@@ -27,6 +28,10 @@
2728
"red-wasps-cover",
2829
"shiny-kiwis-beam",
2930
"smart-coins-hammer",
31+
"sour-mirrors-accept",
32+
"tiny-buckets-teach",
33+
"tricky-houses-invite",
34+
"two-tigers-dream",
3035
"weak-jobs-hide"
3136
]
3237
}

.changeset/sour-mirrors-accept.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"trigger.dev": patch
3+
"@trigger.dev/core": patch
4+
---
5+
6+
Improve usage flushing

.changeset/tiny-buckets-teach.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+
Fix stalled run detection

.changeset/tricky-houses-invite.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"trigger.dev": patch
3+
"@trigger.dev/core": patch
4+
---
5+
6+
Managed run controller performance and reliability improvements

.changeset/two-tigers-dream.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/sdk": patch
3+
---
4+
5+
maintain proper context in metadata.root and parent getters

.configs/tsconfig.base.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
"strict": true,
1212
"alwaysStrict": true,
13-
"strictPropertyInitialization": false,
13+
"strictPropertyInitialization": true,
1414
"skipLibCheck": true,
1515
"forceConsistentCasingInFileNames": true,
1616
"noUnusedLocals": false,

apps/supervisor/src/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const Env = z.object({
2727
RUNNER_HEARTBEAT_INTERVAL_SECONDS: z.coerce.number().optional(),
2828
RUNNER_SNAPSHOT_POLL_INTERVAL_SECONDS: z.coerce.number().optional(),
2929
RUNNER_ADDITIONAL_ENV_VARS: AdditionalEnvVars, // optional (csv)
30+
RUNNER_DOCKER_AUTOREMOVE: BoolEnv.default(true),
3031

3132
// Dequeue settings (provider mode)
3233
TRIGGER_DEQUEUE_ENABLED: BoolEnv.default("true"),

apps/supervisor/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ManagedSupervisor {
6666
heartbeatIntervalSeconds: env.RUNNER_HEARTBEAT_INTERVAL_SECONDS,
6767
snapshotPollIntervalSeconds: env.RUNNER_SNAPSHOT_POLL_INTERVAL_SECONDS,
6868
additionalEnvVars: env.RUNNER_ADDITIONAL_ENV_VARS,
69+
dockerAutoremove: env.RUNNER_DOCKER_AUTOREMOVE,
6970
} satisfies WorkloadManagerOptions;
7071

7172
if (this.isKubernetes) {

apps/supervisor/src/services/podCleaner.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { SimpleStructuredLogger } from "@trigger.dev/core/v3/utils/structuredLogger";
22
import { K8sApi } from "../clients/kubernetes.js";
33
import { createK8sApi } from "../clients/kubernetes.js";
4-
import { HeartbeatService } from "@trigger.dev/core/v3";
4+
import { IntervalService } from "@trigger.dev/core/v3";
55
import { Counter, Gauge, Registry } from "prom-client";
66
import { register } from "../metrics.js";
77

@@ -19,7 +19,7 @@ export class PodCleaner {
1919
private readonly namespace: string;
2020

2121
private readonly batchSize: number;
22-
private readonly deletionHeartbeat: HeartbeatService;
22+
private readonly deletionInterval: IntervalService;
2323

2424
// Metrics
2525
private readonly register: Registry;
@@ -32,10 +32,10 @@ export class PodCleaner {
3232
this.namespace = opts.namespace;
3333
this.batchSize = opts.batchSize ?? 500;
3434

35-
this.deletionHeartbeat = new HeartbeatService({
35+
this.deletionInterval = new IntervalService({
3636
intervalMs: opts.intervalMs ?? 10000,
3737
leadingEdge: true,
38-
heartbeat: this.deleteCompletedPods.bind(this),
38+
onInterval: this.deleteCompletedPods.bind(this),
3939
});
4040

4141
// Initialize metrics
@@ -57,11 +57,11 @@ export class PodCleaner {
5757
}
5858

5959
async start() {
60-
this.deletionHeartbeat.start();
60+
this.deletionInterval.start();
6161
}
6262

6363
async stop() {
64-
this.deletionHeartbeat.stop();
64+
this.deletionInterval.stop();
6565
}
6666

6767
private async deleteCompletedPods() {

apps/supervisor/src/workloadManager/docker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ export class DockerWorkloadManager implements WorkloadManager {
4343
`--name=${runnerId}`,
4444
];
4545

46+
if (this.opts.dockerAutoremove) {
47+
runArgs.push("--rm");
48+
}
49+
4650
if (this.opts.warmStartUrl) {
4751
runArgs.push(`--env=TRIGGER_WARM_START_URL=${this.opts.warmStartUrl}`);
4852
}

apps/supervisor/src/workloadManager/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface WorkloadManagerOptions {
1010
heartbeatIntervalSeconds?: number;
1111
snapshotPollIntervalSeconds?: number;
1212
additionalEnvVars?: Record<string, string>;
13+
dockerAutoremove?: boolean;
1314
}
1415

1516
export interface WorkloadManager {

apps/supervisor/src/workloadServer/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
452452
logger.debug("runConnected", { ...getSocketMetadata() });
453453

454454
// If there's already a run ID set, we should "disconnect" it from this socket
455-
if (socket.data.runFriendlyId) {
455+
if (socket.data.runFriendlyId && socket.data.runFriendlyId !== friendlyId) {
456456
logger.debug("runConnected: disconnecting existing run", {
457457
...getSocketMetadata(),
458458
newRunId: friendlyId,

apps/webapp/app/components/Feedback.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { conform, useForm } from "@conform-to/react";
22
import { parse } from "@conform-to/zod";
3-
import { InformationCircleIcon } from "@heroicons/react/20/solid";
3+
import { InformationCircleIcon, ArrowUpCircleIcon } from "@heroicons/react/20/solid";
44
import { EnvelopeIcon } from "@heroicons/react/24/solid";
55
import { Form, useActionData, useLocation, useNavigation } from "@remix-run/react";
66
import { type ReactNode, useEffect, useState } from "react";
@@ -64,7 +64,9 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
6464
How can we help? We read every message and will respond as quickly as we can.
6565
</Paragraph>
6666
</div>
67-
<hr className="border-charcoal-800" />
67+
{!(type === "feature" || type === "help" || type === "concurrency") && (
68+
<hr className="border-grid-dimmed" />
69+
)}
6870
<Form method="post" action="/resources/feedback" {...form.props} className="w-full">
6971
<Fieldset className="max-w-full gap-y-3">
7072
<input value={location.pathname} {...conform.input(path, { type: "hidden" })} />
@@ -97,6 +99,19 @@ export function Feedback({ button, defaultValue = "bug" }: FeedbackProps) {
9799
</Paragraph>
98100
</InfoPanel>
99101
)}
102+
{type === "concurrency" && (
103+
<InfoPanel
104+
icon={ArrowUpCircleIcon}
105+
iconClassName="text-indigo-500"
106+
panelClassName="w-full mb-2"
107+
>
108+
<Paragraph variant="small">
109+
How much extra concurrency do you need? You can add bundles of 50 for
110+
$50/month each. To help us advise you, please let us know what your tasks do,
111+
your typical run volume, and if your workload is spiky (many runs at once).
112+
</Paragraph>
113+
</InfoPanel>
114+
)}
100115
<Select
101116
{...conform.select(feedbackType)}
102117
variant="tertiary/medium"

apps/webapp/app/components/primitives/CopyableText.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function CopyableText({ value, className }: { value: string; className?:
5151
)}
5252
</span>
5353
}
54-
content={copied ? "Copied!" : "Copy text"}
54+
content={copied ? "Copied!" : "Copy"}
5555
className="font-sans"
5656
disableHoverableContent
5757
/>

apps/webapp/app/components/primitives/Switch.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ const variations = {
3333
"transition group-hover:text-text-bright group-disabled:group-hover:text-text-dimmed"
3434
),
3535
},
36+
medium: {
37+
container:
38+
"flex items-center gap-x-2 rounded-md hover:bg-tertiary py-1.5 px-2 transition focus-custom",
39+
root: "h-4 w-8",
40+
thumb: "size-3.5 data-[state=checked]:translate-x-3.5 data-[state=unchecked]:translate-x-0",
41+
text: "text-sm text-text-dimmed",
42+
},
3643
};
3744

3845
type SwitchProps = React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {

apps/webapp/app/components/primitives/Table.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ export const TableCellMenu = forwardRef<
349349
variants[variant].menuButtonDivider
350350
)}
351351
>
352-
<div className={cn("flex items-center gap-x-0.5")}>{hiddenButtons}</div>
352+
<div className={cn("flex items-center gap-x-0.5 divide-x divide-grid-bright")}>
353+
{hiddenButtons}
354+
</div>
353355
</div>
354356
)}
355357
{/* Always visible buttons */}

apps/webapp/app/components/runs/v3/ReplayRunDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { InputGroup } from "~/components/primitives/InputGroup";
1111
import { Label } from "~/components/primitives/Label";
1212
import { Paragraph } from "~/components/primitives/Paragraph";
1313
import { Select, SelectItem } from "~/components/primitives/Select";
14-
import { ButtonSpinner, Spinner } from "~/components/primitives/Spinner";
14+
import { Spinner, SpinnerWhite } from "~/components/primitives/Spinner";
1515
import { type loader } from "~/routes/resources.taskruns.$runParam.replay";
1616

1717
type ReplayRunDialogProps = {
@@ -157,7 +157,7 @@ function ReplayForm({
157157
<Button
158158
type="submit"
159159
variant="primary/medium"
160-
LeadingIcon={isSubmitting ? ButtonSpinner : undefined}
160+
LeadingIcon={isSubmitting ? SpinnerWhite : undefined}
161161
disabled={isSubmitting}
162162
shortcut={{ modifiers: ["mod"], key: "enter", enabledOnInputElements: true }}
163163
>

apps/webapp/app/presenters/v3/EnvironmentVariablesPresenter.server.ts

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { flipCauseOption } from "effect/Cause";
12
import { PrismaClient, prisma } from "~/db.server";
23
import { Project } from "~/models/project.server";
34
import { User } from "~/models/user.server";
@@ -48,6 +49,7 @@ export class EnvironmentVariablesPresenter {
4849
key: true,
4950
},
5051
},
52+
isSecret: true,
5153
},
5254
},
5355
},
@@ -82,34 +84,43 @@ export class EnvironmentVariablesPresenter {
8284
},
8385
});
8486

85-
const sortedEnvironments = sortEnvironments(filterOrphanedEnvironments(environments));
87+
const sortedEnvironments = sortEnvironments(filterOrphanedEnvironments(environments)).filter(
88+
(e) => e.orgMember?.userId === userId || e.orgMember === null
89+
);
8690

8791
const repository = new EnvironmentVariablesRepository(this.#prismaClient);
8892
const variables = await repository.getProject(project.id);
8993

9094
return {
91-
environmentVariables: environmentVariables.map((environmentVariable) => {
92-
const variable = variables.find((v) => v.key === environmentVariable.key);
95+
environmentVariables: environmentVariables
96+
.flatMap((environmentVariable) => {
97+
const variable = variables.find((v) => v.key === environmentVariable.key);
9398

94-
return {
95-
id: environmentVariable.id,
96-
key: environmentVariable.key,
97-
values: sortedEnvironments.reduce((previous, env) => {
99+
return sortedEnvironments.flatMap((env) => {
98100
const val = variable?.values.find((v) => v.environment.id === env.id);
99-
previous[env.id] = {
100-
value: val?.value,
101-
environment: { type: env.type, id: env.id },
102-
};
103-
return { ...previous };
104-
}, {} as Record<string, { value: string | undefined; environment: { type: string; id: string } }>),
105-
};
106-
}),
107-
environments: sortedEnvironments
108-
.filter((e) => e.orgMember?.userId === userId || e.orgMember === null)
109-
.map((environment) => ({
110-
id: environment.id,
111-
type: environment.type,
112-
})),
101+
const isSecret =
102+
environmentVariable.values.find((v) => v.environmentId === env.id)?.isSecret ?? false;
103+
104+
if (!val) {
105+
return [];
106+
}
107+
108+
return [
109+
{
110+
id: environmentVariable.id,
111+
key: environmentVariable.key,
112+
environment: { type: env.type, id: env.id },
113+
value: isSecret ? "" : val.value,
114+
isSecret,
115+
},
116+
];
117+
});
118+
})
119+
.sort((a, b) => a.key.localeCompare(b.key)),
120+
environments: sortedEnvironments.map((environment) => ({
121+
id: environment.id,
122+
type: environment.type,
123+
})),
113124
hasStaging: environments.some((environment) => environment.type === "STAGING"),
114125
};
115126
}

apps/webapp/app/presenters/v3/ScheduleListPresenter.server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export class ScheduleListPresenter extends BasePresenter {
163163
},
164164
active: true,
165165
lastRunTriggeredAt: true,
166+
createdAt: true,
166167
},
167168
where: {
168169
projectId: project.id,
@@ -206,6 +207,9 @@ export class ScheduleListPresenter extends BasePresenter {
206207
}
207208
: undefined,
208209
},
210+
orderBy: {
211+
createdAt: "desc",
212+
},
209213
take: pageSize,
210214
skip: (page - 1) * pageSize,
211215
});

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ function TaskActivityGraph({ activity }: { activity: TaskActivity }) {
545545
<Bar dataKey="SYSTEM_FAILURE" fill="#F43F5E" stackId="a" strokeWidth={0} barSize={10} />
546546
<Bar dataKey="PAUSED" fill="#FCD34D" stackId="a" strokeWidth={0} barSize={10} />
547547
<Bar dataKey="CRASHED" fill="#F43F5E" stackId="a" strokeWidth={0} barSize={10} />
548+
<Bar dataKey="EXPIRED" fill="#F43F5E" stackId="a" strokeWidth={0} barSize={10} />
549+
<Bar dataKey="TIMED_OUT" fill="#F43F5E" stackId="a" strokeWidth={0} barSize={10} />
548550
</BarChart>
549551
</ResponsiveContainer>
550552
);

0 commit comments

Comments
 (0)