Update trigger - #4
Open
tylerc-govsignals wants to merge 1336 commits into
Open
Conversation
…errors (#4077) ## Summary Two robustness fixes in the dashboard's error handling, found while testing the billing-limit pause/resume flow. ## Toast cookie overflow Toast messages are flashed into the `__message` session cookie, which the session store rejects once the serialized cookie passes the browser's ~4KB limit. Any call site that flashes a raw caught error (a verbose database or validation message, for example) could turn a toast into a failed request. `setErrorMessage` / `setSuccessMessage` now clamp the message length, so a toast can never overflow the cookie. This protects every toast helper at once. ## Pause/resume reporting Resuming an environment that is paused by a billing limit is an expected, user-actionable state, but `PauseEnvironmentService` threw it, and the service's catch reports every throw at error level. It now returns that case as a failure result, so callers still surface the message to the user while genuine errors keep reporting.
Fixed trace rendering for child and nested runs in large traces. Dashboard and trace API responses now load the requested run's trace subtree instead of depending on the run span appearing in the initial trace slice.
Invite acceptance could fail for cloud organizations with many projects because the whole flow ran inside a single transaction and did too much work before it completed. In larger orgs, that pushed the transaction past its timeout and blocked the invite from being accepted. This PR moves the expensive parts of invite acceptance out of the transaction, excludes deleted projects from environment setup, fixes error handling on /invites, and adds regression coverage for the failure cases.
## Summary Upgrades the dashboard form layer from `@conform-to` 0.9 to 1.x. No behaviour change is intended; this is the conform API migration only. conform 1.x peer-depends on `zod` `^3.21 || ^4`, so it runs on the current zod 3 and is a prerequisite for upgrading the repo to zod 4: conform 0.9 imports `ZodNativeEnum`, `ZodEffects`, and `ZodPipeline`, all removed in zod 4, so the webapp cannot build against zod 4 until conform is on 1.x. Landing this first (on zod 3) keeps the zod 4 PR focused on zod alone. ## Testing Did a bunch of local smoke tests and E2E playwright tests, several rounds of different reviewers, all clean.
Adds a `redis_worker.queue.oldest_message_age` observable gauge (labeled `worker_name`) and `SimpleQueue.oldestMessageAge()`, reporting the age of the oldest overdue message in each queue. Generic queue-stall signal: 0 while a queue drains healthily, rising only when due work sits undrained (blocked dequeue, dead consumer, backpressure) — even when no items are being processed.
- auto-reloading for setting up identity & access - ui/ux improvements around the process of setting up connections for the identity & access
Having issues with blacksmith runners coming online.
The `Exec` helper in `@trigger.dev/core` logs command args at debug level (and in its output/error metadata). For commands that take a credential directly on the command line - `--password`, `--token`, `--secret`, etc. - that value is logged verbatim, so turning on debug logging can surface secrets in log sinks. This masks the value of known credential-bearing flags (both `--flag value` and `--flag=value` forms) before the args are logged. The executed command is untouched - only the logged copy is redacted. Added a small unit test for the redaction helper.
Re-enables ~15 oxlint rules that were blanket-disabled before.
…un (#4094) Fixes #4046 ## Problem When a single run creates more than 1000 idempotency keys (e.g. a large batch trigger where each item calls `idempotencyKeys.create()`), the original key and scope metadata is silently dropped for all but the most recent 1000 keys. `idempotencyKeys.create()` returns a plain 64-char hash and stores the `{ key, scope }` mapping in an in-process catalog keyed by that hash. That catalog was a fixed-size **LRU capped at 1000 entries**. Once a run creates more than 1000 keys, the earliest mappings are evicted, so when the SDK later looks them up to attach `idempotencyKeyOptions` to the trigger call, it finds nothing and sends `undefined`. The affected runs then: - report `ctx.run.idempotencyKey` as the raw hash instead of the user-provided key - have no `idempotencyKeyScope` - show empty `idempotency_key` / `idempotency_key_scope` in the dashboard and analytics Deduplication still works (the hash is intact); only the human-readable metadata is lost, which makes the failure silent and hard to notice. ## Fix - Replace the LRU catalog with an unbounded in-memory catalog, so every key created within a run keeps its metadata regardless of how many are created. - Clear the catalog at each run boundary via `resetExecutionEnvironment()` (both dev and managed workers), matching how every other per-run manager is reset. Deployed workers reuse one process across many runs (warm starts), so this bounds memory to a single run's keys instead of accumulating across runs — which is the reason the size cap existed in the first place. ## Tests - New public-API test creates 3000 keys and asserts all of them (including the first) retain their key/scope — this fails on `main` and passes with the fix. - New test for the in-memory catalog covers store/retrieve/overwrite, large-N retention (no eviction), and `clear()`. - New test asserts the catalog is emptied after a run-boundary reset. - Replaces the previous LRU catalog + its eviction tests. Verified: `@trigger.dev/core` and `trigger.dev` both build; all idempotency tests pass. Changeset added (patch).
This reverts commit d5ea3dd.
## Summary Fixes flaky CLI v3 E2E tests by removing fixture-level parallelism. The suite was using `describe.concurrent`, but each fixture test mutates its fixture workspace during setup: removing `node_modules`, renaming/restoring lockfiles, and running package installs. On Windows/npm this can race or hit file-lock/cache contention, causing intermittent failures. ## Fix Run the CLI v3 E2E fixtures serially instead of concurrently. ## Expected impact This should make the Windows/npm E2E job more stable. The E2E step may slow down from ~30s to roughly ~60–90s in typical runs, with a conservative upper bound around ~2 minutes.
…nsert (#4095) ## ✅ Checklist - [ ] I have followed every step in the [contributing guide](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md) - [x] The PR title follows the convention. - [ ] I ran and tested the code works --- ## Testing `pnpm run typecheck --filter @internal/clickhouse` passes. This only adds a ClickHouse input-format setting to existing insert calls; the setting affects type inference for newly-inserted/merged data and is non-destructive to existing rows. --- ## Changelog Sets `input_format_json_infer_array_of_dynamic_from_array_of_different_types = 1` on every native-JSON insert path: - `task_runs_v2` (`output`, `error`) — `insertTaskRuns`, `insertTaskRunsCompactArrays`, and the async-insert variants - `task_events_v1` / `task_events_v2` (`attributes`) - `metrics_v1` - `sessions_v1` ### Why Our JSON columns contain arrays with mixed element types (e.g. `[{"key":"value"}, "string", "string"]`). With this setting off — which is the effective default under `24.12` compatibility — ClickHouse infers those as deeply nested unnamed `Tuple(JSON, Nullable(String), …)` types. ClickHouse 26.2 introduced `input_format_binary_max_type_complexity` (default 1000), and those tuple type trees exceeded the limit, causing background merges to fail with **Code 117**. With the setting on (the default since 25.8), mixed-type arrays are inferred as a single `Array(Dynamic)` — a simpler, flatter type representation that never approaches the complexity limit, even once the upstream default limit is restored. Setting this explicitly at insert time keeps behavior deterministic and version-controlled, so it does not depend on the server profile or a future compatibility bump. This is a forward-only change: it only affects newly inserted/merged data and does not rewrite existing parts. Our read path re-serializes these columns to strings (`toJSONString` via the materialized `*_text` columns), so the internal Tuple → Array(Dynamic) representation change is transparent to the application. ### Companion server-side setting To also apply this on the ClickHouse side (covers merges and any writes not going through these code paths), set it on the default user: ```sql ALTER USER default SETTINGS input_format_json_infer_array_of_dynamic_from_array_of_different_types = 1; ``` --- ## Screenshots _N/A_ 💯 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01AaChyhestFMBYBWh6bgcCF --- _Generated by [Claude Code](https://claude.ai/code/session_01AaChyhestFMBYBWh6bgcCF)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Bumps the `@remix-run/*` family in the webapp from 2.17.4 to 2.17.5 to keep dependencies current. 2.17.5 pulls `@remix-run/router` 1.23.2 → 1.23.3, so the local route-matching perf patch was rebased onto 1.23.3 (regenerated via `pnpm patch`). It is functionally identical to the previous one - the only difference is that 1.23.3 already hoists `decodePath` out of the match loop upstream, so that hunk is dropped; the per-route-tree branch cache and the compiled-path cache are unchanged. Also updated the `@remix-run/dev>tar-fs` override key to track the new dev version. Verified locally against latest main: `typecheck --filter webapp` passes, `--frozen-lockfile` is consistent, and the dev server boots and server-renders pages cleanly (route matching exercised via the patched router).
…updates (#4097) Bumps the github-actions group with 7 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `6.0.2` | `7.0.0` | | [changesets/action](https://github.com/changesets/action) | `1.8.0` | `1.9.0` | | [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) | `1.0.133` | `1.0.157` | | [actions/cache](https://github.com/actions/cache) | `5.0.5` | `6.1.0` | | [azure/setup-helm](https://github.com/azure/setup-helm) | `5.0.0` | `5.0.1` | | [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `3.0.0` | `3.0.1` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.6` | `0.5.7` | Updates `actions/checkout` from 6.0.2 to 7.0.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> <h2>v6.0.3</h2> <h2>What's Changed</h2> <ul> <li>Update changelog by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> <li>Fix checkout init for SHA-256 repositories by <a href="/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>Update changelog for v6.0.3 by <a href="/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="/yaananth"><code>@yaananth</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="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/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v7.0.0</h2> <ul> <li>Block checking out fork PR for pull_request_target and workflow_run by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> </ul> <h2>v6.0.3</h2> <ul> <li>Fix checkout init for SHA-256 repositories by <a href="/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <h2>v6.0.2</h2> <ul> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <h2>v6.0.1</h2> <ul> <li>Add worktree support for persist-credentials includeIf by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> </ul> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a> update error wording (<a href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li> <li><a href="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/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a> getting ready for checkout v7 release (<a href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li> <li><a href="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/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a> Bump the minor-npm-dependencies group across 1 directory with 3 updates (<a href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li> <li><a href="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/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a> upgrade module to esm and update dependencies (<a href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li> <li><a href="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/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a> Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid (<a href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li> <li><a href="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/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a> Bump js-yaml from 4.1.0 to 4.2.0 (<a href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li> <li><a href="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/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a> Bump flatted from 3.3.1 to 3.4.2 (<a href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li> <li><a href="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/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a> Bump actions/publish-immutable-action (<a href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li> <li><a href="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/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a> block checking out fork pr for pull_request_target and workflow_run (<a href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li> <li><a href="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/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a> Update changelog for v6.0.3 (<a href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li> <li>Additional commits viewable in <a href="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/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0">compare view</a></li> </ul> </details> <br /> Updates `changesets/action` from 1.8.0 to 1.9.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/changesets/action/releases">changesets/action's releases</a>.</em></p> <blockquote> <h2>v1.9.0</h2> <h3>Minor Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/changesets/action/pull/636">#636</a> <a href="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/changesets/action/commit/b072bccc4c664a373c42168eed9139dce1e003b1"><code>b072bcc</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Add a new <code>@changesets/action/pr-comment</code> sub-action to comment on PRs</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/625">#625</a> <a href="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/changesets/action/commit/8795eee5eee884e887d352ac673a515ffe35aaa6"><code>8795eee</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Add a new <code>@changesets/action/pr-status</code> sub-action to generate the changeset status comment for PRs as an alternative to the <a href="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/apps/changeset-bot">Changesets Bot</a>.</p> </li> </ul> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/changesets/action/pull/535">#535</a> <a href="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/changesets/action/commit/34f64f6e2e1e47ddc183f174aa27c197aa47f520"><code>34f64f6</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Fixed an issue with GitHub releases not being created for successfully published packages when <em>some</em> packages failed to be published to the registry.</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/632">#632</a> <a href="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/changesets/action/commit/1d54b9e660e435237accbcae0b4581af3be641b4"><code>1d54b9e</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Simplify internal implementation to get changelog entries for a package version</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/629">#629</a> <a href="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/changesets/action/commit/e0c90aa7fbd0cc26931a679c5abe9bbc0deb0b50"><code>e0c90aa</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Fix custom version and publish command argument parsing</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/645">#645</a> <a href="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/changesets/action/commit/f9585d966a9c7d2f668b97199990de6f885823cf"><code>f9585d9</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Improved force-push handling when using <code>commitMode: "github-api"</code> so updating an existing branch no longer temporarily resets the target branch to the base commit, avoiding cases where GitHub closes open pull requests during the update. This should remove a possibility of a GitHub state race that caused the force-pushed PRs not being reopened.</p> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="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/changesets/action/blob/main/CHANGELOG.md">changesets/action's changelog</a>.</em></p> <blockquote> <h1><code>@changesets/action</code></h1> <h2>2.0.0-next.3</h2> <h3>Major Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/changesets/action/pull/680">#680</a> <a href="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/changesets/action/commit/ca57073900dc678254406a052a03c0c8824e319d"><code>ca57073</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Add a new <code>push-git-tags</code> option that complements <code>create-github-releases</code> to control specifically if git tags should be created but not GitHub releases.</p> <p>If <code>create-github-releases</code> was previously set to <code>false</code>, which also indirectly disabled git tag creation, git tags will now be created instead by default. If this is not desired, set <code>push-git-tags</code> to <code>false</code> explicitly.</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/681">#681</a> <a href="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/changesets/action/commit/73591071e61c7f61cf322dd7a6341dc29a8e1d4e"><code>7359107</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Rename the root action inputs and outputs to better match the sub-actions' conventions.</p> <p>Inputs:</p> <ul> <li><code>version</code> -> <code>version-script</code></li> <li><code>publish</code> -> <code>publish-script</code></li> <li><code>commit</code> -> <code>commit-message</code></li> <li><code>title</code> -> <code>pr-title</code></li> <li><code>branch</code> -> <code>pr-base-branch</code></li> </ul> <p>Outputs:</p> <ul> <li><code>pull-request-number</code> -> <code>pr-number</code></li> </ul> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/674">#674</a> <a href="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/changesets/action/commit/164652bdd60525670d95291addb8c6f92833ac60"><code>164652b</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Remove support for passing custom GitHub token through the GITHUB_TOKEN environment variable. It should be passed to the <code>github-token</code> input instead.</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/673">#673</a> <a href="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/changesets/action/commit/823cf741ca57c5e22652123d3a847dfafcd77ca0"><code>823cf74</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Update to Changesets v3 packages</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/668">#668</a> <a href="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/changesets/action/commit/0eae789230defbc4ad287e9b476aba7e842e34e0"><code>0eae789</code></a> Thanks <a href="/bluwy"><code>@bluwy</code></a>! - Rename the input and output names to kebab-case instead of camelCase to match the official GitHub actions pattern</p> </li> </ul> <h3>Minor Changes</h3> <ul> <li><a href="https://redirect.github.com/changesets/action/pull/678">#678</a> <a href="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/changesets/action/commit/f71ae043ed5deb17952900091e009a60edef9507"><code>f71ae04</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Published packages detection done through stdout parsing was replaced with one based on the shared output file using <code>CHANGESETS_OUTPUT</code> environment variable. When using custom scripts this environment variable should always be passed down to the Changesets CLI invocations.</li> </ul> <h2>2.0.0-next.2</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/changesets/action/pull/670">#670</a> <a href="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/changesets/action/commit/5a8b9b721bf683e3bf9bd72ea92a685dc024147b"><code>5a8b9b7</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Authenticate git CLI pushes with the configured GitHub token using Git extra headers instead of writing to a global <code>.netrc</code> file.</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/670">#670</a> <a href="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/changesets/action/commit/5a8b9b721bf683e3bf9bd72ea92a685dc024147b"><code>5a8b9b7</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Derive the Git server URL from the GitHub Actions context when configuring git CLI authentication to support GitHub Enterprise Server setups.</p> </li> </ul> <h2>2.0.0-next.1</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/changesets/action/pull/663">#663</a> <a href="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/changesets/action/commit/ccb38113eaaa4a13eb6aabe09520e49cc8519b84"><code>ccb3811</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Fix the computed publish plan path passed internally to <code>changeset pack</code> by the <code>/pack</code> subaction.</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/662">#662</a> <a href="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/changesets/action/commit/5c88881fff1f0d8b055d4a2d3a74a8ce843db6f3"><code>5c88881</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Fixed usage of <code>--from-publish-plan</code> flag used by the <code>/pack</code> subaction</p> </li> <li> <p><a href="https://redirect.github.com/changesets/action/pull/666">#666</a> <a href="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/changesets/action/commit/dc29b738b532d9e95f46b9bf493e2e3fdf48a7ed"><code>dc29b73</code></a> Thanks <a href="/Andarist"><code>@Andarist</code></a>! - Fix the <code>/version</code> subaction to not crash on missing <code>pr-base-branch</code> input. This input is meant to be optional.</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/changesets/action/commit/a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d"><code>a45c4d5</code></a> v1.9.0</li> <li><a href="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/changesets/action/commit/b459b1eaa0a3889b4eea8af244304a64da6331ce"><code>b459b1e</code></a> Version Packages (<a href="https://redirect.github.com/changesets/action/issues/637">#637</a>)</li> <li><a href="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/changesets/action/commit/f9585d966a9c7d2f668b97199990de6f885823cf"><code>f9585d9</code></a> Update <code>@changesets/ghcommit</code> (<a href="https://redirect.github.com/changesets/action/issues/645">#645</a>)</li> <li><a href="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/changesets/action/commit/020e8cc600a1e7e7b8b843654902f043f32387ea"><code>020e8cc</code></a> Use internal bot for versioning (<a href="https://redirect.github.com/changesets/action/issues/643">#643</a>)</li> <li><a href="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/changesets/action/commit/b072bccc4c664a373c42168eed9139dce1e003b1"><code>b072bcc</code></a> Add simple PR comment sub-action (<a href="https://redirect.github.com/changesets/action/issues/636">#636</a>)</li> <li><a href="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/changesets/action/commit/8795eee5eee884e887d352ac673a515ffe35aaa6"><code>8795eee</code></a> Comment changeset status in PRs (<a href="https://redirect.github.com/changesets/action/issues/625">#625</a>)</li> <li><a href="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/changesets/action/commit/34f64f6e2e1e47ddc183f174aa27c197aa47f520"><code>34f64f6</code></a> Fixed an issue with GitHub releases not being created for successfully publis...</li> <li><a href="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/changesets/action/commit/1d54b9e660e435237accbcae0b4581af3be641b4"><code>1d54b9e</code></a> Simplify getChangelogEntry (<a href="https://redirect.github.com/changesets/action/issues/632">#632</a>)</li> <li><a href="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/changesets/action/commit/031358f743b5a6199bd7a39bdc8b469280983df9"><code>031358f</code></a> Update to typescript v6 (<a href="https://redirect.github.com/changesets/action/issues/633">#633</a>)</li> <li><a href="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/changesets/action/commit/a0c05f7a4b1df776543903d7dca8e39cd787b30a"><code>a0c05f7</code></a> Bump <code>@changesets/changelog-github</code> from 0.5.2 to 0.7.0 (<a href="https://redirect.github.com/changesets/action/issues/620">#620</a>)</li> <li>Additional commits viewable in <a href="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/changesets/action/compare/63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b...a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d">compare view</a></li> </ul> </details> <br /> Updates `anthropics/claude-code-action` from 1.0.133 to 1.0.157 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/anthropics/claude-code-action/releases">anthropics/claude-code-action's releases</a>.</em></p> <blockquote> <h2>v1.0.157</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.157">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.157</a></p> <h2>v1.0.156</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.156">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.156</a></p> <h2>v1.0.155</h2> <h2>What's Changed</h2> <ul> <li>fix: filter PR reviews and inline review comments to trigger time by <a href="/EffortlessSteven"><code>@EffortlessSteven</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1385">anthropics/claude-code-action#1385</a></li> <li>test: cover format-turns content-type fallbacks and system_other handling by <a href="/farmer-data"><code>@farmer-data</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1421">anthropics/claude-code-action#1421</a></li> <li>fix: allow @ in branch names (valid per git-check-ref-format) by <a href="/bellalMohamed"><code>@bellalMohamed</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1411">anthropics/claude-code-action#1411</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="/EffortlessSteven"><code>@EffortlessSteven</code></a> made their first contribution in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1385">anthropics/claude-code-action#1385</a></li> <li><a href="/farmer-data"><code>@farmer-data</code></a> made their first contribution in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1421">anthropics/claude-code-action#1421</a></li> <li><a href="/bellalMohamed"><code>@bellalMohamed</code></a> made their first contribution in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1411">anthropics/claude-code-action#1411</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.155">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.155</a></p> <h2>v1.0.154</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.154">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.154</a></p> <h2>v1.0.153</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.153">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.153</a></p> <h2>v1.0.152</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.152">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.152</a></p> <h2>v1.0.151</h2> <h2>What's Changed</h2> <ul> <li>fix: skip workflow validation token exchange failures by <a href="/Ryanoonan"><code>@Ryanoonan</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1417">anthropics/claude-code-action#1417</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="/Ryanoonan"><code>@Ryanoonan</code></a> made their first contribution in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1417">anthropics/claude-code-action#1417</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.151">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.151</a></p> <h2>v1.0.150</h2> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.150">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.150</a></p> <h2>v1.0.149</h2> <h2>What's Changed</h2> <ul> <li>fix(parse-sdk-options): prevent shell-quote from collapsing unquoted Bash(X:*) rules to bare Bash by <a href="/alexglynn"><code>@alexglynn</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1350">anthropics/claude-code-action#1350</a></li> <li>fix(mcp): align allowed-tools parser with SDK option parser by <a href="/bymle"><code>@bymle</code></a> in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1373">anthropics/claude-code-action#1373</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="/alexglynn"><code>@alexglynn</code></a> made their first contribution in <a href="https://redirect.github.com/anthropics/claude-code-action/pull/1350">anthropics/claude-code-action#1350</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/anthropics/claude-code-action/compare/v1...v1.0.149">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.149</a></p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/anthropics/claude-code-action/commit/428971d2ecd6e3a7cb0ee0da2a3a8b33fdb3678d"><code>428971d</code></a> chore: bump Claude Code to 2.1.191 and Agent SDK to 0.3.191</li> <li><a href="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/anthropics/claude-code-action/commit/74eedf1a1892082d619c3edb66b9402da6520e7f"><code>74eedf1</code></a> chore: bump Claude Code to 2.1.190 and Agent SDK to 0.3.190</li> <li><a href="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/anthropics/claude-code-action/commit/80b31826338489861333dc17217865dfe8085cdc"><code>80b3182</code></a> chore: bump Claude Code to 2.1.187 and Agent SDK to 0.3.187</li> <li><a href="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/anthropics/claude-code-action/commit/360be9c8fc5d80cb33661e0ffd33dcef4c7155aa"><code>360be9c</code></a> fix: allow @ in branch names (valid per git-check-ref-format) (<a href="https://redirect.github.com/anthropics/claude-code-action/issues/1411">#1411</a>)</li> <li><a href="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/anthropics/claude-code-action/commit/e452eb9dce5f3ab14b90cf9386247fbcb3c4ac92"><code>e452eb9</code></a> test: cover format-turns content-type fallbacks and system_other handling (<a href="https://redirect.github.com/anthropics/claude-code-action/issues/1">#1</a>...</li> <li><a href="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/anthropics/claude-code-action/commit/6b8063043eb8bc14e8448185a12d6d9dcf07ce55"><code>6b80630</code></a> fix: filter PR reviews and inline review comments to trigger time (<a href="https://redirect.github.com/anthropics/claude-code-action/issues/1385">#1385</a>)</li> <li><a href="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/anthropics/claude-code-action/commit/30544b674398ee15c84819bd87caf8a87e8c7b55"><code>30544b6</code></a> chore: bump Claude Code to 2.1.186 and Agent SDK to 0.3.186</li> <li><a href="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/anthropics/claude-code-action/commit/2fee15510437d71399d9139ed60433470484a8fb"><code>2fee155</code></a> chore: bump Claude Code to 2.1.185 and Agent SDK to 0.3.185</li> <li><a href="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/anthropics/claude-code-action/commit/51705da45eecce209d4700538bf8377d5b5fc695"><code>51705da</code></a> chore: bump Claude Code to 2.1.183 and Agent SDK to 0.3.183</li> <li><a href="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/anthropics/claude-code-action/commit/806af32823ef69c8ef357086c573a902af641307"><code>806af32</code></a> chore: bump Claude Code to 2.1.181 and Agent SDK to 0.3.181</li> <li>Additional commits viewable in <a href="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/anthropics/claude-code-action/compare/787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251...428971d2ecd6e3a7cb0ee0da2a3a8b33fdb3678d">compare view</a></li> </ul> </details> <br /> Updates `actions/cache` from 5.0.5 to 6.1.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/actions/cache/releases">actions/cache's releases</a>.</em></p> <blockquote> <h2>v6.1.0</h2> <h2>What's Changed</h2> <ul> <li>Bump <code>@actions/cache</code> to v6.1.0 - handle read-only cache access by <a href="/jasongin"><code>@jasongin</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1768">actions/cache#1768</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/actions/cache/compare/v6...v6.1.0">https://github.com/actions/cache/compare/v6...v6.1.0</a></p> <h2>v6.0.0</h2> <h2>What's Changed</h2> <ul> <li>Update packages, migrate to ESM by <a href="/Samirat"><code>@Samirat</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p> <h2>v5.1.0</h2> <h2>What's Changed</h2> <ul> <li>Bump <code>@actions/cache</code> to v5.1.0 - handle read-only cache access by <a href="/jasongin"><code>@jasongin</code></a> in <a href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="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/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="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/actions/cache/blob/main/RELEASES.md">actions/cache's changelog</a>.</em></p> <blockquote> <h1>Releases</h1> <h2>How to prepare a release</h2> <blockquote> <p>[!NOTE] Relevant for maintainers with write access only.</p> </blockquote> <ol> <li>Switch to a new branch from <code>main</code>.</li> <li>Run <code>npm test</code> to ensure all tests are passing.</li> <li>Update the version in <a href="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/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li> <li>Run <code>npm run build</code> to update the compiled files.</li> <li>Update this <a href="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/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a> with the new version and changes in the <code>## Changelog</code> section.</li> <li>Run <code>licensed cache</code> to update the license report.</li> <li>Run <code>licensed status</code> and resolve any warnings by updating the <a href="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/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a> file with the exceptions.</li> <li>Commit your changes and push your branch upstream.</li> <li>Open a pull request against <code>main</code> and get it reviewed and merged.</li> <li>Draft a new release <a href="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/actions/cache/releases">https://github.com/actions/cache/releases</a> use the same version number used in <code>package.json</code> <ol> <li>Create a new tag with the version number.</li> <li>Auto generate release notes and update them to match the changes you made in <code>RELEASES.md</code>.</li> <li>Toggle the set as the latest release option.</li> <li>Publish the release.</li> </ol> </li> <li>Navigate to <a href="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/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a> <ol> <li>There should be a workflow run queued with the same version number.</li> <li>Approve the run to publish the new version and update the major tags for this action.</li> </ol> </li> </ol> <h2>Changelog</h2> <h3>6.1.0</h3> <ul> <li>Bump <code>@actions/cache</code> to v6.1.0 to pick up <a href="https://redirect.github.com/actions/toolkit/pull/2435">actions/toolkit#2435 Handle cache write error due to read-only token</a></li> <li>Switch redundant "Cache save failed" warning to debug log in save-only</li> </ul> <h3>6.0.0</h3> <ul> <li>Updated <code>@actions/cache</code> to ^6.0.1, <code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to ^3.0.0, <code>@actions/io</code> to ^3.0.2</li> <li>Migrated to ESM module system</li> <li>Upgraded Jest to v30 and test infrastructure to be ESM compatible</li> </ul> <h3>5.0.4</h3> <ul> <li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar patterns)</li> <li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb protection, header validation fixes)</li> <li>Bump <code>fast-xml-parser</code> to v5.5.6</li> </ul> <h3>5.0.3</h3> <ul> <li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a href="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/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li> <li>Bump <code>@actions/core</code> to v2.0.3</li> </ul> <h3>5.0.2</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/actions/cache/commit/55cc8345863c7cc4c66a329aec7e433d2d1c52a9"><code>55cc834</code></a> Merge pull request <a href="https://redirect.github.com/actions/cache/issues/1768">#1768</a> from jasongin/readonly-cache</li> <li><a href="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/actions/cache/commit/d8cd72f230726cdf4457ebb61ec1b593a8d12337"><code>d8cd72f</code></a> Bump <code>@actions/cache</code> to v6.1.0 - handle cache write error due to RO token</li> <li><a href="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/actions/cache/commit/2c8a9bd7457de244a408f35966fab2fb45fda9c8"><code>2c8a9bd</code></a> Merge pull request <a href="https://redirect.github.com/actions/cache/issues/1760">#1760</a> from actions/samirat/esm_migration_and_package_update</li> <li><a href="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/actions/cache/commit/e9b91fdc3fea7d79165fceb79042ef45c2d51023"><code>e9b91fd</code></a> Prettier fixes</li> <li><a href="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/actions/cache/commit/e4884b8ff7f92ef6b52c79eda480bbc86e685adb"><code>e4884b8</code></a> Rebuild dist</li> <li><a href="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/actions/cache/commit/10baf0191a3c426ea0fa4a3253a5c04233b6e18f"><code>10baf01</code></a> Fixed licenses</li> <li><a href="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/actions/cache/commit/e39b386c9004d72a15d864ade8c0b3a702d47a37"><code>e39b386</code></a> Fix test mock return order</li> <li><a href="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/actions/cache/commit/b6928203372a8571ff984c0c883ef3a1adfb0c06"><code>b692820</code></a> PR feedback</li> <li><a href="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/actions/cache/commit/60749128a44d25d3c520a489e576380cf00ff3f1"><code>6074912</code></a> Rebuild dist bundles as ESM to match type:module</li> <li><a href="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/actions/cache/commit/5a912e8b4af820fa082a0e75cfd2c782f8fbfe0e"><code>5a912e8</code></a> Fix lint and jest issues</li> <li>Additional commits viewable in <a href="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/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9">compare view</a></li> </ul> </details> <br /> Updates `azure/setup-helm` from 5.0.0 to 5.0.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/azure/setup-helm/releases">azure/setup-helm's releases</a>.</em></p> <blockquote> <h2>v5.0.1</h2> <h3>Fixed</h3> <ul> <li><a href="https://redirect.github.com/azure/setup-helm/issues/271">#271</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/271">Fix TypeScript 6.0 compatibility errors in run.ts</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/278">fix: use chmod 755 instead of 777 for downloaded helm binary and folder</a></li> </ul> <h3>Changed</h3> <ul> <li><a href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/286">Bump actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/285">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/284">Bump undici</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/283">Bump the actions group with 5 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/280">Bump actions/checkout from 6.0.2 to 6.0.3 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/279">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/277">Bump vitest from 4.1.7 to 4.1.8 in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/276">#276</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/276">chore: remove deprecated OliverMKing release workflow, pin to SHA</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/275">#275</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/275">Bump actions/stale from 10.2.0 to 10.3.0 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/274">#274</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/274">Bump the actions group with 3 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/273">#273</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/273">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/269">#269</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/269">Bump the actions group across 1 directory with 7 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/268">#268</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/268">Bump vite from 8.0.0 to 8.0.5</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/260">#260</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/260">Migrate to ESM with esbuild/vitest and upgrade to node24 (v5.0.0)</a></li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="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/Azure/setup-helm/blob/main/CHANGELOG.md">azure/setup-helm's changelog</a>.</em></p> <blockquote> <h1>Change Log</h1> <h2>[5.0.1] - 2026-06-23</h2> <h3>Fixed</h3> <ul> <li><a href="https://redirect.github.com/azure/setup-helm/issues/271">#271</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/271">Fix TypeScript 6.0 compatibility errors in run.ts</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/278">fix: use chmod 755 instead of 777 for downloaded helm binary and folder</a></li> </ul> <h3>Changed</h3> <ul> <li><a href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/286">Bump actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/285">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/284">Bump undici</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/283">Bump the actions group with 5 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/280">Bump actions/checkout from 6.0.2 to 6.0.3 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/279">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/277">Bump vitest from 4.1.7 to 4.1.8 in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/276">#276</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/276">chore: remove deprecated OliverMKing release workflow, pin to SHA</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/275">#275</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/275">Bump actions/stale from 10.2.0 to 10.3.0 in /.github/workflows in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/274">#274</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/274">Bump the actions group with 3 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/273">#273</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/273">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/269">#269</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/269">Bump the actions group across 1 directory with 7 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/268">#268</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/268">Bump vite from 8.0.0 to 8.0.5</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/260">#260</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/260">Migrate to ESM with esbuild/vitest and upgrade to node24 (v5.0.0)</a></li> </ul> <h2>[5.0.0] - 2026-03-23</h2> <h3>Changed</h3> <ul> <li><a href="https://redirect.github.com/azure/setup-helm/issues/259">#259</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/259">Update Node.js runtime from node20 to node24</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/263">#263</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/263">Bump undici</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/257">#257</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/257">Bump undici and @actions/http-client</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/256">#256</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/256">Bump minimatch</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/248">#248</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/248">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/247">#247</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/247">Bump the actions group with 3 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/246">#246</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/246">Bump @types/node from 25.0.2 to 25.0.3 in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/245">#245</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/245">Bump the actions group with 3 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/243">#243</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/243">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/240">#240</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/240">Bump prettier from 3.6.2 to 3.7.3 in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/229">#229</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/229">Bump the actions group across 1 directory with 3 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/231">#231</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/231">Bump js-yaml from 3.14.1 to 3.14.2</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/234">#234</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/234">Bump glob from 10.4.5 to 10.5.0</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/225">#225</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/225">Fix build error</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/222">#222</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/222">Bump @types/node from 24.7.2 to 24.8.1 in the actions group</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/220">#220</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/220">Bump the actions group across 1 directory with 4 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/216">#216</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/216">Bump the actions group across 1 directory with 4 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/213">#213</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/213">Bump the actions group with 2 updates</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/211">#211</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/211">Bump undici</a></li> <li><a href="https://redirect.github.com/azure/setup-helm/issues/212">#212</a> <a href="https://redirect.github.com/Azure/setup-helm/pull/212">Bump jest from 30.0.5 to 30.1.2 in the actions group</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/Azure/setup-helm/commit/9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310"><code>9bc31f4</code></a> build</li> <li><a href="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/Azure/setup-helm/commit/95ecf4967d92f8074e91c548e394f8ac547da403"><code>95ecf49</code></a> Bump version to 5.0.1 and update CHANGELOG with recent changes (<a href="https://redirect.github.com/azure/setup-helm/issues/287">#287</a>)</li> <li><a href="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/Azure/setup-helm/commit/4180b1c05c03707c071b0c4ffb32f7ccf49b71bd"><code>4180b1c</code></a> Bump the actions group with 2 updates (<a href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a>)</li> <li><a href="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/Azure/setup-helm/commit/6949b7ff3ed0c7f9b29dc9eafb275834aacc7802"><code>6949b7f</code></a> Bump undici (<a href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a>)</li> <li><a href="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/Azure/setup-helm/commit/51ce767c788f32a9d2a8b911f38e9033afd42959"><code>51ce767</code></a> Bump actions/checkout in /.github/workflows in the actions group (<a href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a>)</li> <li><a href="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/Azure/setup-helm/commit/d6da4f47af55af3a717c150920167917cdd944b3"><code>d6da4f4</code></a> Bump the actions group with 5 updates (<a href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a>)</li> <li><a href="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/Azure/setup-helm/commit/7e2bc108ba1a7390c1467373bceaa033d6bb74e8"><code>7e2bc10</code></a> Bump actions/checkout in /.github/workflows in the actions group (<a href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a>)</li> <li><a href="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/Azure/setup-helm/commit/64d6be9869229723b9bbc197a01e7d2e3c81895c"><code>64d6be9</code></a> Bump the actions group with 2 updates (<a href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a>)</li> <li><a href="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/Azure/setup-helm/commit/69214f9d74fea2fd41b0d5ca2f5222dd5ba34fd4"><code>69214f9</code></a> fix: use chmod 755 instead of 777 for downloaded helm binary and folder (<a href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a>)</li> <li><a href="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/Azure/setup-helm/commit/9dad99fe3c3d2198a1403a6aab02375f0f27dd09"><code>9dad99f</code></a> Bump vitest from 4.1.7 to 4.1.8 in the actions group (<a href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a>)</li> <li>Additional commits viewable in <a href="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/azure/setup-helm/compare/dda3372f752e03dde6b3237bc9431cdc2f7a02a2...9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310">compare view</a></li> </ul> </details> <br /> Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/softprops/action-gh-release/releases">softprops/action-gh-release's releases</a>.</em></p> <blockquote> <h2>v3.0.1</h2> <h2>3.0.1</h2> <ul> <li>maintenance release with updated dependencies</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="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/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's changelog</a>.</em></p> <blockquote> <h2>3.0.1</h2> <ul> <li>maintenance release with updated dependencies</li> </ul> <h2>3.0.0</h2> <p><code>3.0.0</code> is a major release that moves the action runtime from Node 20 to Node 24. Use <code>v3</code> on GitHub-hosted runners and self-hosted fleets that already support the Node 24 Actions runtime. If you still need the last Node 20-compatible line, stay on <code>v2.6.2</code>.</p> <h2>What's Changed</h2> <h3>Other Changes 🔄</h3> <ul> <li>Move the action runtime and bundle target to Node 24</li> <li>Update <code>@types/node</code> to the Node 24 line and allow future Dependabot updates</li> <li>Keep the floating major tag on <code>v3</code>; <code>v2</code> remains pinned to the latest <code>2.x</code> release</li> </ul> <h2>2.6.2</h2> <h2>What's Changed</h2> <h3>Other Changes 🔄</h3> <ul> <li>chore(deps): bump picomatch from 4.0.3 to 4.0.4 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/775">softprops/action-gh-release#775</a></li> <li>chore(deps): bump brace-expansion from 5.0.4 to 5.0.5 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/777">softprops/action-gh-release#777</a></li> <li>chore(deps): bump vite from 8.0.0 to 8.0.5 by <a href="/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/781">softprops/action-gh-release#781</a></li> </ul> <h2>2.6.1</h2> <p><code>2.6.1</code> is a patch release focused on restoring linked discussion thread creation when <code>discussion_category_name</code> is set. It fixes <code>[#764](https://github.com/softprops/action-gh-release/issues/764)</code>, where the draft-first publish flow stopped carrying the discussion category through the final publish step.</p> <p>If you still hit an issue after upgrading, please open a report with the bug template and include a minimal repro or sanitized workflow snippet where possible.</p> <h2>What's Changed</h2> <h3>Bug fixes 🐛</h3> <ul> <li>fix: preserve discussion category on publish by <a href="/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/765">softprops/action-gh-release#765</a></li> </ul> <h2>2.6.0</h2> <p><code>2.6.0</code> is a minor release centered on <code>previous_tag</code> support for <code>generate_release_notes</code>, which lets workflows pin GitHub's comparison base explicitly instead of relying on the default range. It also includes the recent concurrent asset upload recovery fix, a <code>working_directory</code> docs sync, a checked-bundle freshness guard for maintainers, and clearer immutable-prerelease guidance where GitHub platform behavior imposes constraints on how prerelease asset uploads can be published.</p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/softprops/action-gh-release/commit/718ea10b132b3b2eba29c1007bb80653f286566b"><code>718ea10</code></a> release 3.0.1</li> <li><a href="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/softprops/action-gh-release/commit/f1a938b9d84ca9b770d0d8dfeb3e7285fe261e63"><code>f1a938b</code></a> chore(deps): bump esbuild from 0.28.0 to 0.28.1 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/802">#802</a>)</li> <li><a href="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/softprops/action-gh-release/commit/0066ead0de7252b4876b36b5357fc3974619d36a"><code>0066ead</code></a> chore(deps): bump vite from 8.0.14 to 8.0.16 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/806">#806</a>)</li> <li><a href="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/softprops/action-gh-release/commit/dc643cac6252aaa00c9b0b6c940d489cd7bf6b23"><code>dc643ca</code></a> chore(deps): bump the npm group with 3 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/805">#805</a>)</li> <li><a href="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/softprops/action-gh-release/commit/85ee99b6b20742a3823a8a289ee5e6ceab44e8aa"><code>85ee99b</code></a> chore(deps): bump actions/checkout in the github-actions group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/804">#804</a>)</li> <li><a href="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/softprops/action-gh-release/commit/9ed3cf9a6863b31f005d951c8d19de20628cf4eb"><code>9ed3cf9</code></a> chore(deps): bump the npm group with 2 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/800">#800</a>)</li> <li><a href="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/softprops/action-gh-release/commit/3efcac8951299998593f871640ea8059d6818655"><code>3efcac8</code></a> chore(deps): bump the npm group with 3 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/798">#798</a>)</li> <li><a href="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/softprops/action-gh-release/commit/05d6b9164aa74958de40b0179d6a773112fcdc7f"><code>05d6b91</code></a> chore(deps): bump brace-expansion from 5.0.5 to 5.0.6 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/797">#797</a>)</li> <li><a href="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/softprops/action-gh-release/commit/403a5240f3837fa857f642062e05aad6bb3391ca"><code>403a524</code></a> chore(deps): bump <code>@types/node</code> from 24.12.2 to 24.12.3 in the npm group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/796">#796</a>)</li> <li><a href="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/softprops/action-gh-release/commit/437e073e786973c6b6af97d9e445c41ae43b1d29"><code>437e073</code></a> chore(deps): bump the npm group with 4 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/792">#792</a>)</li> <li>Additional commits viewable in <a href="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/softprops/action-gh-release/compare/b4309332981a82ec1c5618f44dd2e27cc8bfbfda...718ea10b132b3b2eba29c1007bb80653f286566b">compare view</a></li> </ul> </details> <br /> Updates `zizmorcore/zizmor-action` from 0.5.6 to 0.5.7 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="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/zizmorcore/zizmor-action/releases">zizmorcore/zizmor-action's releases</a>.</em></p> <blockquote> <h2>v0.5.7</h2> <p>1.26.1 is now available via the action 1.26.1 is now the default version of zizmor used by the action</p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="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/zizmorcore/zizmor-action/commit/192e21d79ab29983730a13d1382995c2307fbcaa"><code>192e21d</code></a> Sync zizmor versions (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/127">#127</a>)</li> <li><a href="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/zizmorcore/zizmor-action/commit/2720f2673c0b64a8656d08b009ac239b9383c0ae"><code>2720f26</code></a> Update README.md with new actions/checkout version (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/126">#126</a>)</li> <li><a href="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/zizmorcore/zizmor-action/commit/40b41b824eab0ad9c19ddf9856be25550729e6d8"><code>40b41b8</code></a> chore(deps): bump the github-actions group with 2 updates (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/123">#123</a>)</li> <li><a href="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/zizmorcore/zizmor-action/commit/a687b25bf3aa149153e80ed5f45292e47589888c"><code>a687b25</code></a> chore(deps): bump github/codeql-action from 4.35.5 to 4.36.0 in the github-ac...</li> <li><a href="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/zizmorcore/zizmor-action/commit/64a6900ea7f40fab0caa7dcfc77b392d28fe0cb1"><code>64a6900</code></a> add note to explain that the default value for <code>online-checks</code> is different t...</li> <li><a href="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/zizmorcore/zizmor-action/commit/14050abd109fcba34e6e2f31a723280997808e82"><code>14050ab</code></a> chore(deps): bump the github-actions group with 2 updates (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/118">#118</a>)</li> <li><a href="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/zizmorcore/zizmor-action/commit/ee9b4194a74f093e38908dbcfcb078f63eeef002"><code>ee9b419</code></a> chore(deps): bump github/codeql-action in the github-actions group (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/116">#116</a>)</li> <li><a href="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/zizmorcore/zizmor-action/commit/fddf2b4aa9bf29290c6bf9866e6d113b0cdf6f67"><code>fddf2b4</code></a> Bump pins in README (<a href="https://redirect.github.com/zizmorcore/zizmor-action/issues/115">#115</a>)</li> <li>See full diff in <a href="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/zizmorcore/zizmor-action/compare/5f14fd08f7cf1cb1609c1e344975f152c7ee938d...192e21d79ab29983730a13d1382995c2307fbcaa">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: nicktrn <55853254+nicktrn@users.noreply.github.com>
Takes changesets out of rc prerelease mode so the next version bump produces the stable 4.5.0 GA release rather than another release candidate.
## Summary Adds the `4.5.0` GA entry to the AI chat agents changelog covering the `chat.agent` changes in that release: a new `apiClient` option on `chat.headStart` and `chat.createStartSessionAction` for pointing chat sessions at a different project or environment, the fix for messaging chat agents deployed to a preview branch, and the fix for Head Start handovers when the agent also defines a `prepareMessages` hook. All four changes are from [#4018](#4018).
Removes the release-candidate framing from the docs for the 4.5 GA: the `@rc` install caveats on the `skills` CLI command, and the AI Agents and Prompts release-candidate banner (a shared snippet used across the ai-chat and prompts pages) plus the `>=4.5.0-rc.0` compatibility pin in the AI reference.
# Trigger.dev v4.5.0
4.5.0 is the GA of the AI Agents platform. Everything built during the
prerelease line (durable agents, Sessions, AI Prompts) is now stable on
the `latest` tag, alongside a set of SDK and runtime improvements.
## AI Agents (`chat.agent`)
Run Vercel AI SDK chat completions as durable Trigger.dev tasks instead
of fragile API routes. A conversation runs as one long-lived task keyed
on `chatId`, so it survives page refreshes, network blips, redeploys,
and crashes, and every turn is a span in the dashboard.
```ts
import { chat } from "@trigger.dev/sdk/ai";
import { streamText, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
export const myChat = chat.agent({
id: "my-chat",
run: async ({ messages, signal }) => {
return streamText({
...chat.toStreamTextOptions(), // system prompt, compaction, steering, telemetry
model: anthropic("claude-sonnet-4-5"),
messages,
abortSignal: signal,
stopWhen: stepCountIs(15),
});
},
});
```
## Sessions
The durable primitive underneath `chat.agent`, usable on its own: a
run-aware, bidirectional stream channel keyed on a stable `externalId`
whose `.in` / `.out` streams survive run boundaries (suspend, crash,
idle-timeout, redeploy). One Session spans many runs, which makes it a
good fit for agent inboxes and approval flows.
```ts
import { sessions } from "@trigger.dev/sdk";
// Create the session and trigger its first run (idempotent on externalId)
await sessions.start({
type: "inbox",
externalId: userId,
taskIdentifier: "inbox-agent",
});
const session = sessions.open(userId);
await session.in.send({ text: "hello" });
const stream = await session.out.read({ signal: AbortSignal.timeout(30_000) });
for await (const chunk of stream) console.log(chunk); // durable across run swaps
```
## AI Prompts
Define prompt templates as code, versioned on every deploy, and override
the text or model from the dashboard without redeploying
(environment-scoped). Each generation links back to its prompt version
for usage, cost, and latency.
```ts
import { prompts } from "@trigger.dev/sdk";
import { z } from "zod";
export const supportPrompt = prompts.define({
id: "customer-support",
model: "gpt-4o",
variables: z.object({ customerName: z.string(), issue: z.string() }),
content: `You are a support agent for Acme.
Customer: {{customerName}}
Issue: {{issue}}`,
});
// Honors any active dashboard override, else the current deployed version
const resolved = await supportPrompt.resolve({ customerName: "Alice", issue: "Can't log in" });
// resolved.text, resolved.model, resolved.version
```
## `useChat` integration
`useTriggerChatTransport` is a Vercel AI SDK `ChatTransport` that runs
`useChat` over Trigger.dev realtime with no API routes. Text, tool
calls, reasoning, and `data-*` parts stream natively, and it works with
AI SDK v5, v6, and now v7.
## First-turn fast path (`chat.headStart`)
Runs the first turn in your warm server process while the agent boots in
parallel, cutting cold-start time-to-first-chunk roughly in half
(measured ~2.8s to ~1.2s). Available via the new
`@trigger.dev/sdk/chat-server` subpath.
## Human-in-the-loop, stop, and steering
The agent control surface: tool approvals (`needsApproval` +
`addToolApprovalResponse`), client-driven stop-generation, mid-execution
steering (`pendingMessages`), and between-turn context injection
(`chat.inject` / `chat.defer`), all durable across the conversation.
## Agent Skills
`skills.define({ id, path })` bundles a `SKILL.md` folder into your
deploy image. The agent gets a one-line summary up front and loads the
full instructions plus scoped `bash` / `readFile` tools on demand
(progressive disclosure), so a capability is something the model reaches
for rather than a pre-declared typed tool.
## `trigger skills` for coding assistants
`trigger skills` installs version-pinned Trigger.dev skills plus a
bundled docs snapshot into Claude Code, Cursor, GitHub Copilot, and
Codex, so your assistant's Trigger.dev knowledge stays current with your
installed SDK version. `trigger init` now offers to set up the MCP
server and skills too.
## Model library
A new Models page in the dashboard: a catalog of models grouped by
provider with context window, capabilities, and input / output pricing
per 1M tokens, plus a "Your models" tab showing per-model usage, cost,
and cache-hit sparklines from your actual traffic.
## Dev branches
Run multiple local `trigger dev` sessions in parallel (separate git
worktrees or coding agents) without runs colliding, each isolated with
its own dashboard, via `trigger dev --branch <name>`.
## `TriggerClient`
An instantiable client so one process can trigger and read across
projects, environments, and preview branches, each with its own auth and
baseURL, with no shared global state.
```ts
import { TriggerClient } from "@trigger.dev/sdk";
const prod = new TriggerClient({ accessToken: process.env.TRIGGER_PROD_KEY });
const preview = new TriggerClient({
accessToken: process.env.TRIGGER_PREVIEW_KEY,
previewBranch: "signup-flow",
});
await prod.tasks.trigger("send-email", { to: "user@example.com" });
await preview.runs.list({ status: ["COMPLETED"] });
```
## SDK and runtime
- AI SDK 7 support (v5 and v6 still supported), with OpenTelemetry
telemetry auto-wired
- Large trigger-payload offload: trigger payloads at or above 128KB
upload to object storage automatically, using the same auth and baseURL
as the trigger call
- Region support on the runs API: filter runs by region and read each
run's executing region (also on MCP `list_runs`)
- Duplicate task-id detection: `dev` and `deploy` fail with a clear
error instead of silently overwriting
- `envvars.upload` gains an `isSecret` flag to import redacted secret
variables
- Retry hardening: `TASK_MIDDLEWARE_ERROR` now retries under the task's
retry policy
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Once this is merged, oxlint is at a pretty sensible baseline. **Enable `no-unused-vars`, `typescript/consistent-type-imports`, and `import/no-duplicates` lint rules** Turns on three previously-disabled oxlint rules across the monorepo and fixes all violations: - **`no-unused-vars`** – enabled as an error with standard ignore patterns: unused function arguments are ignored by default (`args: "none"`), variables/caught errors/destructured array elements prefixed with `_` are allowed, and rest siblings are permitted. - **`typescript/consistent-type-imports`** – enforced as an error; all type-only imports now use the `import type` syntax. - **`import/no-duplicates`** – enforced as an error; duplicate import statements from the same module have been merged. The remaining commits clean up the violations found across the codebase: removing unused variables/imports/type aliases, adding `_` prefixes to intentionally unused bindings, fixing duplicate imports, and converting value imports to `import type` where appropriate.
Remove the `devBranchesEnabled` feature flag and enable behaviour by default.
…an without GitHub verification (#4109) ## What & why Two related fixes to how new cloud organizations get onboarded onto the Free plan. ### 1. Route new cloud orgs through plan selection New cloud organizations were created already activated, so they skipped the plan-selection step and went straight to creating projects — which meant their plan and usage limits were never set up. They're now created deactivated and routed through plan selection, which activates them once a plan is chosen. Self-hosted installs have no plan-selection step, so they're activated immediately on creation and are unaffected. The `Organization.v3Enabled` field is renamed to `isActivated` to better describe what it now gates. It's mapped to the existing `v3Enabled` column, so there's no data migration — only a schema/code rename. ### 2. Allow selecting the Free plan without GitHub verification Choosing the Free plan no longer requires connecting and verifying a GitHub account. The plan is applied immediately when selected. This removes: - the "Connect to GitHub" dialog and the GitHub-verified badge from the plan picker - the account-rejected state - the now-unreachable GitHub-connect return routes ## Notes - These changes pair with the corresponding change in the billing service that applies the Free plan directly; they should be released together. ## Testing Verified locally end to end: a new cloud org is routed to plan selection, the Free plan applies in one click with no GitHub step, the org is activated, its usage allowance is provisioned, and it lands on the new-project page. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
Two related timezone bugs in the dashboard.
1. The date/time tooltip could show a UTC offset label that contradicted
the time it displayed. A viewer whose machine clock differs from their
saved timezone (or when a date falls in the other DST phase) would see
something like `Local (UTC +0)` next to a value that isn't at +0.
2. A user's timezone preference silently failed to save whenever their
browser reported a zone like `UTC`, `Etc/UTC`, or `Asia/Kolkata`,
leaving their timestamps stuck in a previously-saved timezone.
## Offset label
The "Local" row formatted its time using the viewer's configured
timezone but computed the `(UTC +n)` label from `new
Date().getTimezoneOffset()`, the browser's offset at the current moment.
Those are two independent sources, so they disagreed when the configured
timezone differed from the machine, and also when the displayed date was
in the opposite DST phase. The label is now derived from the same date
and timezone used to render the row (via `Intl.DateTimeFormat` with
`timeZoneName: "longOffset"`), so it always matches the displayed time.
## Preference persistence
`/resources/timezone` validated the incoming zone against
`Intl.supportedValuesOf("timeZone")`, which lists only canonical zone
ids. Browsers report zones that aren't in that list via
`resolvedOptions().timeZone`, notably `UTC` (and `Etc/UTC`,
`Asia/Kolkata`, `GMT`), so those requests returned 400 and the
preference was never stored. Validation now checks whether the runtime
can resolve the zone at all, which accepts every real zone and still
rejects invalid input.
Added unit tests for both.
Bumps the internal/toolchain Node version to the latest 22.x LTS (`22.23.1`) and standardises it across the repo. Scope is the **platform toolchain + the repo's own runtime images** (all `20 → 22` *upgrades*, off the now-EOL node 20). ### Main changes - Node `20.20.2 → 22.23.1` across all CI workflows, `.nvmrc`, `CONTRIBUTING.md`, and the OSS `docker/Dockerfile` (digest-pinned). - `@types/node → 22.20.0` (root dep + pnpm `overrides`, so the whole workspace resolves to it); lockfile regenerated. - `sdk-compat` matrix: adds Node 24 + 26 (keeps 20, still in `engines`). - **App runtime images → node 22** (were on EOL node 20): `apps/coordinator` → `node:22.23.1-bookworm-slim`; `apps/docker-provider` + `apps/kubernetes-provider` → `node:22-alpine` (reusing the exact digest `apps/supervisor` already runs, so all four worker images are now identical). Stage aliases renamed off `node-20`. ### Possible issues / test notes - `@types/node` 22.x can surface new TS errors — typecheck (now on 22) is the gate. - **Smoke-test the v3 worker path** — `coordinator` (`crictl`/CRI calls) and the docker/kubernetes providers (talking to their daemons) now run on node 22 (alpine/musl for the providers). Upgrade off EOL so low-risk, but it's deployed runtime code with its own `publish-worker.yml` pipeline.
## Summary Long task names in the task landing page side menu pushed the **Test** button off the edge of the panel instead of truncating. The heading now truncates with an ellipsis so the Test button always stays in view, on the standard and agent task pages. ## Root cause The side menu lives in a fixed-width resizable panel with `overflow: hidden`. Its header row is a grid item, and a grid item's default `min-width: auto` lets it grow to its content's width. The title `<span>` uses `truncate` (`white-space: nowrap`), whose min-content is the full, untruncated name, so the header row expanded past the panel and the Test button was clipped off the edge. Adding `min-w-0` to the header container lets it shrink back to the panel width so the title truncates. The scheduled task page already had this class; the standard and agent pages did not.
## Bug
Manually pausing an environment works, but resuming it always fails
with:
> This environment is paused because your organization reached its
billing limit. Resolve the limit on the billing limits settings page to
resume.
even when no billing limit is in effect. Once paused by a user, an
environment cannot be resumed at all.
## Root cause
A manual pause leaves `RuntimeEnvironment.pauseSource` as `NULL` (only
billing-limit enforcement sets `BILLING_LIMIT`). The resume path in
`PauseEnvironmentService` guards its `updateMany` with:
```ts
NOT: { pauseSource: EnvironmentPauseSource.BILLING_LIMIT }
```
Prisma's `NOT` on a nullable field translates to SQL `!=`, which
excludes `NULL` rows. So the update matches zero rows for every
user-paused environment, and the zero-count branch (meant to catch a
race with billing-limit pausing) returns the misleading billing-limit
error.
Introduced in #3996 (the guard is correct for `BILLING_LIMIT` rows; it
just also swallows `NULL`).
## Fix
Explicitly include `pauseSource: null` rows:
```ts
OR: [
{ pauseSource: null },
{ NOT: { pauseSource: EnvironmentPauseSource.BILLING_LIMIT } },
]
```
Billing-limit-paused environments are still blocked from manual resume,
both by the `getManualPauseEnvironmentResult` guard and by this clause.
## Verification
Reproduced locally: paused an environment via `PauseEnvironmentService`
(DB shows `paused = true`, `pauseSource = NULL`), resume returned the
billing-limit error with `updateMany` matching 0 rows. With the fix,
resume succeeds and the environment unpauses. Billing-paused rows remain
excluded by the same clause.
) Makes the app error page always render full screen — it previously inherited the width/offset of whatever container the error boundary was mounted in (e.g. the centered `max-w-xs` column in the root boundary), so `min-h-screen` alone couldn't fill the viewport. The root container now uses `fixed inset-0 z-50` to break out and cover the full screen regardless of nesting. Also changes the "Go to homepage" shortcut from `Cmd/Ctrl+G` (which collides with the browser's native "Find Again") to `Enter`.
Stream dev logs over a local telnet/TCP socket. `trigger dev` mirrors its terminal output on port 6767 by default (override with --telnet-logs-port or TRIGGER_DEV_TELNET_LOGS_PORT, 0 disables). webapp, supervisor, and coordinator each expose an opt-in stream gated on a per-service *_TELNET_LOGS_PORT env var. New @trigger.dev/core/v3/telnetLogServer module (localhost-only, backpressure-safe, plain-text) plus optional static Logger.onLog / SimpleStructuredLogger.onLog sinks. Then you (or your agent) can use `nc` to connect and filter out the stream. <img width="1103" height="239" alt="image" src="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/user-attachments/assets/b4d47efc-8a57-4185-a159-10f2806627ae" />
…t threads to org tenant (#4368) ## What Two changes, shipped together: 1. **SDK migration (TRI-12460).** `@team-plain/typescript-sdk` is deprecated. Move the webapp to its successors — `@team-plain/graphql` (client) and `@team-plain/ui-components` (`uiComponent` builder). Behaviour-preserving: the `PlainClient` customer upsert + thread creation move to the new `client.mutation.*({ input })` shape; the client now throws on failure, so `sendToPlain` wraps its calls and logs, staying best-effort. 2. **Org tenant attribution (TRI-12461).** When org context is available, `sendToPlain` now upserts a Plain tenant keyed by `externalId = org_id`, links the customer to it, and stamps the created thread with that tenant — so support threads become attributable to a Trigger.dev org. Wired into the four add-on quota requests and the plan-cancellation feedback (which already have org context). The tenant steps are isolated in their own try/catch and the thread's `tenantIdentifier` is gated on their success, so a tenant failure never blocks thread creation. ## Not affected - `customer.externalId` stays `User.id` — the customer cards + impersonation link are unchanged. - No ticket content leaves Plain. - Callers without a single org (e.g. the feedback widget) are unchanged — the org params are optional. ## Deploy prerequisite The webapp's Plain API key needs three **new** scopes for attribution to work (it already has `customer:create`, `customer:edit`, `thread:create`): - [x] `tenant:create` - [x] `tenant:edit` - [x] `customerTenantMembership:create` Until granted, nothing breaks — `sendToPlain` logs the forbidden error and creates the thread without attribution. ## Testing - `pnpm typecheck --filter webapp` passes; oxfmt + oxlint clean. - Ran the real `sendToPlain` end-to-end via a throwaway vitest harness against live Plain — confirmed the code path executes; the live write is gated only by the key scopes above.
…rs (#4426) Members added by SSO just-in-time provisioning or Directory Sync never got their per-member DEVELOPMENT environments - only invite acceptance and project creation created them. `trigger dev` returned "Environment not found" for those members and the dashboard had no dev view. ensureOrgMember now queues provisioning for every membership it settles, so both paths are covered and members missing environments are repaired on their next sync. Provisioning runs as a common-worker job to keep sign-in and directory webhooks off the per-project write loop. A failed enqueue surfaces for Directory Sync, whose worker retries the idempotent effect, and is swallowed for sign-in, where the next login enqueues again. Environment creation now tolerates a concurrent creator so the project-creation loop and the job cannot collide on the unique index. Also fixes environment resolution ignoring dev-environment ownership: a member without their own dev environment could be handed a colleague's and have it persisted as their dashboard preference.
## Summary Keeps the queue metrics ClickHouse tests stable as wall-clock time advances. ## Root cause The fixtures used fixed timestamps. Once those timestamps crossed the tables' 30-day retention boundary, ClickHouse immediately expired the inserted aggregate rows and all six tests read empty results. The fixtures now derive a recent minute-aligned timestamp once per test file. The second 10-second bucket and ranking window are derived from the same anchor, preserving deterministic bucket relationships while keeping rows inside both the raw and aggregate table TTLs. Verified with `pnpm --filter @internal/clickhouse exec vitest run src/queueMetrics.test.ts`.
) `test/envParamRoute.ownership.test.ts` fails on main: 3 of its 4 tests throw ``` Error: [vitest] No "hasAdminDisplayAccess" export is defined on the "~/services/session.server" mock. Did you forget to return it from "vi.mock"? ``` #4421 added a `hasAdminDisplayAccess(user)` call to the `env.$envParam` loader, and the test's `vi.mock` of `session.server` only returns `requireUser`, so the call blows up. Both changes were green in their own PR and only conflict once merged together, which is why nobody caught it. The mock now mirrors the real implementation rather than returning a constant, so it stays correct if the test's user fixture is ever varied. No assertions were changed: the tests were right, the mock was stale. Worth flagging separately: no workflow runs on push to main, so this has been red since #4421 landed without showing up anywhere. Every PR opened since has inherited the failure.
<!-- ccr-slack-attribution --> _Requested by **Eric Allam** · [Slack thread](https://triggerdotdev.slack.com/archives/C0BEM9Z73TM/p1785491472104199)_ ## Checklist - [ ] I have followed every step in the [contributing guide](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md) - [x] The PR title follows the convention. - [ ] I ran and tested the code works --- ## Testing Static checks only, all clean: - `pnpm run typecheck --filter trigger.dev` - `pnpm run format` - `pnpm run lint` No live task was triggered against a running project, so the "ran and tested" box above is left unchecked. --- ## Changelog **Before:** triggering a task through the MCP server always ran it in the project's default region. There was no way to pick one. **After:** the `trigger_task` tool accepts an optional `region` option, so you can choose the region a run executes in. **How:** `region: z.string().optional()` was added to `TriggerTaskInput.options` in `packages/cli-v3/src/mcp/schemas.ts`. No call-site change was needed — `tools/tasks.ts` passes `options` through verbatim, and `TriggerTaskRequestBody.options.region` already existed. The tool description in `docs/mcp-tools.mdx` gained a matching line, and a patch changeset is included. There is no batch-trigger MCP tool, so there is no sibling tool to mirror this change on. --- ## Screenshots N/A — no UI changes. Co-authored-by: Claude <noreply@anthropic.com>
…reaming never completes (#4397) ## Summary `batchTriggerAndWait()` could leave a parent run waiting forever. The 2-phase batch API blocks the parent on the batch's waitpoint as soon as the batch is created, but the batch is only sealed at the end of item streaming. If streaming never completed, nothing sealed the batch, nothing completed the waitpoint, and the parent stayed suspended with no timeout and no way to recover. Supersedes #4016, which added the reaper alone. ## Fix Admission for item streaming was being decided twice. Batch creation passes its own rate limiter, which fixes `expectedCount` and blocks the parent, and then the item stream had to pass the general API limiter as well, competing with unrelated traffic. A second limiter could therefore veto work the first had already committed the parent to. Creation now mints a bounded grant that the item stream spends, so an admitted batch can finish streaming. The grant is capped per batch rather than exempting the path, and every failure mode (no grant, spent grant, unreachable store) falls back to the normal limiter. That makes stranding much rarer but not impossible, since a request timeout or a crash can still end streaming for good. So a seal-timeout reaper aborts any batch still unsealed after `BATCH_SEAL_TIMEOUT_MS` and completes the parent's waitpoint with an error, letting `batchTriggerAndWait()` reject instead of hang. It is race-safe against a late seal, and it is only scheduled for batches that actually block a parent, so fire-and-forget batches cost nothing. Finally, the batches page used to report "Batch completion checked." for these batches while doing nothing, because the completion path returns early on an unsealed batch. It now says the batch cannot be resumed. Rate limiting is no longer the reason a batch strands, so the reaper's default stays at 30 minutes, comfortably above the SDK's worst-case stream-retry budget. ## Verification Unit and container tests cover the grant cap, the bypass ordering (it runs after the authorization check, so it can never skip authentication), and the reaper's abort, seal race, idempotency, and no-waitpoint cases. Also verified end-to-end against a running stack. With the general limit exhausted, batch creation and other API calls returned 429 while a granted batch still streamed and sealed; an ungranted batch id was rate limited rather than bypassed; and the grant cut off exactly at its configured attempt count. Reproducing the stranded state on a real parent run, the batch was aborted at the timeout, the waitpoint completed with an error, and the parent resumed and finished instead of hanging. A parentless batch left unsealed was untouched well past the reaper window. ## Verified against deployed runs The reaper was proven end to end with a real deployed run (locally-run supervisor, containerised run) and a real network fault, rather than a simulated one: toxiproxy severs the phase 2 item stream mid-flight so every SDK stream retry genuinely fails, while phase 1 still succeeds. Only the batch calls traverse the fault, so control-plane traffic is untouched. The reproduction is the shape that actually strands a parent: the task catches the `BatchTriggerError` the SDK throws and carries on, so the phase 1 block outlives the thrown error and the parent hangs at its next suspension point. With the reaper disabled, the parent sat in `EXECUTING_WITH_WAITPOINTS` for over 24 minutes holding two blockers, and stayed stuck across a full infrastructure restart: ``` type | status | has_timeout BATCH | PENDING | f <- orphan, completedAfter NULL DATETIME | COMPLETED | t <- the wait already elapsed ``` With the reaper enabled the same task under the same fault completed in about 75 seconds with zero blockers left, the batch `ABORTED`, and its waitpoint completed carrying the error. Two conditions are required to observe this at all, which is worth knowing for any future test: the run must be deployed rather than `trigger dev` (dev runs execute in process and finish while still holding blocker rows), and the wait after the caught error must exceed the checkpoint threshold, or it is served in process and never suspends. ### Why completing the batch waitpoint is sufficient `batchTriggerAndWait` runs create, then stream, then wait. A phase 2 failure throws before the wait is ever reached, and the reaper only fires on an unsealed batch, so the parent is never suspended awaiting the batch when it runs. The parent therefore does not need a synthetic result, only to stop being blocked. Note this reasoning depends on that ordering: if the wait were ever reached with an unsealed batch, completing the batch waitpoint alone would not settle the caller. ## Follow-ups - Batches stranded before this ships still need a one-off recovery; the reaper only schedules at creation time. - That same property leaves a gap if the process dies between creating the batch and scheduling the job. A periodic sweep would close it, but wants a supporting index. - When a partially streamed batch aborts, children already enqueued keep running while the parent fails. Left as-is deliberately, since cancelling triggered work is a bigger semantic call.
) ## What `startRunAttempt` — the run controller's first call when a run starts — had no retry on transient connection errors. A brief connection blip on that call would abandon the start and send the run back through the queue, delaying its first attempt. This adds a jittered backoff retry, matching the existing `continueRunExecution` path with a shorter budget, so a transient blip is ridden out in place instead of bouncing the run. ## Why a shorter budget The continue path retries generously. Start-attempt keeps a tighter budget (6 attempts, ~25-40s jittered) so it rides out a transient blip but never keeps retrying past the point the run would already have been requeued. ## Safety Retrying is safe: start-attempt is guarded server-side by the snapshot id — a retry after a start has already committed is rejected, so it can never double-start an attempt. A pure connection error (the common case) never reached the server. ## Scope One retry-options object on `startRunAttempt`; no other behavior change. Warm starts share this path and get the same resilience.
…4419) A non-delayed run used to get two execution snapshots the moment it was triggered: `RUN_CREATED` nested in the run-create transaction, immediately followed by `QUEUED` from its own `BEGIN`/`INSERT`/`COMMIT`. It now gets a single `QUEUED` snapshot written inside the create, and the trigger path only publishes to the queue. One fewer row per run on `TaskRunExecutionSnapshot`, and one fewer round trip on the trigger hot path. `EnqueueSystem` gains a `publishRun` seam that enqueues without writing a snapshot. Every re-enqueue path (waitpoint resume, checkpoint restore, delayed enqueue, pending version, retry requeue) still calls `enqueueRun` and writes its own `QUEUED`, so only the first enqueue changes. The `QUEUED` snapshot still commits before the queue message, so a dequeue sees a dequeueable status exactly as before. Two things for reviewers. Nesting the write skips `createExecutionSnapshot`, which is what emits `executionSnapshotCreated` and therefore the run timeline's `[engine] QUEUED` entry, so the trigger path now emits it directly, the same way the dequeue and attempt-start paths already do for their nested creates. And `RUN_CREATED` is still written when a dequeued run has no background worker yet, so the status and both `statuses.ts` helpers stay live and existing rows keep reading correctly. Delayed runs are untouched: `DELAYED` then `QUEUED` are two genuinely different moments and stay two snapshots. Rollback is a revert. Create-and-enqueue happen in one request in one process, so no in-flight run needs both code paths to agree during a rollout. One note for whoever debugs this path later. The `QUEUED` snapshot now commits before the queue publish, so a failed publish leaves the run recorded as `QUEUED` with no queue message. That state was already reachable, since the publish was never part of the snapshot transaction, but it used to be recorded as `RUN_CREATED`, which was distinctive because it never otherwise persisted. `QUEUED` with no message is indistinguishable from a run waiting on a concurrency slot, so trigger-time publish failure is now one more cause of an apparently stuck queued run.
…te metric (#4442) The pod-count backpressure source read `apiserver_storage_objects{resource="pods"}` from an apiserver `/metrics` scrape. That gauge is a periodically-refreshed cached count, and it is served by whichever apiserver replica the scrape lands on — replicas disagree with each other at the same instant, by enough to swamp the engage/release hysteresis band. Engage and release timing was therefore partly a function of scrape routing. This replaces it with a single `limit=1` list of the workload namespace and computes `remainingItemCount + items.length`. One pod object transferred, no informer, no watch cache. Two request-shape constraints are load-bearing and called out in the code: passing a label or field selector makes the apiserver omit `remainingItemCount` entirely, and setting `resourceVersion` serves a cached count rather than a quorum read. Neither is passed. `remainingItemCount` is only set when the list is truncated, so `_continue` is the truncation signal — if it is absent the returned page is the whole collection and `items.length` is already exact. If the list *is* truncated and the count is missing or implausible, the fetcher throws rather than guessing. Failure semantics are unchanged: a throw lands in the monitor's existing catch, exactly as the previous parse did. The hysteresis, verdict shape, and gauge are untouched. RBAC is unchanged — the existing role already grants `pods: list`. The `/metrics` non-resource grant in the deployment role becomes unused, and the scrape-timeout env var is now a slight misnomer. Both left alone deliberately: the grant may be wanted again for other apiserver signals, and renaming the var would need a coordinated config change for no behavioural gain. Tests cover the not-truncated, truncated, missing-count, negative-count and timeout paths.
## Summary Opening a filter sub-menu that has its own search field left the cursor outside it, so you had to click into the field before you could type. The cursor now lands in the search field every time a sub-menu opens. `ComboBox` now focuses its input whenever the popover is open and the field is present, so the cursor lands there both when a menu opens normally and when a sub-menu mounts its field late. It is a no-op wherever focus already worked. Verified in the dashboard against the Tags menu: before, the field mounted with focus still on the popover container; after, it mounts focused and accepts typing straight away.
## Summary Adds an admin-only "AI agent" storybook page exploring an animated identity for the dashboard agent: a resting dot logo that animates while the agent is thinking, then settles once it is done. The lead experiment is a 5x5 dot matrix. Shapes are five-line string bitmaps, a bright head walks each shape's route on a fixed beat, and it only hands off between shapes on a dot the two share, so the rhythm never breaks. It comes with 26 faces, six gradient palettes, and light and dark treatments. Two earlier prototypes (a crisp logo that scatters into orbiting dots, and a dotted triangle on tilted 3D orbits) are kept in their own tabs for comparison. Everything is plain canvas code with no new dependencies. Also adds an `ask-ai` Button variant: secondary styling with a soft trigger-green border and padding tuned around the leading logo. The variant supplies the agent logo itself, so callers write `<Button variant="ask-ai/small">Ask AI</Button>`. Passing a `LeadingIcon` overrides it, which is how the thinking animation gets driven. No release note: the storybook is admin gated and the button variant is not used in product UI yet.
…run or span has un-ingestable JSON (#4358) ## Summary A single run output, trace span, or payload carrying JSON that ClickHouse can't ingest (for example nesting past its depth limit) used to fail the whole insert batch, so unrelated runs and spans silently disappeared from the runs list, traces, and logs. This keeps the rest of the batch and handles the offending row instead of dropping everything around it. ## Fix Recovery is per-table, matched to what each table needs: - **Runs** (`task_runs_v2`) keep their status. We follow ClickHouse's failing-row hint to strip just the un-ingestable JSON column(s) so the run still lands (its output reads from Postgres on the detail page), up to a configurable limit (`RUN_REPLICATION_MAX_POISON_STRIPS_PER_BATCH`, default `1`). Past the limit we stop and land the batch with `allow_errors` in a single pass, skipping the remainder. Cost stays a fixed handful of inserts no matter how large or poisoned a flush is. - **Trace events and payloads** (high volume, append-only) recover with a single `allow_errors` insert: the good rows land in one pass and only the un-ingestable rows are skipped. Before falling back, a lightweight sanitizer still repairs what it can losslessly (lone UTF-16 surrogates, out-of-range integers) so a repairable row lands in full. To read the failing-row hint we patch `@clickhouse/client-common`: its error parser truncates the server response and discards the `(at row N)` position, so the patch preserves the full text for the recovery path to read.
…yment by createdAt (#4452)
…tnami (#4249) ## Summary Self-hosted deployments now run ClickHouse from the official [`clickhouse/clickhouse-server`](https://hub.docker.com/r/clickhouse/clickhouse-server) image instead of `bitnamilegacy/clickhouse`. Bitnami's free image catalog is EOL and the frozen legacy archive tops out at ClickHouse 25.7.5, below the 25.8 minimum the platform requires since v4.5.0, which broke every ClickHouse insert on chart-bundled deployments. Both stacks now default to 26.2, the same version the platform is developed and tested against. Existing deployments keep their ClickHouse data with no manual migration. Fixes #4197. ## Details **Docker Compose**: the `clickhouse` service uses the official image with its native env vars, plus the recommended `nofile` ulimits. It reuses the same named volume as before: a `data-paths.xml` config override points ClickHouse at the `data/` subdirectory of the volume, which is exactly the layout the Bitnami image used, so old volumes work in place (including SQL-created users) and fresh installs get the identical layout. The service follows the required-secrets model: `CLICKHOUSE_PASSWORD` must be set, matching the other services. **Helm chart**: the Bitnami ClickHouse subchart is replaced by a chart-owned single-node StatefulSet and Service running the official image (non-root, HTTP `/ping` probes, config overrides mounted into `config.d`, and the same `data-paths.xml` layout compatibility). On upgrade, the chart automatically adopts the data PVC left behind by the old subchart (`data-<release>-clickhouse-shard0-0`) via `lookup`, and `fsGroup` relabeling handles the uid change on first mount. Both the ClickHouse server and the webapp read the password from the same chart-managed datastore secret (auto-generated and retained across upgrades), so the server credential and the app's connection URL always match. Existing `clickhouse.*` values keep working: `auth` (including `existingSecret`/`existingSecretKey`), `persistence` (including `global.storageClass`), `resources`, `secure`, `external.*`, `configdFiles`, and now `nodeSelector`/`tolerations`/`affinity`. Bitnami-only keys (`shards`, `replicaCount`, `keeper`, `resourcesPreset`) are gone; default `resources` requests/limits match what the old preset applied. The docs state the 25.8 minimum for bring-your-own ClickHouse. ## Upgrade caveats An adversarial review of the upgrade path found a few cohorts that need awareness (all documented): - **GitOps tools that render with `helm template`** (no cluster access): PVC auto-detection can't run, so `clickhouse.persistence.existingClaim` must be set to the old PVC name or ClickHouse starts on a fresh empty volume. Documented in the values file and the Kubernetes self-hosting docs. Tools that run real helm installs (e.g. Flux) adopt automatically. - **A pinned `CLICKHOUSE_IMAGE_TAG`** pointing at a Bitnami tag must be updated to an official image tag; documented in the Docker self-hosting docs. - **Storage without `fsGroup` support** (NFS, hostPath): set `clickhouse.volumePermissions.enabled: true` for a one-time ownership-fixing init container. - **Rollback is not automatic**: once the official image has run, file ownership changes and the Bitnami image can no longer read the volume without a manual chown, and ClickHouse does not support downgrades across the version gap. ## Verification - Full upgrade simulation for Compose, twice (before and after rebasing onto the required-secrets release): booted the ClickHouse service from the old compose file on `main` (Bitnami), wrote thousands of rows, then brought the same project up with this branch's compose file. The official 26.2 server came up healthy on the same volume with all rows intact, SQL-created users working, and writes succeeding. - Adoption scenarios tested against real containers: old volume + root entrypoint (Compose), old volume owned by the Bitnami uid + non-root 101 with fsGroup-style group permissions (Kubernetes), and fresh volumes for both. - `helm lint`, `helm template` (default values, `existingClaim` set, external ClickHouse, volumePermissions/scheduling toggles, and the production example) and kubeconform all pass, mirroring the release CI steps. The rendered webapp Deployment and ClickHouse StatefulSet resolve to the same datastore secret key. - Inserts using `input_format_json_infer_array_of_dynamic_from_array_of_different_types` (the setting that fails on 25.7.5) succeed on the upgraded volume. ## Upgrade preflight and docs A production upgrade report on this branch surfaced two hazards that predate this PR — both landed in chart 4.5.6 (#4316) — so they are fixed here rather than left for the next person to hit. **`secrets.existingSecret` gained two required keys.** The webapp started reading `PROVIDER_SECRET` and `COORDINATOR_SECRET`, and when `existingSecret` is set the chart generates nothing, so a missing key only surfaced as a `CreateContainerConfigError` partway through the webapp rollout. The pre-install/pre-upgrade validation now looks the Secret up and fails with the complete list of missing keys, leaving the running release untouched. It is skipped under `helm template` and client-side dry-run, where `lookup` cannot read the cluster. **Bundled datastore credentials moved into the chart-managed Secret** (`<release>-clickhouse`/`admin-password` → `trigger-datastore`/`clickhouse-admin-password`). The chart wires both ends itself, but consumers outside it — maintenance CronJobs, Grafana datasources, secret syncs — have to be repointed. A new `## Upgrading` section in the Kubernetes docs carries the old→new mapping, the two new keys, and a pointer to the ClickHouse image notes. The existingSecret key list in the docs also named `OBJECT_STORE_ACCESS_KEY_ID`/`OBJECT_STORE_SECRET_ACCESS_KEY`, which are env var names rather than keys the chart reads; corrected to the real key names and the condition under which they apply. Verified on a throwaway kind cluster with `--dry-run=server`: a pre-4.5.6 Secret fails with both key names listed, the documented `kubectl patch` clears it, and default values, `existingClaim`, external ClickHouse, volumePermissions/scheduling and the production example all still render. A real `helm install` followed by an upgrade against an incomplete Secret aborts with the release still at revision 1 and `deployed`. `helm lint`, the CI render and kubeconform (59 resources, 0 invalid) pass. --------- Co-authored-by: nicktrn <55853254+nicktrn@users.noreply.github.com>
…sk and agent pages (#4454) ## Summary The task, scheduled task and agent pages now name their runs table with its own title bar, and the controls that page the table sit beside it rather than in the bar at the top of the page. The top bar keeps just the date filter. Two agent page layout bugs are fixed along the way: scrolling a wide runs table sideways dragged the charts off screen with it, and the details panel stopped short of the bottom of the window. ## Fix The charts moved because the runs table had no horizontal scroller of its own. `stickyHeader` swaps the table's `overflow-x-auto` for `overflow-visible`, so the overflow escaped up to the page scroll box, and setting only `overflow-y-auto` on that box leaves the computed `overflow-x` at `visible`, which CSS then promotes to `auto`. The chart grid is a sibling inside that box, so it scrolled too. The table now keeps its own scroller (the same rule the queues list already documents) and the page box clips x so this cannot recur. The short panel was a second `PageContainer` wrapping the agent routes. `PageContainer` is `grid-rows-[auto_1fr]`, so a lone child lands in the `auto` row and its `h-full` resolves against content height instead of the viewport. This also reverts the global tooltip `max-w-[230px]` introduced in [#4131](#4131), so longer tooltips are no longer squeezed into a narrow column. ### Agent overview page showing table now scrolling <img width="3452" height="1648" alt="CleanShot 2026-08-01 at 12 04 38@2x" src="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/user-attachments/assets/ef1ac55d-8ffb-4278-983b-031ed21c1f55" />
…mit (#4445) The Help & Feedback → "Contact us" form in the sidebar intermittently failed to send. The `<Feedback>` dialog was nested inside the Help popover, so clicking **Send** closed the popover and unmounted the form mid-submit — canceling the `POST /resources/feedback` before it went out. The message was silently lost (the success toast still shows). A race, so it "worked sometimes"; the standalone "I'm stuck!" path was unaffected. **Fix:** host the Feedback dialog *outside* the popover (same pattern as `AskAIRoot`) and open it from the menu item, so closing the popover no longer tears down the form. `Feedback` gains an optional controlled `open`/`setOpen` mode; existing `button`-triggered usages are unchanged. ## Changes - `Feedback.tsx` — optional controlled `open`/`setOpen`; `button` now optional. - `HelpAndFeedbackPopover.tsx` — "Contact us…" opens a `<Feedback>` hosted outside `PopoverContent`. - `.server-changes/fix-sidebar-feedback.md` — user-facing note. ## Testing Webapp typecheck passes. Sidebar "Contact us…" now sends on every attempt (Network: `POST /resources/feedback` → `204`, never `(canceled)`); "I'm stuck!" and the `?feedbackPanel=` open path unchanged.
… it (#4438) ## Summary The Queues list and queue detail pages opened on a 1 day window, and went back to it every time you navigated between queues or reloaded. They now default to the last hour, and the period you pick is remembered across navigations and refreshes. ## Design The last period is stored in a `queueMetricsPeriod` cookie, written client-side whenever a `period` lands in the URL and read by both loaders. A cookie rather than localStorage because the queues list renders its per-queue metrics columns server-side: with localStorage the page would paint the 1 hour default and then re-fetch, and the picker would flash the wrong window. Both pages resolve the window once, in one place, and pass it down: ```ts period: resolveQueueMetricsPeriod({ period: value("period"), // a usable period in the URL wins from: value("from"), // an absolute range means "no period" to: value("to"), defaultPeriod, // otherwise the remembered default from the loader }), ``` That keeps the picker pill and every chart query on the same value, so no call site falls back to its own default. Periods the picker could never produce (a hand-edited `?period=garbage`, or a window past the 30 day retention) fall back to the default, and the picker renders the resolved window rather than the raw search param so the label can't disagree with the data. Absolute from/to ranges, including drag-to-zoom, are not remembered, since they would pin later visits to a window that has gone stale. While wiring that up: the two queue-metric queries that go straight to ClickHouse (the list table and the concurrency-keys endpoint) never applied the org's `queryPeriodDays` limit, so a hand-typed `?period=` read further back than the plan allows. Everything behind `/resources/metric` is already clipped that way by `executeQuery`; both of these now clip with the same limit, capped at the retention window, and the plan cap is resolved once per load and handed to the page instead of each route deriving its own copy from the client-side subscription. Verified on both pages: default with no cookie is 1 hr, picking 6 hrs survives navigating away and back to a param-free URL and a hard reload, clearing the cookie returns to 1 hr, an oversized period falls back without being remembered, and an absolute range still renders as a range.
Restructures the Kubernetes self-hosting guide around two explicit paths - an **evaluation install** (bundled datastores, one command) and a **production install** (external datastores, your own secrets) - so every configuration decision belongs to one path or the other instead of being a flat list of options with caveats. Also in this pass: - Adds an architecture overview (component-to-`values.yaml` map) and a post-install "verify it" step. - Consolidates the previously scattered upgrade notes into a single collapsible group, and cuts implementation detail and historical asides that no longer apply. - Removes a duplicated object-storage section (two configs in two styles) and trims the Docker ClickHouse note down to what a self-hoster needs to act on.
## Summary Environment API keys backed by the additional-key table can authenticate API requests using their stored effective scopes. Revoked and expired keys are rejected, branch environments retain their existing routing behavior, and last-used timestamps are updated on a throttled best-effort basis. ## Design API route builders receive the resolved ability and reject restricted keys on routes without an authorization declaration. Existing deployment, environment variable, queue, run, task, batch, session, and waitpoint routes declare the resources they access. Trigger and batch responses return server-signed public access tokens, so additional keys never need access to the environment signing secret. Root-key rotation also keeps public tokens valid for the existing grace window. ## Feature notes - Root environment keys remain unrestricted for backward compatibility. Additional keys enforce their persisted scopes and fail closed on routes without an authorization declaration. - Machine-key requests never exchange one credential for another. Additional keys cannot retrieve the root key, and rotated root keys are not upgraded during their grace window. - Public JWT validation remains host-owned, while installed RBAC plugins continue to supply root-key abilities. - Unfiltered session and run listings preserve existing broad task-read behavior. Filtered requests enforce the supplied task identifiers. - Related-run summaries remain embedded in run retrieval for API compatibility. Retrieving or mutating a related run independently still requires permission for that run. - Queue management authorizes at collection scope, matching the queue permissions currently issued. - Batch responses deliberately include server-signed public access tokens for all clients. Selected-task credentials continue using their original credential for per-item authorization. - Two-phase batches authorize declared task identifiers before creation and authorize every streamed item. Streaming paths that cannot declare the complete task set remain fail closed. - Authentication telemetry records successful credential resolution separately from subsequent resource-authorization failures. - API keys are high-entropy random tokens. SHA-256 is intentionally used for deterministic indexed lookup, not password hashing. ## Deployment notes The schema migration must be present before this code is deployed. Because bearer resolution runs on every authenticated request, deploy the resolver with additional-key lookup disabled, verify root-key and public-token parity, then enable lookup before any additional keys can be issued. The multi-task authorization tightening changes the result for narrowly scoped tokens that request tasks outside their grants. Observe would-deny results before enforcing that check. Request-idempotency keys are also newly isolated by environment and task, so a retry crossing the deployment boundary may execute once more before old cache entries expire. ## Follow-ups - [x] Add a system-wide kill switch for additional-key lookup, defaulted off for the initial deployment. - [x] Add authentication observability by credential kind, result, latency, and lookup path without recording credential values. - [ ] ~Add would-deny observability and an independent enforcement switch for multi-task authorization.~ - [ ] ~Add an independent switch for server-issued batch tokens while root-key parity is verified.~ - [ ] Confirm every API route reachable by a restricted key has an explicit authorization declaration or intentionally fails closed. - [x] Verify root-key rotation, revoked-key grace, and public-token validation through each bearer resolver path.
…4488) GET /api/v1/reports/health threw `no catalog registered for report "health"` in production (fine in dev): the catalog registered itself as a side effect of a bare import, which the SSR build tree-shakes under `"sideEffects": false`. Verified on the built server bundle — main's is missing the catalog, this branch's carries it. Fix: catalogs are values on the report registry entries; the resolver reads them from there and the mutable register-at-import step is gone.
Adds `Leafgard` to the list of vouched outside contributors so their PRs aren't auto-closed by the vouch check. Closes #4487
## Summary The four charts above the queues table aggregated over **at most the 25 queues on the current page**. They reused the loader's already-paginated queue array as a ClickHouse `queue IN (...)` filter, so paging or re-sorting changed the values, and a name search matching nothing blanked the whole chart row. The stat tiles above them were already environment-wide, so the two rows disagreed. They now read `env_metrics`, the environment-level rollup that already exists for exactly this (the built-in Queues dashboard and the health report read it). That is both correct and queue-count-independent: no `GROUP BY queue` across an entire environment, and no client-side summing. Note this is not only a paging artifact: page 1 under-reported too. On the seeded environment below, page 1 read 82% saturation against a true 87%, because the environment's running total is not the sum of one page of per-queue gauges. Three related fixes ride along. **Scheduling delay and throttling sawed to zero.** Both are event-driven, so at the 10-second bucket a short range picks, most buckets hold no samples at all and were drawn as `0ms`. Measured over a 1-hour window: **232 of 349 buckets had no scheduling-delay samples**. A bucket where nothing started is not a bucket where nothing waited, so the line was both ugly and wrong. TRQL grows a `minBucketSeconds` floor, plumbed through the metric resource route, and the hero tiles set 60s. Buckets that still have no samples render as a gap instead of a dive to zero. **The floor must not feed a width-dependent headline.** Two of the four headlines are not peaks, so widening the plotted buckets moved them: - **Throttled** is a share of buckets that saw any throttling, so a single brief throttle came to mark a whole minute instead of ten seconds: the same seeded events read 17% at 10s and 85% at 60s. - **Scheduling delay p95** is a percentile, and merging quantile states over a wider bucket yields a p95 between the sub-buckets' own. Two 240s samples among twenty in one 10-second sub-bucket give a worst-of-six p95 of 240,000ms against a merged 60-second p95 of 5,000ms — a 48x understatement of a headline whose tooltip claims it is the worst in the window. Both charts keep the floor, since a readable line was the point of it. Their headlines now come from a second query at the range's natural bucket width, via an optional `readout` on the tile, so each means what its tooltip says regardless of how the plotted buckets are sized. Saturation and backlog are genuinely width-invariant (a max of maxes is the same at any width), so they are unchanged and issue no extra query. Both caught by Devin in review; I had wrongly lumped p95 in with the peaks. **Charts reported a hydration mismatch on every render.** Recharts resolved victory-vendor's CJS entry on the server and its ESM entry in the browser. Those bundle different d3-shape builds, and the CJS one predates d3-path's digit rounding, so every server-rendered curve carried full-precision coordinates while the client rounded to 3 decimals: ``` Server: M0,3C0.9305555555555555,3,1.8611111111111112,3,... Client: M0,3C0.931,3,1.861,3,... ``` Bundling recharts for SSR makes both sides resolve the same ESM build. Verified: 45 of 45 server-rendered chart curves now match the client, and the page loads with an empty console. ## Verification An isolated stack with 40 seeded queues (20 heavily loaded, 20 idle) and 90 minutes of 10-second buckets written into `queue_metrics_raw_v1`, so the real materialized views built `queue_metrics_v1`, `env_metrics_v1` and the 5m rollup. Ground truth for the environment: 260 running against a limit of 300 (**87% saturation**), 800 queued. | | before | after | | -- | -- | -- | | Saturation, page 1 | 82% peak | **87% peak** | | Saturation, page 2 | 5% peak | **87% peak** | | Backlog / delay, page 2 | "No activity" | **800 peak / 59.5s** | | Name search matching nothing | all four charts blank | charts stay environment-wide | | Metric refetches on a page change | 4, each painting a skeleton | **0, no skeleton** | | Buckets drawn as 0ms with no samples | 232 of 349 | **0** | | Throttled readout | 17% | **17%**, unchanged by the wider buckets | | Worst-p95 readout source | plotted buckets | **natural width**, so a sub-minute spike is not averaged away | | Crosshair reach, hovering one detail-page chart | 2 of 4 others | **4 of 4** | | SSR chart curves mismatching the client | 45 | **0** | The bucket floor was measured across ranges: it widens 10s to 60s at 30m and 1h, and is correctly a no-op at 12h (300s) and 7d (3600s). One extra request per page load, for the throttled readout. The built-in Queues dashboard, which reads `env_metrics` independently, agrees at 86.7% and 260 of 300. `internal-packages/tsql` suite green (612 tests), including 5 new ones for the floor that fail without it. Webapp typecheck, oxfmt and oxlint clean. Spot-checked the Run metrics dashboard and the per-queue detail page for SSR regressions from bundling recharts: both render, console clean. The queue detail page carries the same event-driven series, so its scheduling delay, throttling and per-key mean delay take the same treatment. ## Screenshots <img width="2540" height="580" alt="after-page1-charts" src="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/user-attachments/assets/6cd23f9c-e7fd-4918-bcfa-b1d3340b16d1" /> ## Rollout Already behind the per-organization `queueMetricsUiEnabled` flag, so only gated orgs see any of it. Blast radius is chart values on one page plus the SSR bundling of recharts; rollback is a revert with no data migration. ## Stated limitations - `wait_ms_count` and the quantile state both only count `wait_ms > 0`, so "nothing started in this bucket" and "everything started instantly" are indistinguishable in storage. Both render as a gap. Distinguishing them needs a schema change, which is not in this PR. - The queue name search deliberately no longer narrows the charts. It only did so incidentally and incorrectly before (first 25 matches, and blanked on zero matches). Search-scoped charts would need the full unpaginated matching set and a server-side aggregate; worth its own ticket if we want it. - Bundling recharts for SSR grows the server bundle slightly. That is the cost of both sides resolving one d3-shape build. - The plotted delay line is a smoothed 60-second view, so a sub-minute spike above the one-minute warning threshold can fail to colour the line even though the headline reports it and colours itself. - Every chart inside one synced group shares the floor, because the hover crosshair is a reference line on a category x-axis and only draws where the hovered bucket exists in the other chart's own data. That costs the queue detail page's gauges some resolution (1 minute instead of 10 seconds) in exchange for the crosshair working across the row. Separately, while taking the screenshots I found a pre-existing rendering bug unrelated to this change: a **perfectly flat** saturation series draws no line at all (the readout still shows the right percentage), which looks like the threshold gradient's offset degenerating when the series min equals its max. It reproduces on `main`, so it is not a regression here and I have left it alone; filed as its own issue. Refs TRI-12784
## Summary
Self-hosted Kubernetes deployments can now add tolerations to run pods,
so runs
can schedule onto tainted nodes. Previously the only way to do this was
to patch
the supervisor.
`KUBERNETES_RUNNER_TOLERATIONS` takes a comma separated list of
`key=value:effect`, or `key:effect` to tolerate any value. It applies to
every
run pod, and for runs from a schedule tree it merges with the existing
`KUBERNETES_SCHEDULED_RUN_TOLERATIONS`. Left unset, nothing changes: no
tolerations are added and the pod spec leaves the field off entirely.
The Helm chart takes it as a list:
```yaml
supervisor:
config:
kubernetes:
runnerTolerations:
- dedicated=runs:NoSchedule
- spot:NoExecute
```
## Naming
The issue proposed `KUBERNETES_WORKER_TOLERATIONS`. This ships as
`KUBERNETES_RUNNER_TOLERATIONS` instead, because `RUNNER_*` is already
the prefix
for run pod settings (`RUNNER_HEARTBEAT_INTERVAL_SECONDS`,
`RUNNER_ADDITIONAL_ENV_VARS`, and `DOCKER_RUNNER_NETWORKS` for the
Docker
equivalent), whereas "worker" refers to the supervisor itself throughout
this app.
## Validation
Keys and values are checked against the Kubernetes naming rules when the
supervisor starts, so `dedicated=prod runs:NoSchedule` fails immediately
with a
message naming the offending entry. Without that check a bad value is
accepted at
startup and then rejected by the API server on every pod create, which
stops all
runs with the cause buried in an API error.
`KUBERNETES_WORKER_NODETYPE_LABEL` is
trimmed and validated for the same reason: surrounding whitespace is not
valid in
a label value, so a padded value fails every pod create today.
## Node selector off switch
`KUBERNETES_WORKER_NODETYPE_LABEL` accepts an empty string to skip the
node
selector entirely, so runs schedule on any node. This already worked and
the Helm
chart has always shipped it empty, but it was not documented. It is now.
The issue also asked for general node affinity configuration. That is
not
included: the node selector off switch plus tolerations covers the
reported
problem, and a free form affinity setting is a much larger config
surface to
commit to.
Fixes #4458
…#4444) The dequeue brake released the moment its signal became unreadable. `refresh()` caught any error from `source.read()` and set the verdict to `null`, which `computeEngaged()` treats as not-engaged — so a few failed reads dropped an engaged brake, silently, with no log and no metric. That handling was symmetric while the risk is not. A source that has stopped answering correlates with the pressure the brake exists for, so releasing on read failure gives up protection at exactly the wrong moment; holding too long only costs throughput. Now a failed read keeps the last verdict instead of discarding it. The verdict then ages normally, so the existing `maxVerdictAgeMs` check becomes the grace window and still bounds how long a dead source can hold the brake — a permanently unreachable source releases it rather than pinning dequeuing forever. Because `computeEngaged()` only consults staleness for an *engaged* verdict, a released one is unaffected and stays released. The default grace moves from 15s to 120s, comparable to how long the brake normally stays engaged. One guard worth calling out: holding is only safe when something bounds it, so when `maxVerdictAgeMs` is unset the previous discard behaviour is kept. Otherwise an unbounded hold could pin the brake indefinitely. Read failures were previously invisible — the catch block neither logged nor counted. Adds a `read_failures_total` counter, plus an error log on the transition into failure rather than once per tick, since the refresh loop runs every second. The post-release ramp needs no change: it anchors off the engaged-to-released transition, so a grace-window release still ramps back up instead of snapping to full rate, which is what you want after a blind period. Tests cover holding while reads fail, releasing past the max age, and the existing unbounded-config paths are unchanged.
## Summary The webapp's server bundle imports `prop-types` directly, but the package was declared only as a `devDependency`. A production install therefore leaves it out and the built server fails to boot: ``` Failed to start server: Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'prop-types' imported from /triggerdotdev/apps/webapp/build/server/assets/server-build-*.js ``` Moving it to `dependencies` is the whole change. ## Why the bundle imports it Nothing in the webapp's own code uses `prop-types` — there is no reference to it, or to `PropTypes`, anywhere under `apps/webapp/app`. It arrives through `recharts`, whose `react-smooth` dependency still declares `propTypes` on its components. That was invisible until recently. While `recharts` was resolved at runtime, its `prop-types` import was satisfied inside `recharts`' own dependency tree, which is production all the way down. #4486 added `recharts` and `victory-vendor` to `ssr.noExternal` to fix a hydration mismatch on every server-rendered chart; that inlines `react-smooth` into the server bundle, which moves its `prop-types` import into the webapp's own resolution scope — where the package was not available in production. So the bundling change was correct about *which* d3-shape build both sides resolve, and wrong about what the production runtime would be able to find. ## Verification `docker/Dockerfile` builds the runtime dependencies with `pnpm install --prod` against a `turbo prune --scope=webapp --docker` output, so I reproduced exactly that: pruned the workspace, installed with `--prod`, and imported `prop-types` from `apps/webapp`. | | result | | -- | -- | | `main` as it stands (devDependency only) | `FAILS: ERR_MODULE_NOT_FOUND` | | with this change | `prop-types resolves OK` | It resolves both as a CommonJS `require` and as an ESM `import`, which is the form the bundle uses. I also checked this is not one symptom of a wider problem: of the 169 bare specifier roots the server bundle imports, `prop-types` is the **only** one that is a devDependency and not a production dependency. The rest are node builtins or production dependencies. The hydration fix from #4486 is unaffected — the rebuilt bundle still carries the rounding d3-path build. ## Notes `prop-types` is inert in production (its entry point swaps in `factoryWithThrowingShims`), so this adds a 124 KB package that does no work at runtime. It has to be resolvable regardless, because the import is real. An alternative would be adding `prop-types` to `ssr.noExternal` so it is inlined and needs no runtime resolution. That keeps the dependency list honest about the fact that the webapp itself does not use it, at the cost of bundling a CommonJS package into the ESM server output. This route is the smaller, better-understood change. Worth following up separately: a check that every bare import in the server bundle resolves from a production install would have caught this before it landed. Local development installs every devDependency, so the gap is invisible when the built server is run from a working tree.
Adds System Preferences, Dark and Light themes, gated by the `hasThemeSwitcher` feature flag (off by default — dark stays the default theme for everyone). Old theme is now "Classic"and set as default. "System preferences" theme has both Light and Dark modes and uses your laptop settings to use a correct one. It has less color accents (specifically less colored text), and they are the same for both modes, only grayscale values change between them. And Light/Dark themes can be used separately. New Contrast setting is available for System Preferences, Dark and Light themes - it changes the contrast for the whole app. All new visual Settings live in Account.
Adds `Rohan170603` to the list of vouched outside contributors so their PRs aren't auto-closed by the vouch check. Closes #4498
…#4493) When a run reaches a terminal state, ask the checkpoint service to reclaim the storage its checkpoints occupied. Storage for finished runs is not otherwise reclaimed, so nothing frees it today. **Off by default** behind `DELETE_CHECKPOINTS_ON_COMPLETION`, and the service-side handler ships separately, so merging this changes no behaviour. ## Where the tenancy comes from Addressing a run's checkpoints needs org, project, environment, deployment version and run id. All five are already in hand at `attempt.complete`, and three are **signed** by the deployment token: | Value | Source | Trust | | -- | -- | -- | | org | claim `org_id` | signed | | environment | claim `environment_id` | signed | | deployment version | claim `deployment_version` | signed | | project ref | `x-trigger-workload-project-ref` header | runner-supplied | | run | route param | runner-supplied | `authorizeWorkloadRequest` previously returned only `environment_id`, and only in enforce mode, so it now also returns the verified `claims`. That difference is deliberate and documented on the method: claims are used to address a run's **own** resources locally, never to scope the platform, which is why `environmentId` stays enforce-only. The two runner-supplied values are safe because the signed ones are outermost - a runner lying about either can only name something inside its own org and environment, and a project ref that doesn't pair with its signed environment matches nothing. The run id is read from `params.runFriendlyId`, the same value the platform just validated, rather than from the body or a header. Where both a claim and a header exist (`deployment_version`), the claim wins. ## Placement The call sits after `reply.json(...)`, so the runner sees no added latency - the same shape the suspend route already uses. The service enqueues and returns 202, so it is one fast local hop. Terminal means `RUN_FINISHED` **or `RUN_PENDING_CANCEL`** - a run cancelled mid-execution never restores, and skipping it would leave its storage behind. Retries are excluded deliberately: reclamation is per-run, so a retry is covered by the final completion. Also gated on `!snapshotService`, so it stays inert where checkpoints aren't the kind this reclaims. ## Observability `checkpoint_delete_requests_total{result}` counts `sent` **and every reason we decide not to send**: `disabled`, `not_terminal`, `no_claims`, `no_project_ref`, `http_error`. The negative labels are the point - without them, "no requests are happening" looks identical to the feature being switched off. `no_claims` is reachable even under enforcement, since enforce only rejects a *present-but-invalid* token; an absent or legacy id still passes with no claims attached. ## Notes for review - **No changeset**: `CheckpointClient` is `core/v3/serverOnly`, an internal service-to-service API rather than customer-facing surface. - **No `.server-changes/` note**: there is nothing a dashboard user would notice here. Happy to add one if you disagree. - `pnpm run typecheck` can't complete in my checkout - `@trigger.dev/database` fails to build on a missing `tsc` in the pnpm store, unrelated to this diff. Verified with `tsc --noEmit` against the supervisor project instead: **zero errors in `apps/supervisor/src`**. Worth noting it caught a real bug here - the completion response is wrapped, so the status is `data.result.attemptStatus`. refs TRI-12789
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #
✅ Checklist
Testing
[Describe the steps you took to test this change]
Changelog
[Short description of what has changed]
Screenshots
[Screenshots]
💯