Skip to content

Commit 68955dd

Browse files
Merge branch 'main' into issue/ffmpegv7
2 parents a2b0294 + 2812124 commit 68955dd

File tree

140 files changed

+3619
-1256
lines changed

Some content is hidden

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

140 files changed

+3619
-1256
lines changed

.changeset/smart-coins-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
fix: Realtime streams: prevent enqueuing into closed ReadableStream

apps/supervisor/README.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,15 @@
88
api_url=http://localhost:3030
99
wg_name=my-worker
1010

11-
# edit these
11+
# edit this
1212
admin_pat=tr_pat_...
13-
project_id=clsw6q8wz...
1413

1514
curl -sS \
1615
-X POST \
1716
"$api_url/admin/api/v1/workers" \
1817
-H "Authorization: Bearer $admin_pat" \
1918
-H "Content-Type: application/json" \
20-
-d "{
21-
\"name\": \"$wg_name\",
22-
\"makeDefault\": true,
23-
\"projectId\": \"$project_id\"
24-
}"
19+
-d "{\"name\": \"$wg_name\"}"
2520
```
2621

2722
2. Create `.env` and set the worker token
@@ -47,3 +42,26 @@ pnpm exec trigger deploy --self-hosted
4742
# The additional network flag is required on linux
4843
pnpm exec trigger deploy --self-hosted --network host
4944
```
45+
46+
## Additional worker groups
47+
48+
When adding more worker groups you might also want to make them the default for a specific project. This will allow you to test it without having to change the global default:
49+
50+
```sh
51+
api_url=http://localhost:3030
52+
wg_name=my-worker
53+
54+
# edit these
55+
admin_pat=tr_pat_...
56+
project_id=clsw6q8wz...
57+
58+
curl -sS \
59+
-X POST \
60+
"$api_url/admin/api/v1/workers" \
61+
-H "Authorization: Bearer $admin_pat" \
62+
-H "Content-Type: application/json" \
63+
-d "{
64+
\"name\": \"$wg_name\",
65+
\"makeDefaultForProjectId\": \"$project_id\"
66+
}"
67+
```

apps/supervisor/src/env.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
import { randomUUID } from "crypto";
22
import { env as stdEnv } from "std-env";
33
import { z } from "zod";
4-
5-
const BoolEnv = z.preprocess((val) => {
6-
if (typeof val !== "string") {
7-
return val;
8-
}
9-
10-
return ["true", "1"].includes(val.toLowerCase().trim());
11-
}, z.boolean());
4+
import { AdditionalEnvVars, BoolEnv } from "./envUtil.js";
125

