Skip to content

Commit 28b6be2

Browse files
authored
feat: introduce run templates for reusing test run configs (#2253)
* Add new prisma model for task run templates * Create run templates in a new service * Add modal to create run templates in the test page * Show templates list and apply values when selected * Hide template creation time in the dropdown list, only show date * Enable deleting run templates * Show success toast on template creation * Validate template label length * Improve the template creation success indicator * Use formAction consistently to differentiate submissions * Type formAction for better editor support * Prettify run template payload and metadata * Add triggerSource, concurrencyKey and ttl to run templates
1 parent dbcf632 commit 28b6be2

File tree

8 files changed

+836
-63
lines changed

8 files changed

+836
-63
lines changed

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

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import { ScheduledTaskPayload, parsePacket, prettyPrintPacket } from "@trigger.dev/core/v3";
2-
import { type RuntimeEnvironmentType, type TaskRunStatus } from "@trigger.dev/database";
2+
import {
3+
type TaskRunTemplate,
4+
type RuntimeEnvironmentType,
5+
type TaskRunStatus,
6+
} from "@trigger.dev/database";
37
import { type PrismaClient, prisma, sqlDatabaseSchema } from "~/db.server";
48
import { getTimezones } from "~/utils/timezones.server";
59
import { findCurrentWorkerDeployment } from "~/v3/models/workerDeployment.server";
610
import { queueTypeFromType } from "./QueueRetrievePresenter.server";
711
import parse from "parse-duration";
812

13+
export type RunTemplate = TaskRunTemplate & {
14+
scheduledTaskPayload?: ScheduledRun["payload"];
15+
};
16+
917
type TestTaskOptions = {
1018
userId: string;
1119
projectId: string;
@@ -40,6 +48,7 @@ export type TestTaskResult =
4048
latestVersions: string[];
4149
disableVersionSelection: boolean;
4250
allowArbitraryQueues: boolean;
51+
taskRunTemplates: TaskRunTemplate[];
4352
}
4453
| {
4554
foundTask: true;
@@ -51,6 +60,7 @@ export type TestTaskResult =
5160
latestVersions: string[];
5261
disableVersionSelection: boolean;
5362
allowArbitraryQueues: boolean;
63+
taskRunTemplates: TaskRunTemplate[];
5464
}
5565
| {
5666
foundTask: false;
@@ -163,6 +173,18 @@ export class TestTaskPresenter {
163173
take: 20, // last 20 versions should suffice
164174
});
165175

176+
const taskRunTemplates = await this.#prismaClient.taskRunTemplate.findMany({
177+
where: {
178+
projectId,
179+
taskSlug: task.slug,
180+
triggerSource: task.triggerSource,
181+
},
182+
orderBy: {
183+
createdAt: "desc",
184+
},
185+
take: 50,
186+
});
187+
166188
const latestVersions = backgroundWorkers.map((v) => v.version);
167189

168190
const disableVersionSelection = environment.type === "DEVELOPMENT";
@@ -247,6 +269,13 @@ export class TestTaskPresenter {
247269
latestVersions,
248270
disableVersionSelection,
249271
allowArbitraryQueues,
272+
taskRunTemplates: await Promise.all(
273+
taskRunTemplates.map(async (t) => ({
274+
...t,
275+
payload: await prettyPrintPacket(t.payload, t.payloadType),
276+
metadata: t.metadata ? await prettyPrintPacket(t.metadata, t.metadataType) : null,
277+
}))
278+
),
250279
};
251280
case "SCHEDULED": {
252281
const possibleTimezones = getTimezones();
@@ -266,7 +295,7 @@ export class TestTaskPresenter {
266295
runs: (
267296
await Promise.all(
268297
latestRuns.map(async (r) => {
269-
const payload = await getScheduleTaskRunPayload(r);
298+
const payload = await getScheduleTaskRunPayload(r.payload, r.payloadType);
270299

271300
if (payload.success) {
272301
return {
@@ -281,6 +310,21 @@ export class TestTaskPresenter {
281310
latestVersions,
282311
disableVersionSelection,
283312
allowArbitraryQueues,
313+
taskRunTemplates: await Promise.all(
314+
taskRunTemplates.map(async (t) => {
315+
const scheduledTaskPayload = t.payload
316+
? await getScheduleTaskRunPayload(t.payload, t.payloadType)
317+
: undefined;
318+
319+
return {
320+
...t,
321+
scheduledTaskPayload:
322+
scheduledTaskPayload && scheduledTaskPayload.success
323+
? scheduledTaskPayload.data
324+
: undefined,
325+
};
326+
})
327+
),
284328
};
285329
}
286330
default: {
@@ -290,11 +334,11 @@ export class TestTaskPresenter {
290334
}
291335
}
292336

293-
async function getScheduleTaskRunPayload(run: RawRun) {
294-
const payload = await parsePacket({ data: run.payload, dataType: run.payloadType });
295-
if (!payload.timezone) {
296-
payload.timezone = "UTC";
337+
async function getScheduleTaskRunPayload(payload: string, payloadType: string) {
338+
const packet = await parsePacket({ data: payload, dataType: payloadType });
339+
if (!packet.timezone) {
340+
packet.timezone = "UTC";
297341
}
298-
const parsed = ScheduledTaskPayload.safeParse(payload);
342+
const parsed = ScheduledTaskPayload.safeParse(packet);
299343
return parsed;
300344
}

0 commit comments

Comments
 (0)