Skip to content

Commit f197259

Browse files
authored
Merge branch 'main' into fix(webapp)-ask-ai-missing-tooltip
2 parents f937422 + db4fb9e commit f197259

File tree

142 files changed

+8810
-2301
lines changed

Some content is hidden

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

142 files changed

+8810
-2301
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
"@trigger.dev/core": patch
3+
"@trigger.dev/sdk": patch
4+
---
5+
6+
Add `maxDelay` option to debounce feature. This allows setting a maximum time limit for how long a debounced run can be delayed, ensuring execution happens within a specified window even with continuous triggers.
7+
8+
```typescript
9+
await myTask.trigger(payload, {
10+
debounce: {
11+
key: "my-key",
12+
delay: "5s",
13+
maxDelay: "30m", // Execute within 30 minutes regardless of continuous triggers
14+
},
15+
});
16+
```
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+
Export `AnyOnStartAttemptHookFunction` type to allow defining `onStartAttempt` hooks for individual tasks.
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 runner getting stuck indefinitely when `execute()` is called on a dead child process.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
fix: vendor superjson to fix ESM/CJS compatibility
6+
7+
Bundle superjson during build to avoid `ERR_REQUIRE_ESM` errors on Node.js versions that don't support `require(ESM)` by default (< 22.12.0) and AWS Lambda which intentionally disables it.

.github/workflows/pr_checks.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ jobs:
2929
with:
3030
package: cli-v3
3131
secrets: inherit
32+
33+
sdk-compat:
34+
uses: ./.github/workflows/sdk-compat.yml
35+
secrets: inherit

