Commit Graph
707 Commits
Author SHA1 Message Date
hugocasaandClaude Opus 5.5 ed9f8d9fc4 run the weekly ai evals on global and cli across sonnet, opus, gpt-6 and deepseek (#11540)
* feat: run the weekly ai evals on global and cli across sonnet, opus, gpt-6 and deepseek

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep claude- prefixed and capitalised aliases in the cli model filter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:46:08 +02:00
hugocasaandClaude Opus 5.5 222dad1d8c fix: run each ai eval model in its own job and let the docs tools reach the backend (#11533)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 16:43:41 +02:00
hugocasaandClaude Opus 5.5 f74113c75a post ai eval results to the workspace-prefixed cloud route (#11473)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:26:34 +02:00
Ruben Fiszel f1d970bd1a ci: move CI AI models to opus 5.5, gpt-6.1 sol and deepseek v4.1 (#11461)
* ci: move CI AI models to opus 5.5, gpt-6 and deepseek v4.1 flash

* test: point the deepseek eval alias at v4.1 flash

* ci: run the codex review on gpt-6.1-sol with codex cli 0.159.3
2026-10-01 11:11:57 +02:00
dependabot[bot] 94924d4644 chore(deps): bump docker/build-push-action from 5 to 7 (#11421)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 10:49:45 +02:00
hugocasaandClaude Opus 5.5 e117871bec weekly ai evals on current models, and claude 5.5/gpt-6 support (#11409)
* feat: run ai evals weekly on current models and post results to a dashboard

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: add current flagship models, a reasoning flag and claude 5.5 defaults

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: never send a reasoning disable claude 5.5 or gpt-6-astra reject, and treat gpt-6 as a reasoning model

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: address review on gpt-6 support, chat completions tools and model metadata

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: leave tiered gpt-6 unpriced and drop the off sentinel on gpt-5 and o-series

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: point the ai_evals readme at the model registry instead of copying it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: encode the reasoning rules as per-family maps with a shared parity fixture

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep the chat completions tools rule open-ended past gpt-5.6 and scope the parity fixture

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 13:10:24 +02:00
9a1c6e5081 feat: let a workspace withdraw operator schedule and trigger writes (#11226)
* feat: let a workspace withdraw operator schedule and trigger writes

Operators can create, edit and delete schedules and triggers today through the
API, CLI and MCP, while the operator_settings flags beside them only hide those
pages. An admin who wants operators to see what is scheduled without letting
them change it cannot express that. Add manage_schedules and manage_triggers as
enforced settings, gated at the schedule handlers and at the generic TriggerCrud
routes so every trigger kind is covered by one check.

They name capabilities operators already hold, so they are granted unless
withdrawn, and absence has to mean "never configured" rather than a value. The
read coalesces to true; the update endpoint merges into the stored jsonb with
the two fields as Option<bool>, so an omitted key keeps what is stored.
operator_settings is git-synced as a whole object, so a settings file written
before these keys existed reaches the endpoint on every pull, and a serde or SQL
default of either polarity would turn that pull into a silent withdrawal or
restoration.

The rights are read through a per-process cache, so withdrawing one publishes a
notify_event that drops the entry on every replica.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsf6VC4MVLisiEoeQkgbr4

* feat: enforce operator write rights on the router and in the UI

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: close the capture gap and gate the trigger editors' write actions

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: gate acl writes and the native trigger drawer behind manage rights

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: refuse operator writes with 403 and gate sharing at the drawer

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* perf: resolve identity in the operator write gate only for writes

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: gate the suspended-jobs actions and stop the route check refusing reads

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: explain the empty-state create button when operator writes are withdrawn

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: audit operator settings changes and fold path writes into native rows

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: open locked editors read-only and group the operator settings

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: skip email and azure lookups on editor open while triggers are locked

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: state each operator-rights rationale once in comments

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: address CI review findings on operator write rights

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: keep capture move gated and skip it in the builders while locked

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: keep admin and operator exclusive when setting a workspace role

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor: use the shared section component for operator settings groups

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2026-09-25 17:34:58 +00:00
Alexander PetricandClaude Opus 5.5 8caf414301 fix(multiplayer): a malformed frame from one client no longer exits the server (#11353)
* fix(multiplayer): don't drop client messages during cold-start token verification

`wss.on('connection')` awaits `verifyToken()` before `setupWSConnection()`
attaches the 'message' listener. On a cold process that await includes the
first `/api/debug/jwks` fetch (~30ms on ECS). A y-websocket client sends sync
step 1 the instant the socket opens, and `ws` drops messages emitted with no
listener attached, so that step 1 was lost and never answered with step 2 —
the client's provider never became `synced`.

Buffer messages from the moment the connection is accepted and replay them, in
order, once `setupWSConnection()` has installed its handlers. Rejected
connections drop the buffer and close with the same 4401/4403 codes as before.

Also prefetch the public key at startup when WINDMILL_BASE_URL is set. That is
insurance, not the fix: a connection arriving before the prefetch resolves
still relies on the buffer.

Adds `npm test` in multiplayer/ (node:test, no docker or backend needed) with a
fake JWKS endpoint that answers with a delay, which holds the cold window open
and makes the race deterministic; wired into the existing test_extra CI job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(multiplayer): cap what an unauthenticated peer can buffer pre-auth

Review follow-up.

The pre-auth buffer was unbounded: `ws` sets no `maxPayload` here and the JWKS
fetch has no timeout, so a peer that never authenticates could stream frames
into memory for as long as `verifyToken` was stalled. Cap it at 32 frames /
1 MiB — a real client only has sync step 1 and its first awareness update in
flight there — and close 1009 past that, dropping what was buffered.

A socket closed during verification (by the peer, or by that cap) is no longer
handed to setupWSConnection: it would be added to `doc.conns` with a 'close'
listener that can never fire.

The startup prefetch's .catch was dead code — getPublicKey() logs its own
failures and resolves to null rather than rejecting.

Test helper: pin REQUIRE_SIGNED_MULTIPLAYER_REQUESTS and BASE_INTERNAL_URL so an
ambient value cannot turn the rejection tests into false passes; bind the JWKS
server on port 0 instead of a released probe port, and retry the spawned server
on EADDRINUSE; destroy still-delayed JWKS responses on teardown, since
server.close() waits for in-flight requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): gate the JWKS response instead of delaying it

Review follow-up.

The cold window was held open by a 1500 ms delay on the fake JWKS response, but
that timer started when the startup prefetch reached the fake server, not when
the client sent its first frame. A slow enough machine could load the key before
the client connected, and the race test would then pass without ever exercising
the buffer — a false pass.

The fake JWKS server now parks every response until the test calls release(), so
the server provably holds no key while the client is sending. The race test
releases only after both frames are written to the socket, and asserts the
server has not logged the key as loaded at that point; the flood test never
releases until after the cap has closed the connection.

What is left to wall-clock time is 250 ms for bytes already written to the socket
to cross loopback into an otherwise idle server, rather than a window that had to
cover process startup, connect and handshake.

Also drops the prefetch precondition from the forged-token and flood tests so
each test still maps to one behaviour. Suite runs in ~1.1s instead of ~5.3s.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(multiplayer): survive a malformed frame instead of exiting the process

`setupWSConnection`'s message handler decoded whatever an authenticated peer
put on the wire with no guard: `decoding.readVarUint`,
`syncProtocol.readSyncMessage` and `awarenessProtocol.applyAwarenessUpdate` all
throw on input they cannot parse, `ws` re-emits a listener's exception on the
process, and server.mjs installs no `uncaughtException` handler. One bad frame
from one client therefore killed the whole multiplayer server, taking every
other document and every other client with it.

Catch decode/apply failures, log the document, the client address and the error
message (never the payload), and close only the offending connection with 1007
"invalid frame payload data". Frames that arrive once a connection is no longer
OPEN are ignored, so the replay of the pre-auth buffer stops at the first
refusal instead of applying the rest.

docker/entrypoint-extra.sh made that outage permanent: on a service exit it
logged a bare PID and then `wait`ed on the rest, so the container stayed up with
a dead service and the health checks in front of it — which probe the LSP — saw
nothing wrong. It now names the service that died, stops the others through the
same shutdown path SIGTERM uses, and exits non-zero so the orchestrator replaces
the container. The "no services enabled" branch still sleeps.

Tests: multiplayer/test/malformed_frame.test.mjs covers four malformed payloads
from an authenticated client and one replayed out of the pre-auth buffer,
asserting the 1007 close, a live server process, an undisturbed bystander and a
real edit still propagating. docker/test_entrypoint_extra.sh runs the real
entrypoint in a container with stub services.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): prove the replayed malformed frame really is buffered pre-auth

Assert the server has not yet logged the loaded key when the frame is written,
and give it the same in-flight margin as the cold-start tests before releasing
the JWKS response, so the frame provably goes through the replay path rather
than landing on an already-authenticated connection.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* ci(extra): run the entrypoint supervision tests in publish_extra

The multiplayer unit tests already run there; the entrypoint test needs only
docker and the checkout, so run it in the same job, before the image build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(multiplayer): handle WebSocket protocol errors and bound the shutdown

Two crash paths of the same class as the malformed-frame one, from review.

`ws` fails a frame it cannot parse at the protocol level — an unmasked frame
from a client, a reserved opcode, a bad RSV bit — inside its Receiver, before
the application 'message' handler ever sees it, and `receiverOnError` ends with
`websocket.emit('error', err)`. With no 'error' listener that is an unhandled
EventEmitter error, so it exited the process just as a malformed payload did.
(A raw socket error such as ECONNRESET does not: ws 8.21.3's `socketOnError`
swallows those.) Add the listener on the accepted socket, before authentication
so the pre-auth window is covered too, and one on the server.

Log messages now go through `describeError`, which collapses whitespace and
truncates, so nothing that reaches an error message can forge or flood a log
line.

`stop_services` ended in a bare `wait`. On the `docker stop` path dockerd
provides the deadline; the "a service died" path signals itself, so a service
that is wedged or slow to honour SIGTERM would hold the container open
indefinitely — the state that path exists to prevent. Bound it: SIGTERM, wait
SHUTDOWN_GRACE_SECS (10 by default), then SIGKILL the stragglers by name.

Tests: multiplayer/test/socket_error.test.mjs (authenticated and pre-auth
illegal frames, asserting a live process and continued service), a
SIGTERM-ignoring stub scenario in docker/test_entrypoint_extra.sh, and that
harness is now bounded throughout — `timeout -k` on foreground runs, a watchdog
around the backgrounded ones, and an optional outer timeout on `docker run`.
`--entrypoint bash` so the documented windmill-extra:test override runs the
harness instead of the image's real entrypoint. The stubs publish a readiness
marker and the dying one waits for them, removing a startup race in the harness.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(multiplayer): never log peer bytes, and keep a fatal server error fatal

Two review findings on the previous commit, both mine to answer for.

`describeError` collapsed whitespace, which is not enough. An error message is
not always a fixed string: `applyAwarenessUpdate` runs `JSON.parse` on the
peer's bytes and V8 quotes ~30 bytes of the offending input back verbatim, ESC
included, so a peer could put terminal escapes and forged content into a log
line. Strip everything outside printable ASCII instead, and say so where the
comment previously claimed the messages were fixed strings.

`wss.on('error')` was worse than the crash it replaced for one case: `ws`
forwards the HTTP server's errors there, so a failed listen (EADDRINUSE) was
logged and the process then exited 0 — a clean shutdown as far as anything
upstream could tell. It now sets a non-zero exit code. Setting `process.exitCode`
rather than calling `process.exit()` keeps the log line from being truncated.

`openClient` in the test helpers now records the socket error it was already
swallowing, so a failed connection reports its cause instead of surfacing as a
bare `waitFor` timeout.

Tests: a malformed awareness frame whose state is `x\x1b[2J OWNED THE LOG` added
to the payload table, with every case now asserting exactly one refusal line and
no control characters in it (1 fail before, 0 after, 3 runs); and a server that
cannot listen must exit non-zero (1 fail before, 0 after, 3 runs). 14/14 on 5
consecutive runs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): make the exit-status helper robust to spawn and stdio races

Review follow-ups on runMultiplayerServerUntilExit.

Wait for 'close', not 'exit': 'exit' fires when the child terminates, which can
be before its stdio pipes are drained, and the caller reads the output. On the
EADDRINUSE path the child writes one line and exits immediately after, which is
exactly the shape that loses it.

Listen for 'error' too. A child that fails to spawn emits neither 'exit' nor
'close', so the promise would never settle and the SIGKILL guard could not help.

Report whether the guard fired, rather than leaving the caller to infer it from
the exit signal: `signal` is null for every child exit on Windows, so a server
that hung after the listen error would have looked like one that exited on its
own. The test asserts on that flag instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): assert the refusal line itself, and name hasSyncType for what it takes

Two review nits on the test helpers.

The `doc="..."` assertion searched the whole server log, where CONNECT and
DISCONNECT also name the document, so it would have passed even if the refusal
stopped naming anything. Every assertion about the refusal is now made against
the refusal line, which the test already isolates, and it also checks the peer
is named.

`hasKind` took a sync sub-type but was named as if it took any message kind, and
the two families overlap numerically (`syncStep1 === messageSync === 0`), so a
caller passing the wrong one got a silently wrong answer. No runtime check can
tell aliased numbers apart, so the fix is the name: `hasSyncType`, with the
overlap spelled out where the constants are declared.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): make the pre-auth tests prove which path they took

The replay test could not establish that its frame went through the pre-auth
buffer: a frame delivered after setup, into the live handler, produces the same
close code and the same refusal line, so if the in-flight margin were ever
missed the test would quietly become a duplicate of the main-loop cases rather
than fail. server.mjs now logs REPLAY when, and only when, it replays a buffered
pre-auth message — worth having on its own, since that path only runs when a
client beat the JWKS fetch on a slow-starting instance — and the test asserts on
it. Removing that log line turns the test red, which is the point.

The socket-error pre-auth test gated on `jwks.requests >= 1`, which the startup
warm-up already satisfies, so it proved nothing about the offender. What makes
it the pre-auth case is that the JWKS response stays parked for the whole test;
it now asserts the server never logged CONNECT, which is exact.

`killedByTimeout` was set before the kill, so a child that exited on its own just
before the timeout — with 'close' still pending on the stdio drain, the very
window this helper waits for — would have been reported as killed. It now claims
the rescue only when there was a live process to signal.

14/14 on eight consecutive runs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): document the frame-recording contract in openClient

ws hands every frame over as a Buffer under the default binaryType, text frames
included, so recording them as Uint8Array is lossless for both. Worth stating:
ws 7 delivered text frames as strings, where new Uint8Array(string) would have
been a silent zero-fill, and the difference is not visible at the call site.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): pin the close code for an illegal frame, and trim comments to the 4-line rule

Both socket-error tests waited for a close and never checked what it was, so an
abrupt 1006 teardown would have passed while the comment beside the payload
claimed 1002. `ws` sends 1002 for an unmasked frame in both the authenticated
and pre-auth cases, confirmed over repeated runs; that is now a named constant
asserted in each test, mirroring malformed_frame.test.mjs. Changing the expected
value turns both red.

The comments added by this branch also ran past the four lines AGENTS.md allows,
and several justified the change to a reader rather than stating the invariant.
Condensed to the invariant, at the site that would break it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 17:12:47 +02:00
Alexander PetricandClaude Opus 5.5 e8c3f9514e fix(multiplayer): don't drop client messages during cold-start token verification (#11343)
* fix(multiplayer): don't drop client messages during cold-start token verification

`wss.on('connection')` awaits `verifyToken()` before `setupWSConnection()`
attaches the 'message' listener. On a cold process that await includes the
first `/api/debug/jwks` fetch (~30ms on ECS). A y-websocket client sends sync
step 1 the instant the socket opens, and `ws` drops messages emitted with no
listener attached, so that step 1 was lost and never answered with step 2 —
the client's provider never became `synced`.

Buffer messages from the moment the connection is accepted and replay them, in
order, once `setupWSConnection()` has installed its handlers. Rejected
connections drop the buffer and close with the same 4401/4403 codes as before.

Also prefetch the public key at startup when WINDMILL_BASE_URL is set. That is
insurance, not the fix: a connection arriving before the prefetch resolves
still relies on the buffer.

Adds `npm test` in multiplayer/ (node:test, no docker or backend needed) with a
fake JWKS endpoint that answers with a delay, which holds the cold window open
and makes the race deterministic; wired into the existing test_extra CI job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(multiplayer): cap what an unauthenticated peer can buffer pre-auth

Review follow-up.

The pre-auth buffer was unbounded: `ws` sets no `maxPayload` here and the JWKS
fetch has no timeout, so a peer that never authenticates could stream frames
into memory for as long as `verifyToken` was stalled. Cap it at 32 frames /
1 MiB — a real client only has sync step 1 and its first awareness update in
flight there — and close 1009 past that, dropping what was buffered.

A socket closed during verification (by the peer, or by that cap) is no longer
handed to setupWSConnection: it would be added to `doc.conns` with a 'close'
listener that can never fire.

The startup prefetch's .catch was dead code — getPublicKey() logs its own
failures and resolves to null rather than rejecting.

Test helper: pin REQUIRE_SIGNED_MULTIPLAYER_REQUESTS and BASE_INTERNAL_URL so an
ambient value cannot turn the rejection tests into false passes; bind the JWKS
server on port 0 instead of a released probe port, and retry the spawned server
on EADDRINUSE; destroy still-delayed JWKS responses on teardown, since
server.close() waits for in-flight requests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(multiplayer): gate the JWKS response instead of delaying it

Review follow-up.

The cold window was held open by a 1500 ms delay on the fake JWKS response, but
that timer started when the startup prefetch reached the fake server, not when
the client sent its first frame. A slow enough machine could load the key before
the client connected, and the race test would then pass without ever exercising
the buffer — a false pass.

The fake JWKS server now parks every response until the test calls release(), so
the server provably holds no key while the client is sending. The race test
releases only after both frames are written to the socket, and asserts the
server has not logged the key as loaded at that point; the flood test never
releases until after the cap has closed the connection.

What is left to wall-clock time is 250 ms for bytes already written to the socket
to cross loopback into an otherwise idle server, rather than a window that had to
cover process startup, connect and handshake.

Also drops the prefetch precondition from the forged-token and flood tests so
each test still maps to one behaviour. Suite runs in ~1.1s instead of ~5.3s.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 15:54:11 +02:00
Alexander PetricandClaude Opus 5.5 16f3ee84f6 ci: file release Docker Scout results under main so the code scanning status and alerts stay current (#11338)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:41:19 +00:00
9375c93fd8 fix: trust the system CA store for SMTP TLS (#11328)
* fix: trust the system CA store for SMTP TLS

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* ci: run the smtp-gated backend tests

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: depend on webpki-roots 1 directly

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 48193da8cb30bc4ae82a50f944caef85d8a20b48

This commit updates the EE repository reference after PR #826 was merged in windmill-ee-private.

Previous ee-repo-ref: cd3447143b25d9f3301975feca4b202755f2508f

New ee-repo-ref: 48193da8cb30bc4ae82a50f944caef85d8a20b48

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-09-24 15:10:28 +02:00
Alexander PetricandClaude Opus 5 40476e7be9 ci: skip the AI reviews and the Discord notice on Dependabot PRs (#11307)
* ci: skip the AI reviews and the Discord notice on Dependabot PRs

They already do not review them, they just fail while doing so. The Claude
action rejects a bot actor outright ("Workflow initiated by non-human actor"),
and the Codex and Pi jobs find no API key because GitHub gives Dependabot-
triggered runs a separate secret scope from Actions. Verified on #11302: zero
reviews posted, the only comment is a Cloudflare deployment notice, while
codex-review and pi-review both reported success.

So every Dependabot PR carried two permanently red checks that meant nothing,
which is the worst kind of signal — it buries a Dependabot PR that genuinely is
broken, and a green tick that means "skipped" reads exactly like one that means
"looked and approved".

Skipping states it honestly. The workflow_call branch is untouched, so a review
can still be requested on a specific bot PR when the diff deserves one, which is
worth doing for a grouped security update that swaps a cipher or drops a parser
rather than just moving a version.

The Discord notice is excluded for the same reason plus its own: nobody wants a
forum thread per lockfile bump.

Not fixed here, deliberately: making these actually review bot PRs would need
the org's review credentials copied into the Dependabot secret scope, which is a
wider grant than this is worth given the PRs in question are lockfile diffs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* ci: gate the close-time Discord job too, and trim the comments

Both reviewers caught the same gap: merge_success_emoji runs on every `closed`
event with no exclusion, and the reusable workflow it calls exits 1 when it
cannot find a thread. Since open_thread no longer creates one for Dependabot,
the failure would have moved from open-time to merge-time rather than going
away. Gated to match.

The comments are cut from eight lines to two per file. AGENTS.md:205 asks for
constraints in <=4 lines, stated once, describing the code as it is — mine
narrated the drafting history and argued the change to a reviewer, both of which
belong in the PR description. Also drops "bot-authored", which overstated a
condition that only covers dependabot[bot].

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:59:50 +00:00
Ruben FiszelandClaude Opus 5 5798bd07e7 build derived release images from this run's image digest, not :dev (#11280)
* fix: build derived release images from this run's image digest, not :dev

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: scope the digest comment to jobs that build from, extract or retag

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 09:25:12 +02:00
dependabot[bot] f39742ae32 chore(deps): bump actions/setup-python from 5 to 7 (#11256)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 14:47:20 +00:00
dependabot[bot] 6dc78049ba chore(deps): bump actions/setup-go from 2 to 7 (#11257)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 7.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v2...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 14:47:09 +00:00
dependabot[bot] 49e0974c07 chore(deps): bump astral-sh/setup-uv from 5 to 7 (#11258)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 5 to 7.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v5...v7)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 14:46:16 +00:00
dependabot[bot] d340bec999 chore(deps): bump actions/setup-node from 3 to 7 (#11260)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 14:46:03 +00:00
Alexander PetricandClaude Fable 5.1 fc7311c13e chore(dependabot): grouped weekly updates for all shipped manifests (#11189)
* chore(dependabot): grouped weekly updates for all shipped manifests

Until now only /frontend, /backend, /, and /python-client/wmill had
Dependabot version-update jobs; the other shipped manifests only ever
produced security alerts and never fix PRs. Frontend and backend also
received one PR per dependency.

Added (weekly, one group each with patterns ["*"]):
  - /cli                     package-ecosystem "bun" (text bun.lock;
                             GA, enable-beta-ecosystems not needed)
  - /windmill-yaml-validator npm (package-lock.json)
  - /typescript-client       npm (package-lock.json, devDependencies only)
  - /multiplayer             npm (package-lock.json)

Grouping of existing jobs:
  - /frontend: frontend-deps (minor + patch) and frontend-majors (major),
    so routine bumps land in one PR and majors can be reviewed on their
    own without blocking it.
  - /backend:  cargo-deps (minor + patch); majors stay as individual PRs
    because they usually need code changes.

open-pull-requests-limit is left at its default (5): with grouping each
manifest yields at most one or two PRs per run, so no override is needed.

Deliberately not covered:
  - /rust-client: Cargo.toml is generated and gitignored
  - /backend/parsers/windmill-parser-wasm: excluded from the cargo
    workspace, needs nightly cargo
  - /benchmarks/pulumi: being deleted in another PR
  - /integration_tests: CI-only

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: group dependabot security updates per manifest

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 14:31:53 +00:00
Ruben FiszelandClaude Fable 5.1 8b4f6220dc refactor: run the flow chat UI on the windmill-chat sdk (#11134)
* refactor: run the flow chat UI on the windmill-chat sdk

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: structural answer check, poll option and latest run in the chat sdk

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: count jobless tool rows and the loaded license in the flow chat

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 12:56:07 +00:00
Ruben FiszelandClaude Fable 5.1 e8c02c04cd feat: windmill-chat sdk for chat-mode flows in external frontends and raw apps (#11117)
* feat: windmill-chat sdk for chat-mode flows in external frontends and raw apps

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018aQiZNAU8g17kWkyTryS5J

* fix: keep streamed answers until persisted, finish turns after history fallback

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018aQiZNAU8g17kWkyTryS5J

* feat: ai sdk transport and assistant-ui runtime for windmill-chat

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: finish a turn from the flow result until its answer row lands, hash chat ids without crypto.subtle

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: judge a turn answered by a persisted assistant row, wherever it was fetched

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: attribute a turn's answer to its own jobs, keep a local turn when switching conversations

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: mirror local history on every change, attribute failure-handler answers to the turn

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: new chat per token string in the React hook, idle after destroy, no reorder on view

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: recreate the hook's chat on any credential change, namespace local history per user

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: send the latest inputs from the React hook

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 22:32:45 +02:00
Ruben FiszelandClaude Opus 5 15c2b81d6c chore: run local codex review on gpt-6-astra, bump codex cli pin (#11011)
* chore: run local codex review on gpt-6-astra and bump codex cli pin

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X8u6o9MRAs2Rz16UbKQaD9

* fix: keep local codex review alive when --version is unparseable

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X8u6o9MRAs2Rz16UbKQaD9

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 08:19:32 +02:00
Alexander PetricandClaude Fable 5 a2417f6fb6 sign release images with cosign, embed SBOMs, attach SLSA provenance (#10983)
* feat: sign release images with cosign and attach SBOM + SLSA provenance

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

* fix: pin cosign-installer to exact version (no floating v4 tag exists)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

* fix: embed SBOMs at build time via depot instead of rekor-bound cosign attest

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

* docs: latest/main tags are only signed until the next main push

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

* fix: gate signing on push events in cli/extra workflows, verify version tag

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

* fix: refuse tag-targeted dispatches in publish workflows, use GITHUB_REF env

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8mi68bMNUFwCge7xAqyky

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-09-05 11:11:20 +00:00
Ruben FiszelandClaude Fable 5.1 b100606da6 fix: patch critical CVEs in the worker image (#10962)
* fix: patch critical CVEs in the worker image (go, node, php, helm, libtiff)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TT3CyQED8iwwmsKMttk6PP

* ci: run the backend tests on node 24 to match the image

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TT3CyQED8iwwmsKMttk6PP

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 17:02:08 +00:00
Ruben FiszelandClaude Fable 5.1 ca8800959a fix: bump git sync hub scripts to cli 1.802.1, test the fork ui pull (#10955)
* fix: bump git sync hub scripts to cli 1.802.1, test the fork ui pull

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011yMLnAWdjpCEs5VyGMn9ww

* test: guard the ui pull preview shape and pin the pull script ids together

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011yMLnAWdjpCEs5VyGMn9ww

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 11:23:23 +02:00
Ruben Fiszel db0f004613 fix: keep windmill-indexer out of builds without tantivy (#10908)
* fix: keep windmill-indexer out of builds without tantivy

* chore: drop the vcpkg openssl-windows port from the other windows jobs
2026-08-31 22:50:21 +02:00
Ruben FiszelandClaude Opus 5 41d111bf38 chore: emit only line tables for workspace crates in dev builds (#10845)
* chore: emit only line tables for workspace crates in dev builds

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQiM8pqagY19bnWiMebwGa

* docs: correct the CI comments that pinned profile.dev at debug = 2

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQiM8pqagY19bnWiMebwGa

* docs: scope the windows debuginfo comment to the crates that job builds

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQiM8pqagY19bnWiMebwGa

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 00:06:51 +02:00
Ruben FiszelandClaude Opus 5 5088e13705 fix(ci): unbreak the windows test jobs and the discord comment relay (#10799)
* test: assert the unpacked repo symlink without following it

`unpack_keeps_a_link_that_stays_in_the_repo` read through the link it had just
unpacked. Windows stores a symlink's target verbatim and its object manager
rejects the `/` in a POSIX one, so `read_to_string` came back with
`ERROR_INVALID_NAME` and the release's `cargo_test_windows` job was red.

Pin what the function is responsible for on every platform — the link is kept
and materialized — and read through it only where a POSIX relative target
resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3WRtxdKNGdomWX9vaAYGx

* test: key the cli sync-map fixtures with the platform separator

A sync map is keyed with the platform separator on both sides — `FSFSElement`
walks the tree with `path.join`, and the remote `ZipFSElement` starts at
`"." + SEP` and joins from there — while an `!inline` reference is always
forward-slash. `lock_dedup.ts` follows that convention; the fixtures did not,
so on Windows they built a map shape the CLI never produces and 12 of them
failed. `getTypeStrFromPath` is the same story: it matches
`"dependencies" + SEP`, and the test handed it a forward-slashed path.

Build the fixture keys through the separator, leaving the `!inline` references
and the `present` map forward-slash, as `sync.ts` hands them over.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3WRtxdKNGdomWX9vaAYGx

* ci: skip the discord comment relay when the thread lookup returns none

A rate-limited or unauthorized Discord response carries no thread list, and
under `bash -e` that aborted the step — jq cannot iterate null, nor parse the
HTML error page Cloudflare answers a 429 with — before it reached the "thread
not found, skipping" branch right below. Three comment relays failed that way
on the 1.794.0 head.

Keep the step green for both, but tell them apart: a response with no thread
list is a delivery that was dropped for a reason worth seeing, so it warns with
the body it got, while a PR that genuinely has no thread stays quiet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3WRtxdKNGdomWX9vaAYGx

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 12:52:06 +00:00
Ruben Fiszel d85050f505 feat: upgrade bun to 1.4.0 and demote deno in the language picker (#10784)
* chore: upgrade bun to 1.4.0 in dockerfiles and CI pins

* chore: move deno last in the language picker and relabel it Deno

* chore: move deno last in the pipeline language picker too

* chore: pin debugger image to bun 1.4.0 and trim the deno picker comment

* chore: state the deno picker constraint without referencing the old order

* fix: stamp bun lockfiles back to v1 while the fleet predates bun 1.4

* fix: ask bun for a v1 lockfile instead of rewriting one, and refuse an escalated lock

* chore: warn instead of silently storing a lockfile with no readable version
2026-08-21 01:16:59 +02:00
343ce6e143 fix: derive a raw app's policy on deploy, and default an omitted execution_mode (#10733)
* fix: default an omitted app policy execution_mode to publisher

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: drop stale comments claiming execution_mode is required

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: derive a raw app's policy on deploy instead of trusting the caller's

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: pin the ee ref to the companion branch

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: vendor the raw-app policy derivation into the bundle job

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: note the vendored raw-app policy bundle

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: derive the policy on a value-only raw-source update too

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: reject raw-app runnables whose shape yields an unusable grant

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: cache the new policy query and tighten raw-app runnable validation

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: let the policy bundle drift guard survive a CRLF checkout

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 23431f5cf1d627051ded89111bbf2e301e9db456

This commit updates the EE repository reference after PR #729 was merged in windmill-ee-private.

Previous ee-repo-ref: 0bdf8818fa115ad6b0d14f3117a18e8a580cce4d

New ee-repo-ref: 23431f5cf1d627051ded89111bbf2e301e9db456

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-08-18 01:52:10 +02:00
Ruben FiszelandClaude Opus 5 66e3790da4 docs: announce we are not seeking outside contribution (#10724)
* docs: announce we are not seeking outside contribution

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: point big ideas at the feature request template

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:27:37 +02:00
AlexRV12andClaude Opus 5 850b028778 feat: advertise the pinned artifact version in get_preview_status (#10691)
* test: let global evals seed the session's preview tabs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: advertise the pinned artifact version in get_preview_status

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test: reject ambiguous preview-tab and artifact eval fixtures

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 18:41:09 +02:00
Ruben Fiszel 0fc74dec5f fix(ci): use random delimiters for untrusted multiline workflow values (#10706)
* fix(ci): use a random delimiter for the review prompt env var

* fix(ci): use a random delimiter for the review command extra_prompt output
2026-08-14 18:38:10 +02:00
Ruben Fiszel 44b7d97e36 chore: improve pi review 2026-08-13 11:59:05 +00:00
Ruben Fiszel 6da1b501e3 chore: improve pi review 2026-08-13 11:41:50 +00:00
4fafe59371 fix: bump the bundled DuckDB engine to 1.5.5 (#10588)
* fix: bump the bundled DuckDB engine to 1.5.5

The 1.5.5 duckdb crate no longer hands back a 96-bit `rust_decimal`, so a
DECIMAL wider than that renders instead of panicking inside an `extern "C"`
frame — which, being unable to unwind, aborted the whole worker process and
left the job running as a zombie. `SELECT
'1234567890123456789012345678.9012345678'::DECIMAL(38, 10)` was enough.

Adapting to the crate's API: `Value` is now `#[non_exhaustive]` and gained
`UHugeInt` and `Geometry`, and `rust_decimal` became an optional feature that
the `decimal`/`numeric` argument path still needs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: address review findings on the duckdb bump

Run the FFI crate's own tests in CI: it is excluded from the workspace, so the
`cargo test --all` in backend-test never reached them and the new guard against
the worker-aborting DECIMAL would not have run. build_dev.sh now honors a
caller-pinned CARGO_TARGET_DIR so the test build reuses that compile instead of
building the bundled engine a second time.

Also pin UHUGEINT rendering, and correct the rust_decimal rationale —
`Decimal::new` is public without the feature, so the reason is that the feature
reproduces the exact binding the crate used to derive, not that nothing else can.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: address review nits on the duckdb bump

Name the unsupported DuckDB type rather than dumping the value, which may be
arbitrarily large or hold data that does not belong in an error message, and
say which column it came from.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: pin the ee ref to the narrowed duckdb extension allowlist

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: pin the ee ref to the verified duckdb extension allowlist

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: pin the ee ref to the allowlist regression test

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 04dd9c5c352f04995cd0470400a877261f956561

This commit updates the EE repository reference after PR #716 was merged in windmill-ee-private.

Previous ee-repo-ref: fe7eb440a5bbae37774d3a96b69ab5c46c0b8936

New ee-repo-ref: 04dd9c5c352f04995cd0470400a877261f956561

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-08-11 09:34:27 +02:00
Ruben Fiszel 1a709d49f9 unblock the frontend check (type error + svelte-check OOM) (#10617)
* fix(frontend): count login options inside a closure so tsc keeps their type

* ci: give svelte-check a heap above node's 4GB default
2026-08-10 19:25:02 +02:00
Ruben Fiszel 5497710d47 chore(ci): drop the now-live dbt quickstart docs-link exemption (#10553) 2026-08-06 00:26:46 +02:00
Ruben FiszelandClaude Opus 5 505705fd3d serve getJob in the ai evals benchmark api catalog (#10511)
* fix: serve getJob in the ai evals benchmark api catalog

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: scope the frontend format hook to the frontend dir

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: answer the run-by-path endpoints and mirror the real getJob entry

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: gate the format hook on a repo-root frontend, not the project dir

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 14:51:48 +00:00
Ruben FiszelandClaude Opus 5 141ed7bae0 never let check-write-access fail the review chain (#10505)
check-write-access is additive by design: every caller ORs its `authorized`
output with `github.event.comment.author_association`, so a failure should
degrade to the author_association path, not block anything.

It does not. `claude`, `codex` and `pi` all `needs: [parse, check-access, plan]`,
so a failed check-access skips `plan` and with it all three reviewers. Any
disruption to the app credentials — an unset `INTERNAL_APP_ID`, a rotated
`INTERNAL_APP_KEY`, the app uninstalled from the org — turns a redundant
authorization probe into a total /review outage.

Guard the token minting and fall back to the default token, which still resolves
public members and repo collaborators; private members fall through to
author_association exactly as they did before this workflow existed.

Found while porting these workflows to windmill-helm-charts
(windmill-labs/windmill-helm-charts#656), where the app credentials are not
guaranteed to be present.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 11:38:51 +00:00
Ruben Fiszel c434703ee7 ci: drive release-please from a manifest config on action v5 (#10494)
* ci: drive release-please from a manifest config on action v5

* ci: trim the release-please config comment
2026-08-04 09:05:32 +02:00
Guilhem 5746674ba7 ci: run ai evals on node 24 so npm ci accepts the npm 11 lockfile (#10482) 2026-08-03 18:51:28 +00:00
Ruben FiszelandClaude Opus 5 053fb98428 repair the two CI jobs that fail on a release tag (#10451)
* test: assert the dbt sslrootcert path with the platform separator

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: let check-docs-links tolerate a link pending a docs deploy

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: fail check-docs-links on a stale pending-deploy entry

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: narrow the pending-deploy exemption to a 404

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 23:00:18 +02:00
Ruben FiszelandClaude Opus 5 a372ae0c04 fix(cli): lint against the checkout's schema, not the published validator (#10418)
* fix(cli): lint against the checkout's schema, not the published validator

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cli): mirror the permissioned_as exclusion into agent guidance

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: version windmill-yaml-validator with the release, publish by hand

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: generate schemas with the validator's own yaml parser

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cli): declare ajv, no longer reaching tests via the validator

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: fail schema generation on a spec YAML syntax error

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 23:33:35 +02:00
Ruben FiszelandClaude Opus 5 faf5aead6f ci: run the SDK suites on release (#10386)
* ci: run the python and typescript SDK suites

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* ci: run the SDK suites on release tags only

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore(ci): state the constraint without the incident

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(sdk): claim only what functools.wraps actually restores

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(ci): note the interpreter the suite runs on is not the worker's

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 16:51:47 +02:00
Ruben FiszelandClaude Opus 5 65db58bfda fix(frontend): pin sveltekit version.name so builds are reproducible across architectures (#10315)
* fix(docker): pin frontend build stage to linux/amd64

Rollup selects platform-specific native binaries that can emit different
content-hashed chunk filenames for identical sources. The frontend assets are
embedded into the Rust binary via rust_embed, so building the stage once per
target architecture produced amd64 and arm64 images whose HTML references
`_app/immutable/chunks/<hash>.js` files that only exist in that architecture's
image. In a mixed-architecture cluster, a page served by a pod of one arch 404s
on JS/CSS fetched from a pod of the other.

Pinning the stage makes both image variants embed byte-identical assets. The
stage output is JS/CSS/HTML/WASM only, so the build platform does not leak into
the artifacts.

Fixes WIN-2242

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: tighten frontend platform-pin comment

Vite 8 bundles with rolldown, not rollup; name the right bindings and keep the
constraint to four lines.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(frontend): make the build reproducible so mixed-arch clusters agree on asset names

SvelteKit defaults `kit.version.name` to `Date.now().toString()`, so every build
of the same commit gets a different version string. It is embedded in the client
chunk (and in the `__sveltekit_<hash>` global derived from it), which changes
that chunk's content hash and cascades into new filenames for roughly a quarter
of `_app/immutable`. The assets are baked into the binary via rust_embed, so the
amd64 and arm64 images of one release ship different `chunks/<hash>.js` names:
in a mixed-architecture cluster, HTML served by a pod of one architecture 404s
on assets requested from a pod of the other.

Measured on the published windmill:1.770.0 images: 224 of 863 asset filenames
differ between the two architecture variants, yet 854 of 855 chunks are
byte-identical once chunk-name references are normalized. The single genuinely
differing chunk is the one carrying the timestamp. The bundler is deterministic
across architectures; the timestamp is the whole divergence.

Pinning the version to the package version (overridable via WM_BUILD_VERSION)
makes repeat builds byte-identical. `version.pollInterval` is 0 and nothing
reads the `updated` store, so this has no runtime behavior change.

This supersedes pinning the Docker frontend stage to linux/amd64, which fixed
the symptom by building the stage under emulation on the arm64 builder — that
cost 32 minutes of QEMU time per build and left the underlying non-determinism
in place.

Fixes WIN-2242

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(frontend): key the sveltekit version on the commit sha

The package version only moves on releases, but `:dev` and RHEL images are
published on every main push. Two such deployments would then advertise the same
SvelteKit version, and SvelteKit only recovers from a chunk that 404s after a
redeploy (client.js: "Referenced node could have been removed due to redeploy")
when the deployed version differs from the baked-in one, so an open tab would
render an error page instead of reloading.

Pass the commit sha through WM_BUILD_VERSION from every workflow that builds the
root Dockerfile, so the value is identical across the per-architecture builds of
one commit and distinct between commits. The package version stays the fallback,
which keeps unwired builds architecture-consistent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(docker): declare WM_BUILD_VERSION in the RHEL frontend stages

The RHEL workflows copy docker/RHEL{8,9}/Dockerfile over the root one before
building, so the build-arg was unconsumed there and those images fell back to
the package version: two RHEL builds between releases would share a SvelteKit
version across different manifests.

Also switch the root declaration to the `ARG name=""` form used by `features`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: keep the version-arg rationale in one place

The root Dockerfile comment restated what frontend/svelte.config.js already
documents; point at it instead, matching the RHEL Dockerfiles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 23:55:47 +02:00
Ruben Fiszel 1973bc806b migrate to opus 5 2026-07-24 23:05:36 +02:00
Ruben FiszelandClaude Opus 4.8 3aaceb7efb fix(ci): make /review idempotent per head commit, re-run cancelled reviews in place (#10283)
* fix(ci): make /review idempotent per head commit, re-run cancelled reviews in place

`/review` fanned out to codex/pi/claude unconditionally. A push already
auto-triggers codex/pi (and claude on open) against the PR head, so the
comment-driven relaunch both cancelled those in-flight auto runs (shared
concurrency group) and landed its own status on main — issue_comment runs
never attach a check to the PR head — leaving the PR showing only a
cancelled review that never resolves.

Add a `plan` job that, for the `/review` fan-out, decides per agent:
skip when a running or successful review already covers the head commit;
re-run the head's cancelled/failed run in place (a re-run keeps the
original pull_request event so its checks re-attach to the PR head);
launch a fresh run when nothing usable covers the head commit (no runs,
or only a skipped draft/fork-gated run). Explicit /codex, /pi, /claude
remain deliberate re-reviews and always launch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ci): make explicit /codex idempotent per head, track fresh launches on head SHA

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 12:31:20 +02:00
Ruben FiszelandClaude Opus 4.8 8310e46b19 (windows) lean worker-only build, stop compiling the amqp trigger (#10251)
windmill-trigger-amqp does not compile on Windows: tokio-reactor-trait only
implements reactor_trait::Reactor for its Tokio type under #[cfg(unix)]. This
broke two Windows CI jobs since the amqp trigger landed (#10230): the ee_windows
worker build (via the amqp_trigger feature) and, because the crate is a default
workspace member, the backend-test-windows job (`cargo test --all` compiles
every member regardless of features).

The amqp trigger is a server-only feature never run on Windows workers, so the
fix is to stop compiling it on Windows rather than port its reactor.

Worker binary (ee_windows): replace the ce_core+ee_core bundle (every trigger +
all server-only features) with a worker-only worker_windows_core. A non-agent
worker still runs the full windmill-api on localhost for its own operations
(main.rs run_server, under `if !is_agent`) and jobs call back into it via the
wmill client, so keep every feature the worker's own runtime path or its jobs
touch, and drop the rest.

  Kept: languages, parquet, quickjs, enterprise/license, prometheus, otel,
  jemalloc, AI-agent execution (windmill-worker/mcp + windmill-store/mcp client
  and OAuth-MCP refresh, windmill-worker/bedrock for direct AWS Bedrock), OIDC
  Vault secrets (openidconnect), instance-SMTP email — critical alerts and the
  error-handler send endpoint (windmill-api/instance_smtp), OAuth refresh (oauth2
  — reload_base_url_setting populates OAUTH_CLIENTS, get_value_internal refreshes
  tokens in the worker's internal API server), inline/preview runs (run_inline —
  jobs call /jobs/run_inline/*).

  Dropped: all *_trigger/kafka/nats/sqs listeners plus static_frontend, stripe,
  embedding, zip, the MCP gateway (windmill-api/mcp), the server Bedrock proxy
  route (windmill-api/bedrock), and cloud (runtime-gated on CLOUD_HOSTED, never
  true self-hosted).

Split windmill-api's smtp feature: the send_email_with_instance_smtp endpoint
(error-handler failure emails) only needs windmill-common's rustls sender, but
the smtp feature also bundled the inbound email trigger's openssl + mail-parser +
windmill-trigger-email. Add instance_smtp = ["windmill-common/smtp"] gating just
the endpoint; smtp now includes it. The worker uses instance_smtp, avoiding
openssl (which broke the ee_windows check step) and the email-trigger crate.

backend-test-windows: the Windows binary is worker-only, so test the crates a
worker runs (windmill-worker/-common/-queue) via -p instead of `cargo test
--all`. --all compiled every workspace member regardless of features — pulling
in the amqp crate (which does not build on Windows) and linking the whole
windmill-api integration-test suite, whose combined size overran the runner disk
(LNK1180). Also unset the setup-rust-toolchain default RUSTFLAGS=-D warnings for
this job so cross-platform dead-code (cfg(unix)-only helpers unused on Windows)
does not fail the run; hygiene stays enforced on the Linux CI and the
build_windows_worker_ release build. Full-workspace coverage runs on the Linux CI.

Also drop the redundant `mkdir frontend/build` from the Windows worker workflows
and stub openapi-deref.json alongside the .yaml to avoid embedding ~2.5MB of
openapi spec the worker never serves.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 12:41:37 +02:00
2ce21c9ef8 feat(git-sync): enable per-item promotion mode on dev workspaces (#10205)
* feat(git-sync): enable per-item promotion mode on dev workspaces

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style: keep unrelated git-sync Alert copy at its original wrapping

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): fall back to parent_path on empty deploy path + bump ee ref

computeGitSyncDeployBranch used ?? so a backend-serialized empty path (rename out of the repo filter) skipped the deploy branch and could commit to the tracked base; use || to fall back to parent_path like the backend. Bumps ee-repo-ref for the single-object promotion_open_prs fix (windmill-ee-private#679).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): route dev-promotion non-branchable objects off the tracked base

user/group objects (and any unresolvable ref) returned null in promotion mode, so a dev-workspace deploy pushed them straight to the parent's tracked branch. Fall back to the dev's env-label branch instead; the backend opens no PR for them (isolated, not promoted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(git-sync): dev-workspace promotion via a toggle on the inherited repo

A dev workspace reuses the single repo it inherited from prod: a 'Promote to prod via Git' toggle flips it between sync mode (deploys to the dev branch) and promotion mode (per-item wm_deploy/** PRs to prod), with a per-item/per-folder sub-toggle. Removes the redundant separate-promotion-repo setup for dev workspaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(git-sync): dev-promotion regression test + widen git_sync_e2e path filter

Adds a CLI integration case covering dev-workspace promotion (script -> wm_deploy branch; user/group -> env-label branch, main never touched). Widens the git-sync-test.yml relevance filter to the deploy-branch derivation, git-sync guard, and CLI git-deploy files so the e2e suite runs on PRs like this one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): gate dev promotion toggle on EE, fix card mode + workflow path filters

Codex review: (1) show the dev promotion toggle only under an active EE license and revert the optimistic save if the backend rejects it; (2) derive the dev card's display mode from use_individual_branch so promotion copy shows in promotion mode; (3) mirror the new relevance paths into the workflow's top-level push/pull_request filters so it actually triggers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): only use the single-card dev promotion UX when the dev has one repo

Codex review: an attached dev workspace keeps its own repositories rather than inheriting prod's. Gating the single-card + toggle + hidden-secondaries UX on repositories.length <= 1 makes a multi-repo attached dev fall back to the normal layout, so no active repo is hidden and an unrelated repo isn't presented as prod's promotion target.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): runtime EE-plan gate for promotion mode, consistent with auto-pull/PR

Codex review: promotion mode only had the CE compile rejection, while auto-pull and PR creation runtime-gate on the active plan (check_git_sync_ee_license). Add check_promotion_license and call it from both edit_git_sync_config and edit_git_sync_repository, plus the matching CE rejection on edit_git_sync_config so the two endpoints are symmetric. Promotion is now gated like every other git-sync EE setting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): dev promotion must reuse the parent workspace's repository

Codex review: repository count doesn't prove a dev inherited prod's repo — an attached dev keeps its own. check_dev_promotion_targets_parent_repo resolves the promotion repo's URL and rejects enabling promotion unless it matches one the parent (prod) tracks, so branches/PRs can't target an unrelated repository. Called from both git-sync edit endpoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): dev promotion save-time check uses shared parent-repo matcher (url+branch)

Delegates to windmill_common::git_sync_ee::dev_promotion_target_matches_parent so the settings gate and the deploy-time safety net share one url+branch identity check. Bumps ee-repo-ref for the EE deploy-time enforcement.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: bump ee-repo-ref for private resolve_repo_url_and_branch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: bump ee-repo-ref for promotion-target matcher authz doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(git-sync): bump hub scripts to gitsync-cli versions, fix promotion tooltips

Point LATEST_GIT_SYNC_SCRIPT_PATH (28790 -> 28796) and
GIT_SYNC_PULL_SCRIPT_PATH / gitInitRepo (28789 -> 28795) at the hub
versions pinning windmill-cli@1.763.1-gitsync.0, which carries the
dev-workspace promotion routing. Slugs unchanged, so the GitHub-App
token check and hub script cache are unaffected.

Tooltips: enabling promotion pushes a PR-ready wm_deploy/** branch;
Windmill only opens the pull request itself when automatic pull
requests are enabled. Reword both toggles to stop promising a PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): dev promotion mirrors to the env-label branch, PR toggles exclusive by branch type

Bump ee-repo-ref for the dispatcher changes: a promotion dev's deploys
now also push to its env-label branch (one extra mirror job per batch,
users/groups mirror-only), and `fork_open_prs` no longer applies to a
dev in promotion mode where `promotion_open_prs` governs.

Frontend: the fork-PR toggle tooltip states its actual coverage
(wm-fork/** and the dev branch of a dev workspace) and that a promotion
dev's own pull request toggle takes over for wm_deploy/** branches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): reject dev promotion on pre-28796 pinned sync scripts

An older pinned sync script bundles a CLI that force-disables per-item
branches on every fork, so enabling promotion on a dev workspace with
such a pin would silently keep deploying to the env-label branch. Both
git-sync edit endpoints now reject the combination with an actionable
error; the EE dispatchers (via ee-repo-ref bump) demote inherited
configs to promotion-off semantics so markers, branch keys and the
mirror match the branch the CLI actually pushes. Roots and auto-managed
repositories are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): serialize dev promotion toggle saves

The promotion and per-folder toggles persist immediately via whole-repo
saves; leaving them interactive while one is pending lets rapid flips
race, and the earlier save (enabling runs extra backend checks) can
commit last, silently reversing the state the UI shows. Both toggles now
disable while a save is in flight.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(git-sync): lock auto-PR toggle during promotion save, rename-out branch routing

Frontend: the automatic-PR toggle is revealed by the promotion toggle's
in-flight save; an edit made mid-save was absorbed into the saved
baseline without reaching the backend. It now disables during that save.

EE (ee-repo-ref bump): dispatcher debounce/concurrency keys and PR
markers follow the CLI's parent_path fallback for rename-out items, so
their wm_deploy/** branches debounce per-branch and open their PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(git-sync): condense comments to durable constraints

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: update ee-repo-ref to 8bf73f803158bcbf7b8d55a36f4a1ebfcc1bbcd9

This commit updates the EE repository reference after PR #679 was merged in windmill-ee-private.

Previous ee-repo-ref: c2cd718cb53d234f909f485bd7cd43ed9605ffd1

New ee-repo-ref: 8bf73f803158bcbf7b8d55a36f4a1ebfcc1bbcd9

Automated by sync-ee-ref workflow.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-07-21 17:07:52 +00:00
hugocasaandClaude Fable 5 4e63ca2cd4 gate PR ready on clean agent-driven review rounds (#10157)
* feat(ci): gate PR ready on clean review rounds driven from draft

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ci): robust review-round wait loop, require codex evidence for marker skip

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ci): require pre-marker codex evidence, fail open on marker fetch errors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:23:24 +02:00