Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8e00344
feat(supervisor): project-based scheduling affinity for image cache l…
myftija Feb 4, 2026
7781e2a
docs: usage function examples were missing the imports (#2830)
matt-aitken Feb 4, 2026
e017913
docs(self-hosting): added graphile worker troubleshooting to docs (#2…
isshaddad Feb 4, 2026
104f720
docs(troubleshooting): add COULD_NOT_FIND_EXECUTOR error and IPv4 sup…
isshaddad Feb 4, 2026
6a45f56
docs: multi-tenant applications and concurrency limits (#2961)
isshaddad Feb 4, 2026
c059570
docs: clarify .env.local loading and idempotency key reset scope (#2996)
isshaddad Feb 4, 2026
db4fb9e
docs: Add Hookdeck example (#3005)
isshaddad Feb 5, 2026
c55af7b
fix(webapp): ask ai button missing tooltip (#2964)
samejr Feb 5, 2026
283f88b
feat(webapp): add triggered via field to deployment details page (#2850)
myftija Feb 5, 2026
3bb9aac
Fix(webapp): Prevent big numbers on Queue page from jumping around wh…
samejr Feb 5, 2026
b96a0b7
Docs: Clarify AI tool compatibility and expand context snippet (#3000)
D-K-P Feb 5, 2026
e536d35
fix(ci): fix docker image publishing and worker builds (#3013)
nicktrn Feb 6, 2026
9b21f8d
feat(webapp): Vercel integration (#2994)
0ski Feb 10, 2026
eaed7d0
fix(webapp): UI/UX improvements for logs, query, and shortcuts (#2997)
mpcgrid Feb 10, 2026
bc63edd
chore(repo): adopt vouch with issue based workflow and require for PR…
ericallam Feb 10, 2026
ebffa10
docs: added Cursor background agent docs (#3023)
D-K-P Feb 10, 2026
48a96ef
chore(webapp): Expose Vercel errors (#3025)
0ski Feb 10, 2026
2feecec
fix(api): skip external build creation for native builds (#3024)
myftija Feb 10, 2026
ddeb9c4
docs: heartbeats, Bun version, troubleshooting, and preview-branch cl…
isshaddad Feb 10, 2026
170fde3
Move vouch requirement to top of CONTRIBUTING.md (#3029)
matt-aitken Feb 11, 2026
6e3ac8b
docs: cursor cli docs update (remove chmod workaround) (#3031)
D-K-P Feb 11, 2026
d7bc37f
Feat(dashboard): show the Betterstack incident title in the dashboard…
samejr Feb 12, 2026
c2085e6
feat(dashboard): link git sha and ref to GitHub on settings page (#3034)
nicktrn Feb 12, 2026
062bcae
feat(mcp): add timeout parameter to wait_for_run_to_complete tool (#3…
ericallam Feb 12, 2026
bc0d1ff
Metrics dashboards (#3019)
matt-aitken Feb 12, 2026
ba320a4
chore(vouch): vouch for gautamsi (#3039)
ericallam Feb 12, 2026
bfe417f
docs: add note about single-issue PRs to contributing guide (#3044)
matt-aitken Feb 13, 2026
4b7f676
feat(webapp/deployments): Vercel improvements & fixes (#3037)
0ski Feb 13, 2026
a8f9a90
improv(webapp): Add new table for optimized logs search (#3036)
mpcgrid Feb 13, 2026
2462c80
chore(vouch): vouch for capaj (#3048)
ericallam Feb 13, 2026
9030e94
Metrics improvements (#3046)
matt-aitken Feb 13, 2026
35e11e0
Fix(webapp): Show an error to the user when their add-on upgrade paym…
samejr Feb 13, 2026
a3d3b17
TRQL: always add FINAL keyword (#3051)
matt-aitken Feb 13, 2026
1d744fa
fix(dashboard): apply time filter preset periods immediately on click…
nicktrn Feb 13, 2026
6b9289d
fix: explicitly set machineConfig to null when task machine is remove…
Feb 14, 2026
d6dca75
fix: apply consistent ?? null handling to all Json? fields in Backgro…
Feb 14, 2026
152c383
feat(marqs): optimize batch context fetching in sharedQueueConsumer
Feb 14, 2026
4b1f911
perf(run-engine): optimize waitpoint mapping in executionSnapshotSystem
Feb 14, 2026
cab9fae
feat: implement 4 medium-level improvements
Feb 18, 2026
6ba9134
chore: revert strict schema validation changes to fix CI
Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mcp-wait-timeout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---

Add optional `timeoutInSeconds` parameter to the `wait_for_run_to_complete` MCP tool. Defaults to 60 seconds. If the run doesn't complete within the timeout, the current state of the run is returned instead of waiting indefinitely.
5 changes: 5 additions & 0 deletions .changeset/vercel-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Add Vercel integration support to API schemas: `commitSHA` and `integrationDeployments` on deployment responses, and `source` field for environment variable imports.
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/vouch-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Vouch Request
description: Request to be vouched as a contributor
labels: ["vouch-request"]
body:
- type: markdown
attributes:
value: |
## Vouch Request

We use [vouch](https://github.com/mitchellh/vouch) to manage contributor trust. PRs from unvouched users are automatically closed.

To get vouched, fill out this form. A maintainer will review your request and vouch for you by commenting on this issue.
- type: textarea
id: context
attributes:
label: Why do you want to contribute?
description: Tell us a bit about yourself and what you'd like to work on.
placeholder: "I'd like to fix a bug I found in..."
validations:
required: true
- type: textarea
id: prior-work
attributes:
label: Prior contributions or relevant experience
description: Links to previous open source work, relevant projects, or anything that helps us understand your background.
placeholder: "https://github.com/..."
validations:
required: false
16 changes: 16 additions & 0 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Vouched contributors for Trigger.dev
# See: https://github.com/mitchellh/vouch
#
# Org members
0ski
D-K-P
ericallam
matt-aitken
mpcgrid
myftija
nicktrn
samejr
isshaddad
# Outside contributors
gautamsi
capaj
12 changes: 11 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,24 @@ jobs:
package_version=$(echo '${{ steps.changesets.outputs.publishedPackages }}' | jq -r '.[0].version')
echo "package_version=${package_version}" >> "$GITHUB_OUTPUT"

# this triggers the publish workflow for the docker images
- name: Create and push Docker tag
if: steps.changesets.outputs.published == 'true'
run: |
set -e
git tag "v.docker.${{ steps.get_version.outputs.package_version }}"
git push origin "v.docker.${{ steps.get_version.outputs.package_version }}"

# Trigger Docker builds directly via workflow_call since tags pushed with
# GITHUB_TOKEN don't trigger other workflows (GitHub Actions limitation).
publish-docker:
name: 🐳 Publish Docker images
needs: release
if: needs.release.outputs.published == 'true'
uses: ./.github/workflows/publish.yml
secrets: inherit
with:
image_tag: v${{ needs.release.outputs.published_package_version }}

# The prerelease job needs to be on the same workflow file due to a limitation related to how npm verifies OIDC claims.
prerelease:
name: 🧪 Prerelease
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/vouch-check-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Vouch - Check PR

on:
pull_request_target:
types: [opened, reopened]

permissions:
contents: read
pull-requests: write
issues: read

jobs:
check-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mitchellh/vouch/action/check-pr@main
with:
pr-number: ${{ github.event.pull_request.number }}
auto-close: true
require-vouch: true
env:
GH_TOKEN: ${{ github.token }}
25 changes: 25 additions & 0 deletions .github/workflows/vouch-manage-by-issue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Vouch - Manage by Issue

on:
issue_comment:
types: [created]

permissions:
contents: write
issues: write

jobs:
manage:
runs-on: ubuntu-latest
if: >-
contains(github.event.comment.body, 'vouch') ||
contains(github.event.comment.body, 'denounce') ||
contains(github.event.comment.body, 'unvouch')
steps:
- uses: actions/checkout@v4
- uses: mitchellh/vouch/action/manage-by-issue@main
with:
comment-id: ${{ github.event.comment.id }}
issue-id: ${{ github.event.issue.number }}
env:
GH_TOKEN: ${{ github.token }}
9 changes: 9 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
"cwd": "${workspaceFolder}/apps/webapp",
"sourceMaps": true
},
{
"type": "node-terminal",
"request": "launch",
"name": "Debug opened test file",
"command": "pnpm run test -- ./${relativeFile}",
"envFile": "${workspaceFolder}/.env",
"cwd": "${workspaceFolder}",
"sourceMaps": true
},
{
"type": "chrome",
"request": "launch",
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"packages/cli-v3/e2e": true
},
"vitest.disableWorkspaceWarning": true,
"typescript.experimental.useTsgo": false
"chat.agent.maxRequests": 10000
}
17 changes: 16 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,25 @@

Thank you for taking the time to contribute to Trigger.dev. Your involvement is not just welcomed, but we encourage it! 🚀

Please take some time to read this guide to understand contributing best practices for Trigger.dev.
Please take some time to read this guide to understand contributing best practices for Trigger.dev. Note that we use [vouch](https://github.com/mitchellh/vouch) to manage contributor trust, so you'll need to be vouched before opening a PR.

Thank you for helping us make Trigger.dev even better! 🤩

> **Important:** We only accept PRs that address a single issue. Please do not submit PRs containing multiple unrelated fixes or features. If you have multiple contributions, open a separate PR for each one.

## Getting vouched (required before opening a PR)

We use [vouch](https://github.com/mitchellh/vouch) to manage contributor trust. **PRs from unvouched users are automatically closed.**

Before you open your first pull request, you need to be vouched by a maintainer. Here's how:

1. Open a [Vouch Request](https://github.com/triggerdotdev/trigger.dev/issues/new?template=vouch-request.yml) issue.
2. Tell us what you'd like to work on and share any relevant background.
3. A maintainer will review your request and vouch for you by commenting on the issue.
4. Once vouched, your PRs will be accepted normally.

If you're unsure whether you're already vouched, go ahead and open a PR — the check will tell you.

## Developing

The development branch is `main`. This is the branch that all pull
Expand Down
2 changes: 1 addition & 1 deletion apps/coordinator/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ COPY --from=pruner --chown=node:node /app/out/full/ .
COPY --from=dev-deps --chown=node:node /app/ .
COPY --chown=node:node turbo.json turbo.json

RUN pnpm run -r --filter coordinator build:bundle
RUN pnpm run -r --filter @trigger.dev/core bundle-vendor && pnpm run -r --filter coordinator build:bundle

FROM alpine AS cri-tools

Expand Down
2 changes: 1 addition & 1 deletion apps/docker-provider/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ COPY --from=pruner --chown=node:node /app/out/full/ .
COPY --from=dev-deps --chown=node:node /app/ .
COPY --chown=node:node turbo.json turbo.json

RUN pnpm run -r --filter docker-provider build:bundle
RUN pnpm run -r --filter @trigger.dev/core bundle-vendor && pnpm run -r --filter docker-provider build:bundle

FROM base AS runner

Expand Down
2 changes: 1 addition & 1 deletion apps/kubernetes-provider/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ COPY --from=pruner --chown=node:node /app/out/full/ .
COPY --from=dev-deps --chown=node:node /app/ .
COPY --chown=node:node turbo.json turbo.json

RUN pnpm run -r --filter kubernetes-provider build:bundle
RUN pnpm run -r --filter @trigger.dev/core bundle-vendor && pnpm run -r --filter kubernetes-provider build:bundle

FROM base AS runner

Expand Down
5 changes: 5 additions & 0 deletions apps/supervisor/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ const Env = z.object({
KUBERNETES_SCHEDULER_NAME: z.string().optional(), // Custom scheduler name for pods
KUBERNETES_LARGE_MACHINE_POOL_LABEL: z.string().optional(), // if set, large-* presets affinity for machinepool=<value>

// Project affinity settings - pods from the same project prefer the same node
KUBERNETES_PROJECT_AFFINITY_ENABLED: BoolEnv.default(false),
KUBERNETES_PROJECT_AFFINITY_WEIGHT: z.coerce.number().int().min(1).max(100).default(50),
KUBERNETES_PROJECT_AFFINITY_TOPOLOGY_KEY: z.string().trim().min(1).default("kubernetes.io/hostname"),

// Placement tags settings
PLACEMENT_TAGS_ENABLED: BoolEnv.default(false),
PLACEMENT_TAGS_PREFIX: z.string().default("node.cluster.x-k8s.io"),
Expand Down
88 changes: 62 additions & 26 deletions apps/supervisor/src/workloadManager/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class KubernetesWorkloadManager implements WorkloadManager {
},
spec: {
...this.addPlacementTags(this.#defaultPodSpec, opts.placementTags),
affinity: this.#getNodeAffinity(opts.machine),
affinity: this.#getAffinity(opts.machine, opts.projectId),
terminationGracePeriodSeconds: 60 * 60,
containers: [
{
Expand Down Expand Up @@ -390,50 +390,86 @@ export class KubernetesWorkloadManager implements WorkloadManager {
return preset.name.startsWith("large-");
}

#getNodeAffinity(preset: MachinePreset): k8s.V1Affinity | undefined {
#getAffinity(preset: MachinePreset, projectId: string): k8s.V1Affinity | undefined {
const nodeAffinity = this.#getNodeAffinityRules(preset);
const podAffinity = this.#getProjectPodAffinity(projectId);

if (!nodeAffinity && !podAffinity) {
return undefined;
}

return {
...(nodeAffinity && { nodeAffinity }),
...(podAffinity && { podAffinity }),
};
}

#getNodeAffinityRules(preset: MachinePreset): k8s.V1NodeAffinity | undefined {
if (!env.KUBERNETES_LARGE_MACHINE_POOL_LABEL) {
return undefined;
}

if (this.#isLargeMachine(preset)) {
// soft preference for the large-machine pool, falls back to standard if unavailable
return {
nodeAffinity: {
preferredDuringSchedulingIgnoredDuringExecution: [
{
weight: 100,
preference: {
matchExpressions: [
{
key: "node.cluster.x-k8s.io/machinepool",
operator: "In",
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
},
],
},
preferredDuringSchedulingIgnoredDuringExecution: [
{
weight: 100,
preference: {
matchExpressions: [
{
key: "node.cluster.x-k8s.io/machinepool",
operator: "In",
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
},
],
},
],
},
},
],
};
}

// not schedulable in the large-machine pool
return {
nodeAffinity: {
requiredDuringSchedulingIgnoredDuringExecution: {
nodeSelectorTerms: [
{
requiredDuringSchedulingIgnoredDuringExecution: {
nodeSelectorTerms: [
{
matchExpressions: [
{
key: "node.cluster.x-k8s.io/machinepool",
operator: "NotIn",
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
},
],
},
],
},
};
}

#getProjectPodAffinity(projectId: string): k8s.V1PodAffinity | undefined {
if (!env.KUBERNETES_PROJECT_AFFINITY_ENABLED) {
return undefined;
}

return {
preferredDuringSchedulingIgnoredDuringExecution: [
{
weight: env.KUBERNETES_PROJECT_AFFINITY_WEIGHT,
podAffinityTerm: {
labelSelector: {
matchExpressions: [
{
key: "node.cluster.x-k8s.io/machinepool",
operator: "NotIn",
values: [env.KUBERNETES_LARGE_MACHINE_POOL_LABEL],
key: "project",
operator: "In",
values: [projectId],
},
],
},
],
topologyKey: env.KUBERNETES_PROJECT_AFFINITY_TOPOLOGY_KEY,
},
},
},
],
};
}
}
29 changes: 29 additions & 0 deletions apps/webapp/app/components/AlphaBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,32 @@ export function AlphaTitle({ children }: { children: React.ReactNode }) {
</>
);
}

export function BetaBadge({
inline = false,
className,
}: {
inline?: boolean;
className?: string;
}) {
return (
<SimpleTooltip
button={
<Badge variant="extra-small" className={cn(inline ? "inline-grid" : "", className)}>
Beta
</Badge>
}
content="This feature is in Beta."
disableHoverableContent
/>
);
}

export function BetaTitle({ children }: { children: React.ReactNode }) {
return (
<>
<span>{children}</span>
<BetaBadge />
</>
);
}
Loading
Loading