.github/workflows/sdk-compat.yml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: "🔌 SDK Compatibility Tests"
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
workflow_call:
8+
9+
jobs:
10+
node-compat:
11+
name: "Node.js ${{ matrix.node }} (${{ matrix.os }})"
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest]
17+
node: ["20.20", "22.12"]
18+
19+
steps:
20+
- name: ⬇️ Checkout repo
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: ⎔ Setup pnpm
26+
uses: pnpm/action-setup@v4
27+
with:
28+
version: 10.23.0
29+
30+
- name: ⎔ Setup node
31+
uses: buildjet/setup-node@v4
32+
with:
33+
node-version: ${{ matrix.node }}
34+
cache: "pnpm"
35+
36+
- name: 📥 Download deps
37+
run: pnpm install --frozen-lockfile
38+
39+
- name: 📀 Generate Prisma Client
40+
run: pnpm run generate
41+
42+
- name: 🔨 Build SDK dependencies
43+
shell: bash
44+
run: pnpm run build --filter '@trigger.dev/sdk^...'
45+
46+
- name: 🔨 Build SDK
47+
shell: bash
48+
run: pnpm run build --filter '@trigger.dev/sdk'
49+
50+
- name: 🧪 Run SDK Compatibility Tests
51+
shell: bash
52+
run: pnpm --filter @internal/sdk-compat-tests test
53+
54+
bun-compat:
55+
name: "Bun Runtime"
56+
runs-on: ubuntu-latest
57+
steps:
58+
- name: ⬇️ Checkout repo
59+
uses: actions/checkout@v4
60+
with:
61+
fetch-depth: 0
62+
63+
- name: ⎔ Setup pnpm
64+
uses: pnpm/action-setup@v4
65+
with:
66+
version: 10.23.0
67+
68+
- name: ⎔ Setup node
69+
uses: buildjet/setup-node@v4
70+
with:
71+
node-version: 20.20.0
72+
cache: "pnpm"
73+
74+
- name: 🥟 Setup Bun
75+
uses: oven-sh/setup-bun@v2
76+
with:
77+
bun-version: latest
78+
79+
- name: 📥 Download deps
80+
run: pnpm install --frozen-lockfile
81+
82+
- name: 📀 Generate Prisma Client
83+
run: pnpm run generate
84+
85+
- name: 🔨 Build SDK dependencies
86+
run: pnpm run build --filter @trigger.dev/sdk^...
87+
88+
- name: 🔨 Build SDK
89+
run: pnpm run build --filter @trigger.dev/sdk
90+
91+
- name: 🧪 Run Bun Compatibility Test
92+
working-directory: internal-packages/sdk-compat-tests/src/fixtures/bun
93+
run: bun run test.ts
94+
95+
deno-compat:
96+
name: "Deno Runtime"
97+
runs-on: ubuntu-latest
98+
steps:
99+
- name: ⬇️ Checkout repo
100+
uses: actions/checkout@v4
101+
with:
102+
fetch-depth: 0
103+
104+
- name: ⎔ Setup pnpm
105+
uses: pnpm/action-setup@v4
106+
with:
107+
version: 10.23.0
108+
109+
- name: ⎔ Setup node
110+
uses: buildjet/setup-node@v4
111+
with:
112+
node-version: 20.20.0
113+
cache: "pnpm"
114+
115+
- name: 🦕 Setup Deno
116+
uses: denoland/setup-deno@v2
117+
with:
118+
deno-version: v2.x
119+
120+
- name: 📥 Download deps
121+
run: pnpm install --frozen-lockfile
122+
123+
- name: 📀 Generate Prisma Client
124+
run: pnpm run generate
125+
126+
- name: 🔨 Build SDK dependencies
127+
run: pnpm run build --filter @trigger.dev/sdk^...
128+
129+
- name: 🔨 Build SDK
130+
run: pnpm run build --filter @trigger.dev/sdk
131+
132+
- name: 🔗 Link node_modules for Deno fixture
133+
working-directory: internal-packages/sdk-compat-tests/src/fixtures/deno
134+
run: ln -s ../../../../../node_modules node_modules
135+
136+
- name: 🧪 Run Deno Compatibility Test
137+
working-directory: internal-packages/sdk-compat-tests/src/fixtures/deno
138+
run: deno run --allow-read --allow-env --allow-sys test.ts
139+
140+
cloudflare-compat:
141+
name: "Cloudflare Workers"
142+
runs-on: ubuntu-latest
143+
steps:
144+
- name: ⬇️ Checkout repo
145+
uses: actions/checkout@v4
146+
with:
147+
fetch-depth: 0
148+
149+
- name: ⎔ Setup pnpm
150+
uses: pnpm/action-setup@v4
151+
with:
152+
version: 10.23.0
153+
154+
- name: ⎔ Setup node
155+
uses: buildjet/setup-node@v4
156+
with:
157+
node-version: 20.20.0
158+
cache: "pnpm"
159+
160+
- name: 📥 Download deps
161+
run: pnpm install --frozen-lockfile
162+
163+
- name: 📀 Generate Prisma Client
164+
run: pnpm run generate
165+
166+
- name: 🔨 Build SDK dependencies
167+
run: pnpm run build --filter @trigger.dev/sdk^...
168+
169+
- name: 🔨 Build SDK
170+
run: pnpm run build --filter @trigger.dev/sdk
171+
172+
- name: 📥 Install Cloudflare fixture deps
173+
working-directory: internal-packages/sdk-compat-tests/src/fixtures/cloudflare-worker
174+
run: pnpm install
175+
176+
- name: 🧪 Run Cloudflare Workers Compatibility Test (dry-run)
177+
working-directory: internal-packages/sdk-compat-tests/src/fixtures/cloudflare-worker
178+
run: npx wrangler deploy --dry-run --outdir dist

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ out/
1515
dist
1616
packages/**/dist
1717

18+
# vendored bundles (generated during build)
19+
packages/**/src/**/vendor
20+
1821
# Tailwind
1922
apps/**/styles/tailwind.css
2023
packages/**/styles/tailwind.css

