Commit Graph
1914 Commits
Author SHA1 Message Date
Ruben Fiszelandrubenfiszel 907141152e chore(main): release 1.771.1 (#10336)
* chore(main): release 1.771.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-27 03:14:35 +02:00
Ruben Fiszelandrubenfiszel 3a08656dad chore(main): release 1.771.0 (#10316)
* chore(main): release 1.771.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-26 11:56:50 +02:00
Ruben Fiszel a8455acd7d feat: make bigquery and snowflake script languages available in CE (#10324)
* feat: make bigquery and snowflake script languages available in CE

* docs: add snowflake to backend cargo feature map

* fix: stop logging the snowflake bearer token at debug level
2026-07-25 12:07:28 +02:00
Ruben Fiszelandrubenfiszel 113f41bab5 chore(main): release 1.770.0 (#10309)
* chore(main): release 1.770.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-24 19:14:23 +02:00
Ruben Fiszelandrubenfiszel a26ea4d43f chore(main): release 1.769.0 (#10302)
* chore(main): release 1.769.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-24 15:46:50 +02:00
Ruben Fiszelandrubenfiszel c24d6f9d11 chore(main): release 1.768.0 (#10281)
* chore(main): release 1.768.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-24 11:00:22 +02:00
Ruben FiszelandClaude Opus 4.8 0f1b8641f2 feat(windows): enable ruby and rlang on the windows worker (#10279)
Adds ruby and rlang to all_languages_windows so the Windows worker
carries the same language set as Linux (all_languages). The only
remaining difference is mssql-winauth vs mssql-kerberos, which is the
correct per-OS integrated-auth backend.

Both are parser-only Rust crates with no dependencies, so the
build/binary cost is negligible; the ruby and r executors already have
#[cfg(windows)] branches. When the Ruby/R runtime is absent on the host,
a job degrades to a runtime "command not found", same as any other
missing runtime.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 10:47:34 +02:00
Ruben Fiszelandrubenfiszel 6de4ec0f66 chore(main): release 1.767.0 (#10268)
* chore(main): release 1.767.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-23 01:16:55 +02:00
Ruben Fiszelandrubenfiszel abd659925d chore(main): release 1.766.2 (#10265)
* chore(main): release 1.766.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-22 22:47:34 +02:00
Ruben FiszelandClaude Opus 4.8 7e2f1afffb fix(python,windows): cross-platform cross-process wheel-install lock (#10264)
* fix(python,windows): cross-platform cross-process wheel-install lock

The advisory lock that serializes concurrent uv installs into a shared
Python wheel-cache dir was gated `#[cfg(unix)]` and used `nix::fcntl::flock`
directly, so on Windows there was no cross-process serialization at all.
Multiple agents running as services on one Windows host share a single
per-user cache dir (`.../Temp/windmill/cache/python_<v>/`); when several jobs
install the same package at once their uv processes clobber each other's
atomic renames, surfacing as "no .dist-info directory", "RECORD ... cannot
find the file specified", and "failed to rename ... os error 2" install
failures.

Replace the unix-only flock with `fs4`'s cross-platform advisory lock
(flock on unix, LockFileEx on windows). Unix behavior is unchanged (same
flock syscall, whole-file, released on handle close/process death); Windows
now gets a real per-package cross-process lock so co-located agents serialize
their installs instead of corrupting the shared cache.

Fixes WIN-2225

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

* chore(worker): drop now-unused nix `fs` feature

The `fs` feature was only pulled in for `nix::fcntl::flock`, which the
previous commit replaced with `fs4`. Remaining nix usages need only
`user` (plus the workspace-inherited `process`/`signal`).

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 22:42:35 +02:00
Ruben Fiszelandrubenfiszel b282cd9f5a chore(main): release 1.766.1 (#10263)
* chore(main): release 1.766.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-22 17:00:08 +02:00
Ruben Fiszelandrubenfiszel 26fcc93d4c chore(main): release 1.766.0 (#10247)
* chore(main): release 1.766.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-22 16:35:56 +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
Ruben Fiszelandrubenfiszel 50f1375f18 chore(main): release 1.765.0 (#10223)
* chore(main): release 1.765.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-21 20:15:14 +02:00
68debab877 feat(triggers): add AMQP (RabbitMQ) trigger via lapin (#10230)
* feat(triggers): add AMQP (RabbitMQ) trigger using the lapin library

Fixes WIN-2214

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

* chore(triggers): defer AMQP cross-workspace deploy pending utils-internal publish

Revert the amqp_trigger additions to the shared windmill-utils-internal
TriggerDeployKind and the frontend cross-workspace deploy adapter: the
frontend installs the published npm package, which lacks the new kind
until a release is cut. AMQP create/edit/delete/list/sync/capture are
unaffected (they use local types); only cross-workspace deploy/merge of
AMQP triggers waits on the package bump. Also document the at-most-once
ack in the consumer loop.

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

* fix(triggers): address AMQP review — at-least-once ack, workspace cascade, contracts

- ack AMQP deliveries only after successful dispatch; nack+requeue on failure
- add ON DELETE CASCADE workspace FK so amqp_trigger rows are cleaned on
  workspace deletion (and the listener stops)
- fix the /amqp_triggers/test OpenAPI body and add amqp_trigger to
  WorkspaceDiffRow.kind
- register AMQP in the generated workspace trigger tool (create_trigger)
- drop banned $bindable defaults on optional props in the config section
- add build_uri unit tests (encoding, ports, vhost)

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

* fix(triggers): stop AMQP poison-message loop and reconnect on transient drops

Chaos testing against a live RabbitMQ broker showed the previous
nack(requeue) + immediate re-poll spun a tight redelivery loop (~1000
critical-error reports/sec) on a poison message, and any connection blip
permanently disabled the trigger (lapin has no built-in reconnect).

- on dispatch failure: nack+requeue then stop consuming; the listener
  framework re-lists the trigger after its ping goes stale (~15s), backing
  redelivery off to that cadence instead of a tight loop (verified: rate
  dropped from ~1000/s to ~1 per ~26s, message preserved)
- on connection/stream error: stop and let the framework reconnect instead
  of disabling; persistent failures are still disabled via get_consumer
  (verified: a forced connection close now auto-reconnects and resumes)
- finish the AI create-trigger action wiring for AMQP: add amqp to
  CreatedResourceTriggerKind, the action-card registry, and the drawer
  registry so the result card renders and its "Open" action works

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

* fix(triggers): complete AMQP frontend registries and defer merge rows

- add amqp to capturableTriggerTypes (so AmqpCapture mounts), the Runs
  jobTriggerKinds filter, and CLOUD_DISABLED_TRIGGER_TYPES
- wire AMQP into global AI chat mode: TRIGGER_KINDS, the request union,
  writeTriggerSchema, triggerServices, and the draft adapter
- stop emitting actionable AMQP fork-comparison rows (revert amqp_trigger
  from TRIGGER_OR_SCHEDULE_TABLES) since cross-workspace deploy is deferred
  until windmill-utils-internal is published — avoids a deploy that fails
  with "Unknown kind: amqp_trigger"
- use design-system TextInput instead of raw <input> in the config section

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

* fix(triggers): complete AMQP session/draft registries and constrain prefetch

- add amqp to the session-deploy, draft-compare, preview-router, and
  copilot workspace-item registries so AMQP drafts/deploys/nav/path
  resolution work
- include amqp_count in the MoveDrawer attached-trigger rename warning
- replace the raw prefetch <input> with a design-system TextInput bounded
  to an integer 1-65535 (backend u16) and block save on invalid values

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

* fix(triggers): make AMQP disconnect/reconnect consistent with the Kafka trigger

lapin, like rdkafka, has no transparent reconnect, so the AMQP listener now
mirrors the Kafka trigger's explicit reconnect loop instead of relying on the
framework re-list (which disabled the trigger once get_consumer failed on a
sustained outage):

- get_consumer returns cheaply; consume owns a (re)connect loop that retries
  with a 30s backoff, reports a critical error every 10 failed attempts, and
  reports a recovered critical error once it reconnects — never disabling the
  trigger on a connectivity failure
- a consumer/stream error breaks out to reconnect rather than disabling
- dispatch failure still nacks+requeues (at-least-once) with a short backoff
  to avoid a tight poison-message loop, keeping the connection alive

Verified against a live RabbitMQ broker: killing the broker keeps the trigger
enabled and retrying (attempt N), and restarting it auto-reconnects (logs
"reconnected after N attempts") and resumes dispatch.

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

* fix(triggers): complete AMQP capture registries and constrain prefetch contract

- add the 'amqp' case to triggerKindToTriggerType so opening the AMQP editor
  from a capture button no longer throws "Unknown TriggerKind: amqp"
- register AmqpIcon in CaptureTable's icon map and add an AMQP entry to the
  script/flow CaptureButton menu
- bound the OpenAPI prefetch_count to an integer 1-65535 (matches the Rust
  u16) and regenerate clients/prompts
- require a non-empty exchange name when the exchange binding is enabled
- build_uri: fall back to "/" on a blank vhost and bracket IPv6 hosts (+ tests)

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

* feat(triggers): wire AMQP into pipeline graph, git-sync, and preprocessor types

- asset_graph: discover attached amqp_trigger rows and emit an AMQP TriggerEdge
  so AMQP triggers render (and can be opened/deleted) on the data-pipeline canvas
- frontend pipeline graph: add amqp to NativeTriggerKind, the add-trigger menu,
  node presentation, event-trigger set, annotation keywords, and the
  editor/service registrations
- git-sync: add the amqp_trigger include pattern (+ test) so an AMQP git-sync
  deployment stages only its .amqp_trigger.* file, not an unrelated same-path object
- preprocessor starters: add the AMQP event to the generated TS/Python/PHP
  trigger event types (kind/payload/exchange/routing_key/queue_name/redelivered/
  delivery_tag)

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

* fix(triggers): finish AMQP pipeline/parser wiring, prefetch validation, source lists

- fix a stray edit that corrupted the pre-existing MqttTriggerEditor import
  ($lib/... path) in PipelineTriggerEditors.svelte
- reject prefetch_count = 0 server-side in validate_config (RabbitMQ treats 0
  as unlimited) and defensively skip basic_qos(0) in build_consumer (covers
  the capture path that bypasses CRUD validation)
- recognize `// on amqp` in the canonical parser (TriggerSpec::Amqp) and add
  amqp to the CLI non-autorun/event-trigger sets so a pipeline cascade never
  runs an AMQP-only node as a manual root without an event
- add amqp to the preprocessor intro lists and both pipeline AI instructions

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

* fix(triggers): reject zero AMQP prefetch in all paths and finish guidance lists

- extract a shared validate_amqp_options used by both CRUD validate_config
  and build_consumer, so capture configs (which bypass CRUD validation) also
  reject prefetch 0 instead of silently connecting with an unlimited buffer
  (+ unit tests for 0/1/65535/None)
- add AMQP to the main script-writing preprocessor-sources prompt and the CLI
  triggers-skill guidance list

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

* docs(triggers): de-duplicate AMQP prefetch comment and fix GET response text

- keep the zero-prefetch rationale only on the shared validate_amqp_options
  doc; drop the redundant call-site comments
- correct the getAmqpTrigger OpenAPI 200 description ("deleted" -> "retrieved")

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

* chore: update ee-repo-ref to aaa6cb89b05b76139252c64f057e53b94d12ac60

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

Previous ee-repo-ref: 5da5fd65aca9594b2611837a52e4677b544b0380

New ee-repo-ref: aaa6cb89b05b76139252c64f057e53b94d12ac60

Automated by sync-ee-ref workflow.

* chore(migrations): consolidate the four AMQP migrations into one

The table and the three enum ADD VALUE statements (trigger_kind, job_trigger_kind,
draft_kind) are one atomic feature. ALTER TYPE ... ADD VALUE runs inside the
migration transaction on PG >= 14 (Windmill's minimum) since the amqp_trigger
table doesn't reference those enum types, so they can share a single migration
instead of four. Verified applying cleanly in a single transaction on a fresh DB.

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

---------

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 15:10:29 +00:00
Ruben Fiszelandrubenfiszel 858d9a5527 chore(main): release 1.764.0 (#10196)
* chore(main): release 1.764.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-20 22:56:04 +02:00
Ruben Fiszelandrubenfiszel 60a7a23a04 chore(main): release 1.763.0 (#10186)
* chore(main): release 1.763.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-19 10:45:40 +02:00
Ruben Fiszelandrubenfiszel d5b0a1b5c7 chore(main): release 1.762.2 (#10184)
* chore(main): release 1.762.2

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-18 08:49:56 +02:00
Ruben Fiszelandrubenfiszel 252ffd0401 chore(main): release 1.762.1 (#10181)
* chore(main): release 1.762.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-17 22:52:46 +02:00
Ruben Fiszelandrubenfiszel 3ffce7e2cc chore(main): release 1.762.0 (#10175)
* chore(main): release 1.762.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-17 20:15:13 +02:00
396fb1c475 feat(otel-tracing-proxy): trust internal endpoints with untrusted CAs (#10139)
* [ee] feat(otel-tracing-proxy): trust internal endpoints with untrusted CAs

Add `insecure_upstream_hosts` and `upstream_ca_certs` to the HTTP Request Tracing
settings so the OTEL tracing proxy can reach internal endpoints with untrusted or
private-CA certificates while keeping them traced. Wires the two settings through
the worker config and live reload, adds the inputs to the instance settings UI,
and pulls in the rustls upstream-client deps (hyper-rustls/tokio-rustls/rustls/
rustls-native-certs/rustls-pemfile; hyper-http-proxy switched to its rustls
feature).

The proxy-side implementation lives in the companion EE PR.

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

* chore: bump ee-repo-ref to otel_ca companion commit

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

* fix(otel-tracing-proxy): expose new fields in declarative config; bump ee-ref

Addresses code-review findings:
- Add `insecure_upstream_hosts` and `upstream_ca_certs` to the declarative
  `OtelTracingProxySettings` in instance_config.rs so operator/GitOps-managed
  installs can set them and reconciliation no longer drops values saved via the UI.
- Restore the trailing newline on ee-repo-ref.txt and bump it to the companion
  EE commit carrying the strict host-matching / port-ordering fixes.

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

* chore: update ee-repo-ref to 51e50629f48dbc4f5520a787b4bdfb76f4cd38d3

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

Previous ee-repo-ref: 49f458e4446395e98915c220baa757ab3b2ed2d8

New ee-repo-ref: 51e50629f48dbc4f5520a787b4bdfb76f4cd38d3

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-17 15:57:00 +02:00
Ruben Fiszelandrubenfiszel 6131f7d2ae chore(main): release 1.761.0 (#10148)
* chore(main): release 1.761.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-17 00:22:56 +02:00
51d8db6602 feat: automatic git-to-windmill sync (polling, webhooks, in-app PRs + checks) (#9552)
* docs: add design doc for automatic git-to-windmill pull sync

* docs: add migration plan and implementation phases to git-sync pull design

* feat(git-sync): add auto_pull settings schema and pull enqueue primitive

Adds AutoPullSettings/AutoPullMode/AutoPullStatus on GitRepositorySettings
(workspace_settings.git_sync JSONB), the GIT_SYNC_PULL_SCRIPT_PATH constant,
and should_pull/effective_poll_interval_s helpers with unit tests. Exports the
EE enqueue_git_pull_job primitive. Foundation for repo→Windmill auto-pull.

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

* feat(git-sync): poll repos and auto-pull new commits into the workspace

Phase 1 of automatic repo → Windmill sync. A monitor task (EE-licensed,
single-replica via advisory lock) git ls-remotes each auto-pull-enabled
repository ~every minute and enqueues a pull when the tracked branch moves,
reusing the {workspace_id}:git_sync concurrency key so pulls serialize with
in-flight push commits.

- windmill-store: background (no-authed) resolver get_git_repo_head_for_autopull
  that resolves the repo resource (incl. $var: refs) and ls-remotes; GitHub-App
  repos are skipped here and will sync via webhooks (phase 2).
- monitor.rs: poll/reconcile/persist with optimistic sha advance and failure
  status; targeted jsonb update so concurrent settings edits aren't clobbered.
- edit_git_sync_repository: preserve server-owned auto_pull state on UI save.
- openapi: AutoPullSettings/AutoPullMode/AutoPullStatus + auto_pull field.
- frontend: per-repo "Automatically deploy changes from Git" toggle with last
  sync status; demote the GitHub Actions link to an advanced CI option.

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

* feat(git-sync): wire webhook lifecycle + receiver; share reconcile logic

OSS side of phase 2 auto-pull webhooks:
- edit_git_sync_repository creates/removes the repo webhook on save (EE-gated,
  best-effort → falls back to polling).
- monitor poller now delegates to the shared windmill_git_sync reconcile/persist
  helpers (also used by the webhook receiver), removing duplicated logic.
- export the shared reconcile/persist/failure helpers; bump EE ref.

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

* chore(git-sync): bump EE ref for phase 3 in-app PR creation

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

* feat(git-sync): show webhook vs polling status on the auto-pull toggle

When a repo has an active webhook (auto_pull.webhook_id set), the status line
reads "instant via webhook"; otherwise it reads the ~1-minute polling cadence.

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

* feat(git-sync): post PR diff check on dry-run completion (phase 4)

Worker completion hook in process_completed_job: when a DeploymentCallback job
carrying the __git_sync_pr_check marker finishes, parse the dry-run SyncResponse
and patch the GitHub check run with the diff summary (success/neutral/failure).
Export enqueue_git_pull_dry_run; bump EE ref.

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

* chore(git-sync): bump EE ref (drop unused GHES webhook_secret)

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

* revert(git-sync): defer phase 4 PR diff checks (OSS side)

Remove the worker completion hook that posted the PR check run, drop the
enqueue_git_pull_dry_run re-export and the orphaned sqlx cache, bump EE ref.
Phases 1-3 (polling, webhooks, in-app PR creation) are unaffected.

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

* Revert "revert(git-sync): defer phase 4 PR diff checks (OSS side)"

This reverts commit 0137d3ca48.

* chore(git-sync): point EE ref at restored phase 4 commit

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

* chore(git-sync): bump EE ref for clone_ref dry-run

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

* chore(git-sync): bump init-repository hub script to v28784

Picks up the clone_ref param (windmill-integrations#158) so the phase 4 PR-check
dry-run can clone the PR head. Backward compatible; manual pull/push and the
automated pull/poller/webhook all move to the same published version.

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

* chore(git-sync): bump EE ref for auto-pull admin-permissioning fix

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

* chore(git-sync): bump EE ref for superadmin pull fallback

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

* fix(git-sync): refresh auto-pull tooltip; bump EE ref for webhook secret encryption

The auto-pull toggle tooltip claimed GitHub App repos would sync via
webhooks "in a future update"; webhook delivery now works, so describe
the webhook-vs-polling behavior accurately. Bump the EE ref to pick up
encrypting the webhook HMAC secret at rest.

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

* fix(git-sync): poll app-backed repos in auto/polling mode

The auto-pull poller skipped app-backed repos (the ls-remote head check
can't authenticate a tokenless URL), so auto- and polling-mode app repos
never synced when their webhook wasn't live. Wire the poller to fetch the
head via the GitHub API for app repos and reconcile. Bump the EE ref.

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

* feat(git-sync): auto-pull UI — direction split, delivery mode, fallback notice

Reorganize the repository card into two clearly labeled directions:
"Push to Git on deploy (Windmill → Git)" and "Pull from Git (Git →
Windmill)". In the pull section:
- new connections default to auto-pull enabled (webhook with polling
  fallback); existing repos load with auto-pull off and are unchanged
- a Delivery selector chooses "Webhook with polling fallback" or
  "Polling only (air-gapped)"
- a notice surfaces webhook_error when delivery falls back to polling
- a reminder to remove any pre-existing GitHub Action that pushed into
  Windmill, to avoid conflicting double-syncs

Adds the webhook_error field to AutoPullSettings (+ openapi) and bumps
the EE ref.

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

* feat(git-sync): clearer push indicator + gate webhook delivery to app repos

- Push-on-deploy is shown with a check icon + concise line (via the
  shared GitSyncModeDisplay, restyled from the oversized "Sync:" text);
  the setup wizard reuses it without the check (pre-save preview).
- The delivery-mode selector only shows for GitHub App-backed repos;
  token-based repos show a "webhooks require the GitHub App (managed or
  GHES)" note with a docs link and poll instead. Bumps the EE ref.

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

* feat(git-sync): fork auto-sync (phase 5) + live deploy check (phase 6)

Phase 5 — fork auto-sync configured at the parent (replaces the *-to-forks
GitHub Actions):
- Add fork_open_prs + fork_pull_sync to GitRepositorySettings (openapi + UI).
- UI: two "Forks of this workspace" toggles in the repo card, gated on
  app-backed and not-a-fork; serialize the flags on save.
- On fork creation, strip the inherited auto_pull block (and fork_* flags) from
  the copied git_sync repo: a fork must not carry the parent's webhook id (it
  would delete the parent's hook on disable) or self-poll on top of the parent's
  fan-out. Push-direction config + installation are still inherited unchanged.

Phase 6 — live deploy status check on the commit (Cloudflare-style): an
in-progress "Windmill" check on the head commit that flips to "Deployed N
changes"; completion handled by the generalized git-sync check hook.

Bump EE ref for the phase 5-6 EE implementation.

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

* chore(git-sync): bump EE ref for PAT auto-pull mode normalization

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

* fix(git-sync): address PR review findings

- webhook_secret: redact from the settings API response and Debug output (still
  persisted encrypted); it's a server-only HMAC key the UI never needs.
- poller: honor each repo's effective poll interval (relaxed ~10 min when a
  webhook is live) instead of probing every ~60s tick.
- settings save: roll back a just-created webhook if the settings transaction
  doesn't commit, so a failed save can't orphan a hook.
- auto-pull head check: fail SSH remotes with an actionable message (background
  polling has no SSH identity) instead of a confusing ls-remote error.
- deploy/PR check summary: a pull result carrying neither changes nor a settings
  diff now falls back to the unsummarized path instead of a false "in sync".
- UI: reset isGithubApp on resource change / failed fetch so webhook + fork
  controls can't show for the wrong repo.
- tests: cover parse_git_sync_changes and format_change_list edge cases.

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

* fix(git-sync): correct feature gating for OSS builds

- monitor.rs: keep the AUTO_PULL_LAST_POLL static, slack const, and
  poll_git_auto_pull_inner all behind #[cfg(feature = "private")] (an inserted
  static had split the cfg off the function, ungating it in OSS builds).
- edit_git_sync_repository: the webhook create/rollback block references
  windmill_common::git_sync_ee (private module), so gate it on
  all(enterprise, private) instead of enterprise only.

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

* chore(sqlx): cache workspace_diff query pulled in from origin/main

Re-merged origin/main (advanced past the earlier merge); regenerate the offline
sqlx entry for the new workspace_comparison test query so SQLX_OFFLINE builds
(cargo_test) pass.

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

* fix(git-sync): address Codex review findings (webhook cleanup on delete)

- Deleting a git-sync repository now tears down its managed GitHub webhook
  (deletion bypassed the sync_repo_webhook lifecycle, orphaning the hook so
  GitHub kept delivering to the instance).
- Worker completion hook rolls back the optimistic auto-pull sha on job failure
  (OSS side of the EE change) + caches the new marker query. Bump EE ref.

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

* fix(git-sync): delete repo webhook after the removal commits

Codex re-review nits:
- delete_git_sync_repository deleted the webhook before the settings transaction
  committed; a failed save would then leave the repo pointing at a hook that no
  longer exists (sync_repo_webhook treats a set webhook_id as live and won't
  recreate it). Capture the hook id, commit the DB removal, then delete the hook.
- Reword a fork-copy comment to drop drafting-history wording per AGENTS.md.

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

* fix(git-sync): reconcile the edit-path webhook after the settings commit

Codex nit: edit_git_sync_repository ran sync_repo_webhook before the transaction
committed. The rollback only covered created hooks, but sync_repo_webhook also
deletes a hook on disable/switch-to-polling — a commit failure then left the DB
with a webhook_id whose hook was already gone (and it wouldn't be recreated).
Save + commit first, then reconcile the webhook against the durable config and
persist any hook id/secret change (best-effort). Bump EE ref.

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

* fix(git-sync): preserve webhook secret on whole-config save + default on visible add

Codex nits:
- edit_git_sync_config saved the client config verbatim, so the webhook_secret
  redacted from the GET response would be dropped (breaking delivery). Preserve
  server-owned auto-pull state (webhook id/secret, synced sha, last status) per
  repo from the existing settings, matching edit_git_sync_repository.
- addSyncRepository (the visible add path) didn't set the auto_pull default, so
  new sync repos added from the UI came up with auto-deploy off. Match
  addRepository's default (webhook + polling fallback).

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

* refactor(git-sync): drop fork_pull_sync (parent-level keep-forks-in-sync)

Removes the "Keep forks in sync with the tracked branch" toggle and its
fan-out. Pulling the tracked branch straight into every fork was the
inconsistent piece; the consistent model is per-fork branch sync (each
fork tracks its own wm-fork/** branch), which is a separate follow-up.
fork_open_prs is kept. Also tightens the fork toggle-section spacing.

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

* fix(git-sync): detect dev workspaces in CLI fork branch derivation

isForkWorkspace / computeGitSyncDeployBranch keyed off the wm-fork- id
prefix. Dev workspaces are forks with a custom, prefix-less id, so their
wm-fork/** branch was never derived or created. Detect them via
parent_workspace_id too (which the backend already passes), mirroring the
backend's `parent.is_some() || wm-fork- prefix` rule.

Pairs with the hub-script clone-flag fix (windmill-integrations#163); both
take effect once the CLI is released and the pinned version is bumped.

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

* fix(git-sync): reconcile webhooks on full-config save

edit_git_sync_config preserved server-owned webhook fields but never
created or deleted the managed GitHub webhook, so enabling auto-pull
through the whole-config endpoint only polled, and disabling or removing
a repo left an orphan hook still delivering. Mirror the per-repository
endpoint: after the commit is durable, reconcile every saved repo's
webhook (sync_repo_webhook) and delete the hooks of repos the save
removed, including the clear-whole-config case. Addresses the Codex nit.

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

* fix(git-sync): address Codex nits (webhook orphan on cleared auto_pull, fork detection)

- edit_git_sync_config: also delete a repo's old webhook when the save drops
  the repo OR clears its auto_pull. Webhook fields are only preserved onto a
  Some auto_pull, so a save that present-but-clears a repo would otherwise
  orphan its hook.
- GitSyncRepositoryCard: isFork now uses parent_workspace_id OR the wm-fork-
  prefix (was AND), matching the backend/CLI rule, so prefix-less dev
  workspaces are detected as forks and don't show the parent fork-PR toggle.

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

* docs(git-sync): update design doc for the dropped fork_pull_sync

Phase 5 documented "Keep forks in sync with the tracked branch"
(fork_pull_sync) and its fan-out as implemented; that feature was removed.
Rewrite the section to reflect what ships (fork_open_prs), note the drop +
the per-fork-branch follow-up, and remove the stale fan-out mentions
elsewhere. Addresses the Codex nit.

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

* fix(git-sync): redact webhook secrets from workspace export; fix doc endpoints

- Export (P1): strip the server-owned auto_pull state (webhook secret/id/error
  + synced sha + last pull status) from git_sync before it is written into an
  export's settings.json for both settings formats. The HMAC webhook secret
  must never leave the server (matching the GET-settings redaction), and a
  re-imported workspace must not inherit another install's hook/sync state.
- Docs: the webhook receiver is a single per-workspace endpoint
  /api/w/{workspace}/github_app/webhook (host-aware for managed + self-managed);
  update the stale push_webhook/{id} and instance-global /api/github_app/webhook
  references.

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

* fix(git-sync): skip deleted/archived workspaces in the auto-pull poller

The poller scanned workspace_settings directly, so an archived (soft-deleted)
or renamed-away workspace — whose settings row persists — kept polling and
could enqueue a pull into a dead workspace. Join workspace and require
NOT deleted. The EE webhook receiver gets the same filter (ee ref bumped).

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

* fix(git-sync): never trust client-supplied server-owned auto-pull fields

Both write endpoints (edit_git_sync_repository, edit_git_sync_config)
persisted caller-supplied auto_pull.webhook_id / webhook_secret /
webhook_error / last_synced_sha / last_pull_status when adding a repo or
newly enabling auto-pull, letting a client inject a webhook id/secret or
fake sync state. Strip those server-owned fields from the request up front;
existing repos re-derive them from the DB (carried over), new ones start
clean and the server (re)creates the webhook.

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

* fix(git-sync): merge webhook fields post-commit instead of clobbering the row

The post-commit webhook reconcile in edit_git_sync_repository and
edit_git_sync_config wrote the whole pre-reconcile git_sync snapshot back
after the main save committed. A concurrent git-sync edit or poller status
write that landed in the gap could then be dropped by the stale snapshot.
Re-read the current row and merge only the reconciled webhook id/secret/error
for the repos the reconcile actually changed.

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

* feat(git-sync): parent-managed fork sync + PR-on-deploy toggles

Fork sync (push-on-merge-to-forks parity): a parent-level
auto_pull.sync_forks toggle routes changes on each fork's wm-fork/** branch
into that fork workspace, via the parent's existing webhook and one extra
fork-heads listing per poll tick (git ls-remote pattern for token repos,
git/matching-refs for app-backed). Fork state is a server-written
status-only auto_pull blob on the fork's own repo entry; the fork's card
shows a read-only "managed in the parent workspace" line with its branch
and last pull status. Dev workspaces (prefix-less ids) use the same branch
parsing (unit-tested in windmill-common).

PR-on-deploy: opening PRs for Windmill-pushed branches moves into the
deploy pipeline, per repo toggle (promotion_open_prs on the promotion
repo; parent-level fork_open_prs for fork deploys). The push job carries a
marker and the job-completion hook derives the pushed branch (helper
unit-tested against the CLI formula) and opens the PR outbound, so it
works without inbound webhooks; the webhook-side wm_deploy PR arm is
removed. The documented open-pr-* GitHub Actions remain valid alternatives
(PR creation is idempotent).

Fork guards: promotion mode, enabled auto-pull, and fork_open_prs are
rejected on fork workspaces (they are parent-managed; a fork's deploys
always target its wm-fork/** branch) and the promotion card is hidden in a
fork's settings. Enabling auto-pull now also requires EE, and the
post-commit webhook reconcile persists the normalized delivery mode.

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

* feat(git-sync): dev workspaces sync with their environment-label branch

A dev workspace's git branch is its environment label verbatim (dev/
staging, default dev) — a first-class env branch like the documented
push-on-merge-staging layout — instead of the wm-fork/** form. The label
rides the deploy job args (backend → hub script → CLI
--dev-workspace-label), the PR completion hook derives the same head, the
webhook/poller route label branches into the matching dev-workspace child
(poller lists them alongside wm-fork/* via extra ls-remote refs / per-label
API lookups), and manual pulls from the UI pass clone_ref accordingly. The
CLI refuses to deploy when the label branch equals the checked-out tracked
branch, which would otherwise commit fork content straight to it.

Because the branch is keyed on the label, the label is now immutable after
creation: set at create/attach only, the set_dev_workspace_label endpoint
is removed and the settings tab shows it read-only.

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

* feat(git-sync): nested fork routing + fork-of-dev branch rooting

A fork of a dev workspace now roots its wm-fork/** branch on the dev's
environment-label branch (the content it diverged from) and its PR merges
back into that branch: the backend passes parent_dev_workspace_label with
the deploy (parent row joined in both enqueue paths), the CLI gains
--parent-dev-workspace-label and checks it before the wm-fork- prefix
fallback when rooting a fork-of-a-fork branch, and the PR completion hook
uses it as the PR base.

Fork sync routing covers the whole live descendant chain of the
webhook/poller workspace (recursive, depth-capped) instead of direct
children only, and fork_open_prs is resolved at the root ancestor — only
the root can hold auto-pull config, so grandchild forks sync through it.

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

* feat(git-sync): PR deploy-preview comment, clearer check copy, app-only hints

- The PR diff completion hook maintains one managed comment on the PR
  (Cloudflare deploy-preview style: workspace, status, commit, collapsible
  change list), upserted per synchronize via a hidden marker. The check run
  stays for required-check gating.
- A settings difference in the diff summary is worded by cause: the PR
  changes wmill.yaml, vs pre-existing drift between the repo's wmill.yaml
  and the workspace, vs undetermined (neutral wording).
- Deploy-status check titles name the target workspace ("Deployed 2
  change(s) to staging"), since GitHub shows a head commit's checks on any
  PR containing it and a bare "Deployed" read as if the PR had deployed.
- Token-based repos see a hint pointing at the open-pr-on-commit /
  open-pr-on-fork-commit workflows where the app-only PR toggles would be;
  an API-set toggle on a non-app repo now logs a warning naming the
  fallback; the design doc lists app-only features and their degradation.

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

* fix(git-sync): EE-gate auto-pull UI, fork pull clone_ref, no-op push PR gate

- CE: the auto-pull and fork-PR toggles are disabled with an EE badge, and
  new sync repos only default them on when licensed (basic git sync is
  available on CE since #8493, but auto-pull is EE and the backend rejects it)
- The pull modal passes clone_ref for wm-fork- forks (wm-fork/<tracked>/<id>)
  so a manual pull fetches the fork branch instead of the tracked branch head
- PR-on-deploy skips no-op pushes: when the push script reports pushed=false
  (e.g. the deploy was caused by an auto-pull), the completion hook no longer
  ensures a PR, so closed PRs aren't recreated by the sync loop

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

* chore: refresh package-lock after main merge (windmill-utils-internal 1.8.2)

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

* test: auto-pull e2e integration tests; fix PR comment table formatting

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

* fix(git-sync): runtime license gate for auto-pull saves; user/group promotion-branch parity

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

* fix(git-sync): explain in-sync PR verdicts with the repo's sync filter scope

A PR that only touches files outside the repository's include paths gets
"In sync", which reads as a wrong verdict; the check summary (and managed
comment) now name the filters, e.g. "Only files matching this repository's
sync filters deploy on merge: `f/**` (excluding `f/pat/**`)."

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

* feat(git-sync): clearer card copy/structure; surface PR-creation failures

- Fork sync toggle renamed and kept in the pull section; the fork PR toggle
  moves to the push section with a note that push settings apply to forks
- Fork/dev workspaces' push section names their actual branch instead of the
  tracked-branch line; promotion repos hide the pull direction (promotion
  pushes deploy branches on top of a sync-mode setup)
- Promotion mode line describes the wm_deploy/** branch + merge-to-promote
  flow; workflow-fallback hints lead with the how-to and link to the docs;
  test connection button demoted from accent per brand guidelines
- New server-owned open_pr_error on repo settings: the deploy completion hook
  records why a PR couldn't be opened (e.g. app permission not yet approved)
  and clears it on the next success; shown as a warning under the PR toggles

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

* fix: cfg-gate scope-note helper (dead code on OSS builds)

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

* fix(git-sync): license-gate preserved auto-pull; attach strips parent-only settings

- edit_git_sync_repository re-checks the runtime Enterprise gate against the
  EFFECTIVE repo state after preservation: the older-client arm copies the
  existing auto_pull back, which the request-side check never saw
- attach_dev_workspace now mirrors the fork-creation copy on the attached
  workspace's own git sync: promotion repos dropped, auto_pull/fork PRs/PR
  error stripped, and any managed webhook deleted after commit (the attached
  workspace is parent-managed and must not keep pulling its old tracked branch)
- integration test: attaching an auto-pull-enabled workspace strips it

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

* fix(git-sync): detach clears standalone parent; reject label == tracked branch

- detach_dev_workspace clears parent_workspace_id for prefix-less (attached
  standalone) workspaces so they stop classifying as forks and deploying to
  wm-fork/** branches; wm-fork- re-designated forks keep their parent; cache
  invalidations mirror attach
- dev-workspace create/attach reject an environment label that equals a
  git-sync repository's tracked branch (prod's or the candidate's): deploys
  would target the very branch the repo syncs from, and the CLI guard would
  fail every push job after the fact
- CLI unit tests: prefix-less fork beats wm_deploy derivation; isForkWorkspace
  parent-id argument

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

* chore(git-sync): bump hub script pins (push 28786, pull 28785)

Published from windmill-integrations #163 with windmill-cli@1.753.1-gitsync.0:
dev-workspace label deploys, fork-of-dev rooting, fork checkout on the
existing remote branch, and the pushed-flag result.

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

* fix(git-sync): no parent-only defaults on fork repos; rename strips webhook state

- addSyncRepository skips the auto_pull/fork_open_prs defaults on fork/dev
  workspaces where the backend rejects them (saving a new sync repo from an
  EE fork 400'd deterministically)
- change_workspace_id strips webhook id/secret/error from the copied git_sync
  and deletes the stale GitHub hooks post-commit: they deliver to the old
  (archived) workspace URL, so the new workspace would report a live webhook
  while polling at the relaxed interval; next save re-registers cleanly
- EE: PR diff checks for contributor-fork PRs clone the synthetic
  pull/<n>/head ref (head.ref doesn't exist in the base repo)

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

* chore(git-sync): bump pull script pin to hub/28787 (synthetic PR ref support)

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

* fix(git-sync): targeted jsonb update for open_pr_error (no full-blob clobber)

The full read-modify-write raced the poller's concurrent last_synced_sha /
last_pull_status writes on the same column; mirror the EE status writer and
update only the matching repository element's open_pr_error key.

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

* style(git-sync): inline EE badge on gated toggles (matches settings nav)

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

* copy(git-sync): both directions in page/card descriptions; clearer promotion flow

- Page header and sync-card description mention the pull direction, not only
  push-on-deploy
- Promotion description walks the actual flow (wm_deploy/** branch, merge to
  promote, sync the target workspace) and points at the PR toggle / workflow;
  the Git Promotion docs link now also shows on configured cards, not only in
  the empty state

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

* fix(git-sync): resolve branch-less resources' default branch for fork sync

A git resource without an explicit branch polled as the bare "HEAD" ref,
which the fork/dev-label fan-out cannot scope (wm-fork/<branch>/*), so fork
sync silently never ran on polling-only repos. Resolve the remote's default
branch name with `ls-remote --symref HEAD` (one call for name + head sha);
"HEAD" only remains when resolution fails. The polling e2e test now uses a
branch-less resource to cover this shape.

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

* fix(git-sync): runtime license gate for in-app PR creation

promotion_open_prs/fork_open_prs are rejected on save without an Enterprise
plan (like auto_pull), and the deploy completion hook re-checks the plan
before opening PRs so flags stored while licensed stop driving GitHub calls
after a lapse.

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

* feat(git-sync): app-aware pull defaults, always webhook delivery, token-repo guidance

- Pull-from-Git defaults on only for app-backed repos (applied when the
  selected resource resolves); polling is opt-in for token repositories,
  with a warning alert recommending the GitHub App (instant pull + in-app
  PRs) or the sync GitHub workflow
- App repos always use webhook delivery with polling fallback: the delivery
  selector is gone and a stored polling mode is normalized back to auto
- Post-save modal reflects the auto-pull state instead of telling the user
  to turn on a toggle that is already on
- Non-app PR hints recommend the GitHub App explicitly

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

* copy(git-sync): single info box for token-repo pull guidance

Merges the instant-pull recommendation with the GitHub Action conflict note,
shown only for non-app repos; app repos need neither, and the redundant
'instant webhook sync requires' line is gone.

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

* copy(git-sync): keep the GitHub Action conflict note on app repos

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

* copy(git-sync): anchor docs links to their exact sections

GitHub App references point at integrations/git_repository#github-app, the
workflow hints at deploy_gh_gl#github-actions-setup, and the sync workflow
at git_sync#github-actions (all anchors verified against the live docs).

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

* copy(git-sync): fork workflow hint links to git_sync#github-actions

open-pr-on-fork-commit is documented on the git_sync page, not deploy_gh_gl.

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

* fix(git-sync): fork PRs are opt-in on new connections too

Only auto-pull and fork sync default on for new app-backed connections;
opening pull requests stays a deliberate per-repo decision.

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

* feat(git-sync): default the managed PR on for new app-backed promotion repos

A promotion deploy's wm_deploy/** branch exists to be merged; without a PR
it's an orphaned branch. Fork PRs stay opt-in. Also scope the sync-repo
auto-pull default to sync mode so promotion repos can't pick it up.

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

* docs(git-sync): GHES self-managed app permission setup

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

* docs(git-sync): frame permission update against GitHub Actions, not polling

Existing installations don't have polling; their git-to-Windmill direction
runs on GitHub Actions today, so the approval text describes the update as
replacing those workflows and notes every feature is opt-in.

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

* copy(workspaces): drop 'cosmetic' qualifier from dev-workspace label UI

* chore: update ee-repo-ref to 9b2a6375f838436cf68cff449cc9bc621cca5281

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

Previous ee-repo-ref: 99eef24e2f0402b9a997cde5f67be52ee5d54b0e

New ee-repo-ref: 9b2a6375f838436cf68cff449cc9bc621cca5281

Automated by sync-ee-ref workflow.

* fix(git-sync): reject '/' in fork and dev workspace ids

* fix(git-sync): bound auto-pull git probes with a per-command timeout

* fix(git-sync): persist webhook reconcile via targeted jsonb updates

---------

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-16 15:55:44 +02:00
Ruben Fiszelandrubenfiszel a935d06c8e chore(main): release 1.760.1 (#10142)
* chore(main): release 1.760.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-15 21:29:39 +02:00
Ruben FiszelandClaude Opus 4.8 8c725d9e44 fix(apps): honor presigned S3 signature on app display/preview routes (#10141)
The app provenance gate short-circuits on a valid presigned signature, but only the raw download_s3_file route parsed it. The parquet/csv/table-count/file-preview/metadata routes discarded sig/exp and always fell through to the provenance gate, so a presigned S3 object rendered as a table showed "File restricted" for any viewer who did not produce it. Thread sig/exp through every apps_u S3 display route and forward the presigned bearer from ParqetCsvTableRenderer/DisplayResult.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:18:15 +02:00
Ruben Fiszelandrubenfiszel 2092155191 chore(main): release 1.760.0 (#10128)
* chore(main): release 1.760.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-15 18:00:53 +02:00
Ruben Fiszelandrubenfiszel 360e783b1d chore(main): release 1.759.0 (#10108)
* chore(main): release 1.759.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-15 10:02:01 +02:00
Ruben FiszelandClaude Opus 4.8 ba232544e7 feat(nativets): add Web Crypto support via deno_crypto (#10109)
The nativets in-process runtime (deno_core) exposed no Web Crypto API:
`crypto` was undefined, so scripts could not use `crypto.getRandomValues`,
`crypto.randomUUID`, or `crypto.subtle`, even though the bun runner provides
them. This closes that parity gap by registering the `deno_crypto` extension
and wiring the crypto globals onto `globalThis`.

- Pin `deno_crypto = "0.223.0"`, the sibling release of the already-pinned
  deno_core 0.352 / deno_web 0.240 stack (deps: deno_core ^0.352,
  deno_web ^0.240, deno_error =0.6.1), so the rest of the deno stack is
  untouched.
- Register `deno_crypto::init(None)` after `deno_web` in both the snapshot
  (build.rs) and the runtime (lib.rs) extension lists, keeping the snapshot a
  prefix of the runtime list. deno_crypto declares deps = [deno_webidl,
  deno_web], which the position satisfies.
- Import `ext:deno_crypto/00_crypto.js` in runtime.js and assign
  `crypto` / `Crypto` / `CryptoKey` / `SubtleCrypto` to `globalThis`.
- Add the `smoke_web_crypto` opt-in smoke test asserting the UUIDv4 shape of
  `randomUUID`, a non-zero `getRandomValues` fill, and the known
  SHA-256("abc") vector via `subtle.digest`.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 01:58:56 +02:00
Ruben Fiszelandrubenfiszel 65d6f477ab chore(main): release 1.758.0 (#10084)
* chore(main): release 1.758.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-14 22:38:45 +02:00
Ruben Fiszelandrubenfiszel 1ffe5a1075 chore(main): release 1.757.0 (#10080)
* chore(main): release 1.757.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-14 12:47:53 +02:00
Ruben Fiszelandrubenfiszel 4f65187f9e chore(main): release 1.756.1 (#10072)
* chore(main): release 1.756.1

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-14 10:46:55 +02:00
Ruben Fiszelandrubenfiszel 22b47c8823 chore(main): release 1.756.0 (#10062)
* chore(main): release 1.756.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-12 10:30:58 +02:00
Ruben Fiszelandrubenfiszel 1ed7fc066b chore(main): release 1.755.0 (#10041)
* chore(main): release 1.755.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-12 00:01:39 +02:00
Ruben Fiszelandrubenfiszel 38a190b53a chore(main): release 1.754.0 (#10017)
* chore(main): release 1.754.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-10 13:59:22 +00:00
Ruben Fiszelandrubenfiszel 9ad6927231 chore(main): release 1.753.0 (#9997)
* chore(main): release 1.753.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-08 16:46:15 +00:00
Ruben Fiszelandrubenfiszel 223e1569ce chore(main): release 1.752.0 (#9974)
* chore(main): release 1.752.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-07 22:10:10 +02:00
Ruben Fiszelandrubenfiszel 8dd5e48a68 chore(main): release 1.751.0 (#9965)
* chore(main): release 1.751.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-06 19:00:48 +00:00
Ruben Fiszelandrubenfiszel 5fe7e1f3e8 chore(main): release 1.750.0 (#9952)
* chore(main): release 1.750.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-06 11:39:57 +02:00
Ruben Fiszelandrubenfiszel 891b32195a chore(main): release 1.749.0 (#9938)
* chore(main): release 1.749.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-06 01:40:42 +02:00
Ruben Fiszelandrubenfiszel 799b9e3b7c chore(main): release 1.748.0 (#9914)
* chore(main): release 1.748.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-05 18:23:51 +02:00
Ruben Fiszelandrubenfiszel df6e511763 chore(main): release 1.747.0 (#9901)
* chore(main): release 1.747.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-03 19:40:01 +02:00
Ruben Fiszelandrubenfiszel fad5419b9d chore(main): release 1.746.0 (#9872)
* chore(main): release 1.746.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-03 01:03:44 +02:00
Ruben Fiszel e77b7523a5 nit enterprise implies license feature 2026-07-02 06:01:22 +00:00
Ruben Fiszelandrubenfiszel 9a24cd2bef chore(main): release 1.745.0 (#9858)
* chore(main): release 1.745.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-02 00:15:58 +02:00
Ruben Fiszelandrubenfiszel cfcc0b9453 chore(main): release 1.744.0 (#9839)
* chore(main): release 1.744.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-07-01 11:47:34 +02:00
Ruben Fiszelandrubenfiszel a9ffdb996b chore(main): release 1.743.0 (#9837)
* chore(main): release 1.743.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-06-29 20:41:38 +00:00
Ruben Fiszelandrubenfiszel 96c0ff65bd chore(main): release 1.742.0 (#9830)
* chore(main): release 1.742.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-06-28 14:33:27 +02:00
Ruben Fiszelandrubenfiszel 9172a0945b chore(main): release 1.741.0 (#9804)
* chore(main): release 1.741.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-06-26 21:43:02 +02:00
Ruben Fiszelandrubenfiszel b7a227f860 chore(main): release 1.740.0 (#9776)
* chore(main): release 1.740.0

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <275584+rubenfiszel@users.noreply.github.com>
2026-06-25 21:37:57 +00:00
Ruben FiszelandClaude Opus 4.8 0dbd9c1231 perf: eliminate dual-connection DB pool contention across worker, queue, and api (#9798)
* perf: eliminate dual-connection DB pool contention across worker, queue, and api

Reuse the held transaction (or move pool reads before begin()) instead of
checking out a second pool connection while a tx is open, extending the
fix from #9789/#7861. Targets the per-worker pool (max 5) hot paths plus
several server-pool API handlers.

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

* fix: pass owned pool to get_email_from_permissioned_as in http trigger handler

The generified signature takes impl PgExecutor; the http trigger handler
passed &db where db is already &DB, yielding &&Pool which does not impl
PgExecutor (only surfaced under the full feature set in CI).

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

* fix: keep RLS-exposed reads on the non-RLS pool and isolate flow-eval reads in a savepoint

Addresses review of the dual-connection sweep:

- worker_flow: wrap the stop_after_all_iters_if reads in a SAVEPOINT. The
  caller swallows the error and keeps using tx, so a DB read failure must
  not leave the outer transaction aborted (it would fail the later commit).
  Matches the previous pool-read semantics.

- Revert reads that were moved onto an RLS (user_db) transaction back to the
  non-RLS pool, since RLS row-visibility/role context can change results:
  push_scheduled_job (email/tag/settings lookups; reachable with a user_db
  tx from api-schedule/api-flows), push_inner native-retry dedicated_worker
  routing (RLS isolation variants), resources.rs app-namespace folder
  auto-create (non-admins must not be blocked), and the script archive/delete
  UPDATEs. Non-RLS db.begin() reuse and move-before-begin are kept.

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

* test: failpoint proving the stop_after_all_iters_if savepoint isolates an aborted read

Adds a worker-crate failpoints feature and a data-driven hook: when the
stop_after_all_iters_if expr is the magic sentinel, the in-evaluation read runs
SELECT 1/0 to abort its (savepoint) transaction. The test asserts the flow still
completes (iteration marked failed) — which only holds if the savepoint keeps the
outer status-update transaction committable. Without the savepoint the abort would
poison the outer tx and the job would never complete.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:33:17 +00:00