136
const Env = z.object({
147
// This will come from `spec.nodeName` in k8s
@@ -26,9 +19,15 @@ const Env = z.object({
2619
.transform((s) => z.enum(["http", "https"]).parse(s.toLowerCase()))
2720
.default("http"),
2821
TRIGGER_WORKLOAD_API_DOMAIN: z.string().optional(), // If unset, will use orchestrator-specific default
22+
TRIGGER_WORKLOAD_API_HOST_INTERNAL: z.string().default("0.0.0.0"),
2923
TRIGGER_WORKLOAD_API_PORT_INTERNAL: z.coerce.number().default(8020), // This is the port the workload API listens on
3024
TRIGGER_WORKLOAD_API_PORT_EXTERNAL: z.coerce.number().default(8020), // This is the exposed port passed to the run controller
3125

26+
// Runner settings
27+
RUNNER_HEARTBEAT_INTERVAL_SECONDS: z.coerce.number().optional(),
28+
RUNNER_SNAPSHOT_POLL_INTERVAL_SECONDS: z.coerce.number().optional(),
29+
RUNNER_ADDITIONAL_ENV_VARS: AdditionalEnvVars, // optional (csv)
30+
3231
// Dequeue settings (provider mode)
3332
TRIGGER_DEQUEUE_ENABLED: BoolEnv.default("true"),
3433
TRIGGER_DEQUEUE_INTERVAL_MS: z.coerce.number().int().default(1000),
@@ -41,6 +40,7 @@ const Env = z.object({
4140
DOCKER_NETWORK: z.string().default("host"),
4241
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().url(),
4342
ENFORCE_MACHINE_PRESETS: z.coerce.boolean().default(false),
43+
KUBERNETES_IMAGE_PULL_SECRETS: z.string().optional(), // csv
4444

4545
// Used by the resource monitor
4646
OVERRIDE_CPU_TOTAL: z.coerce.number().optional(),
@@ -53,7 +53,10 @@ const Env = z.object({
5353
EPHEMERAL_STORAGE_SIZE_REQUEST: z.string().default("2Gi"),
5454

5555
// Metrics
56+
METRICS_ENABLED: BoolEnv.default(true),
5657
METRICS_COLLECT_DEFAULTS: BoolEnv.default(true),
58+
METRICS_HOST: z.string().default("127.0.0.1"),
59+
METRICS_PORT: z.coerce.number().int().default(9090),
5760

5861
// Pod cleaner
5962
POD_CLEANER_ENABLED: BoolEnv.default(true),
@@ -63,6 +66,9 @@ const Env = z.object({
6366
// Failed pod handler
6467
FAILED_POD_HANDLER_ENABLED: BoolEnv.default(true),
6568
FAILED_POD_HANDLER_RECONNECT_INTERVAL_MS: z.coerce.number().int().default(1000),
69+
70+
// Debug
71+
DEBUG: BoolEnv.default(false),
6672
});
6773

6874
export const env = Env.parse(stdEnv);
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { describe, it, expect } from "vitest";
2+
import { BoolEnv, AdditionalEnvVars } from "./envUtil.js";
3+
4+
describe("BoolEnv", () => {
5+
it("should parse string 'true' as true", () => {
6+
expect(BoolEnv.parse("true")).toBe(true);
7+
expect(BoolEnv.parse("TRUE")).toBe(true);
8+
expect(BoolEnv.parse("True")).toBe(true);
9+
});
10+
11+
it("should parse string '1' as true", () => {
12+
expect(BoolEnv.parse("1")).toBe(true);
13+
});
14+
15+
it("should parse string 'false' as false", () => {
16+
expect(BoolEnv.parse("false")).toBe(false);
17+
expect(BoolEnv.parse("FALSE")).toBe(false);
18+
expect(BoolEnv.parse("False")).toBe(false);
19+
});
20+
21+
it("should handle whitespace", () => {
22+
expect(BoolEnv.parse(" true ")).toBe(true);
23+
expect(BoolEnv.parse(" 1 ")).toBe(true);
24+
});
25+
26+
it("should pass through boolean values", () => {
27+
expect(BoolEnv.parse(true)).toBe(true);
28+
expect(BoolEnv.parse(false)).toBe(false);
29+
});
30+
31+
it("should return false for invalid inputs", () => {
32+
expect(BoolEnv.parse("invalid")).toBe(false);
33+
expect(BoolEnv.parse("")).toBe(false);
34+
});
35+
});
36+
37+
describe("AdditionalEnvVars", () => {
38+
it("should parse single key-value pair", () => {
39+
expect(AdditionalEnvVars.parse("FOO=bar")).toEqual({ FOO: "bar" });
40+
});
41+
42+
it("should parse multiple key-value pairs", () => {
43+
expect(AdditionalEnvVars.parse("FOO=bar,BAZ=qux")).toEqual({
44+
FOO: "bar",
45+
BAZ: "qux",
46+
});
47+
});
48+
49+
it("should handle whitespace", () => {
50+
expect(AdditionalEnvVars.parse(" FOO = bar , BAZ = qux ")).toEqual({
51+
FOO: "bar",
52+
BAZ: "qux",
53+
});
54+
});
55+
56+
it("should return undefined for empty string", () => {
57+
expect(AdditionalEnvVars.parse("")).toBeUndefined();
58+
});
59+
60+
it("should return undefined for invalid format", () => {
61+
expect(AdditionalEnvVars.parse("invalid")).toBeUndefined();
62+
});
63+
64+
it("should skip invalid pairs but include valid ones", () => {
65+
expect(AdditionalEnvVars.parse("FOO=bar,INVALID,BAZ=qux")).toEqual({
66+
FOO: "bar",
67+
BAZ: "qux",
68+
});
69+
});
70+
71+
it("should pass through undefined", () => {
72+
expect(AdditionalEnvVars.parse(undefined)).toBeUndefined();
73+
});
74+
75+
it("should handle empty values", () => {
76+
expect(AdditionalEnvVars.parse("FOO=,BAR=value")).toEqual({
77+
BAR: "value",
78+
});
79+
});
80+
});

apps/supervisor/src/envUtil.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { z } from "zod";
2+
3+
export const BoolEnv = z.preprocess((val) => {
4+
if (typeof val !== "string") {
5+
return val;
6+
}
7+
8+
return ["true", "1"].includes(val.toLowerCase().trim());
9+
}, z.boolean());
10+
11+
export const AdditionalEnvVars = z.preprocess((val) => {
12+
if (typeof val !== "string") {
13+
return val;
14+
}
15+
16+
if (!val) {
17+
return undefined;
18+
}
19+
20+
try {
21+
const result = val.split(",").reduce(
22+
(acc, pair) => {
23+
const [key, value] = pair.split("=");
24+
if (!key || !value) {
25+
return acc;
26+
}
27+
acc[key.trim()] = value.trim();
28+
return acc;
29+
},
30+
{} as Record<string, string>
31+
);
32+
33+
// Return undefined if no valid key-value pairs were found
34+
return Object.keys(result).length === 0 ? undefined : result;
35+
} catch (error) {
36+
console.warn("Failed to parse additional env vars", { error, val });
37+
return undefined;
38+
}
39+
}, z.record(z.string(), z.string()).optional());

0 commit comments

Comments
 (0)