apps/supervisor/src/env.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ const Env = z.object({
112112
KUBERNETES_SCHEDULER_NAME: z.string().optional(), // Custom scheduler name for pods
113113
KUBERNETES_LARGE_MACHINE_POOL_LABEL: z.string().optional(), // if set, large-* presets affinity for machinepool=<value>
114114

115+
// Project affinity settings - pods from the same project prefer the same node
116+
KUBERNETES_PROJECT_AFFINITY_ENABLED: BoolEnv.default(false),
117+
KUBERNETES_PROJECT_AFFINITY_WEIGHT: z.coerce.number().int().min(1).max(100).default(50),
118+
KUBERNETES_PROJECT_AFFINITY_TOPOLOGY_KEY: z.string().trim().min(1).default("kubernetes.io/hostname"),
119+
115120
// Placement tags settings
116121
PLACEMENT_TAGS_ENABLED: BoolEnv.default(false),
117122
PLACEMENT_TAGS_PREFIX: z.string().default("node.cluster.x-k8s.io"),

apps/supervisor/src/workloadManager/kubernetes.ts

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export class KubernetesWorkloadManager implements WorkloadManager {
120120
},
121121
spec: {
122122
...this.addPlacementTags(this.#defaultPodSpec, opts.placementTags),
123-
affinity: this.#getNodeAffinity(opts.machine),
123+
affinity: this.#getAffinity(opts.machine, opts.projectId),
124124
terminationGracePeriodSeconds: 60 * 60,
125125
containers: [
126126
{
@@ -390,50 +390,86 @@ export class KubernetesWorkloadManager implements WorkloadManager {
390390
return preset.name.startsWith("large-");
391391
}
392392

393-
#getNodeAffinity(preset: MachinePreset): k8s.V1Affinity | undefined {
393+
#getAffinity(preset: MachinePreset, projectId: string): k8s.V1Affinity | undefined {
394+
const nodeAffinity = this.#getNodeAffinityRules(preset);
395+
const podAffinity = this.#getProjectPodAffinity(projectId);
396+
397+
if (!nodeAffinity && !podAffinity) {
398+
return undefined;
399+
}
400+
401+
return {
402+
...(nodeAffinity && { nodeAffinity }),
403+
...(podAffinity && { podAffinity }),
404+
};
405+
}
406+
407+
#getNodeAffinityRules(preset: MachinePreset): k8s.V1NodeAffinity | undefined {
394408
if (!env.KUBERNETES_LARGE_MACHINE_POOL_LABEL) {
395409
return undefined;
396410
}
397411

398412
if (this.#isLargeMachine(preset)) {
399413
// soft preference for the large-machine pool, falls back to standard if unavailable
400414
return {
401-
nodeAffinity: {
402-
preferredDuringSchedulingIgnoredDuringExecution: [
403-
{
404-
weight: 100,
405-
preference: {
406-
matchExpressions: [
407-
{
408-
key: "node.cluster.x-k8s.io/machinepool",
409-
operator: "In",
410-
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
411-
},
412-
],
413-
},
415+
preferredDuringSchedulingIgnoredDuringExecution: [
416+
{
417+
weight: 100,
418+
preference: {
419+
matchExpressions: [
420+
{
421+
key: "node.cluster.x-k8s.io/machinepool",
422+
operator: "In",
423+
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
424+
},
425+
],
414426
},
415-
],
416-
},
427+
},
428+
],
417429
};
418430
}
419431

420432
// not schedulable in the large-machine pool
421433
return {
422-
nodeAffinity: {
423-
requiredDuringSchedulingIgnoredDuringExecution: {
424-
nodeSelectorTerms: [
425-
{
434+
requiredDuringSchedulingIgnoredDuringExecution: {
435+
nodeSelectorTerms: [
436+
{
437+
matchExpressions: [
438+
{
439+
key: "node.cluster.x-k8s.io/machinepool",
440+
operator: "NotIn",
441+
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
442+
},
443+
],
444+
},
445+
],
446+
},
447+
};
448+
}
449+
450+
#getProjectPodAffinity(projectId: string): k8s.V1PodAffinity | undefined {
451+
if (!env.KUBERNETES_PROJECT_AFFINITY_ENABLED) {
452+
return undefined;
453+
}
454+
455+
return {
456+
preferredDuringSchedulingIgnoredDuringExecution: [
457+
{
458+
weight: env.KUBERNETES_PROJECT_AFFINITY_WEIGHT,
459+
podAffinityTerm: {
460+
labelSelector: {
426461
matchExpressions: [
427462
{
428-
key: "node.cluster.x-k8s.io/machinepool",
429-
operator: "NotIn",
430-
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
463+
key: "project",
464+
operator: "In",
465+
values: [projectId],
431466
},
432467
],
433468
},
434-
],
469+
topologyKey: env.KUBERNETES_PROJECT_AFFINITY_TOPOLOGY_KEY,
470+
},
435471
},
436-
},
472+
],
437473
};
438474
}
439475
}

0 commit comments

Comments
 (0)