Commit Graph

619 Commits

Author SHA1 Message Date
Ruben Fiszel 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 Fiszel 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
AlexRV12 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
Ruben Fiszel 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 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 Fiszel 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 Fiszel 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 Fiszel 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 Fiszel 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 Fiszel 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 Fiszel 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
hugocasa 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
hugocasa 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
Ruben Fiszel 2f6c35b15b fix(self-host): unbreak self-hosted Caddy after the caddy-l4 syntax change (#10156)
* fix(self-host): accept pre-2.11 Caddyfiles in the caddy-l4 image

The Caddyfile is a bind-mounted file the user owns, so `docker compose pull`
updates the image but never their config. #10106 and #10113 changed the syntax
the image requires (native caddy-l4 `route { proxy { upstream } }`, and a
non-empty `bind`), which strands every existing self-host on their next pull:

  Error: adapting config using caddyfile: parsing caddyfile tokens for 'layer4':
  wrong argument count or unexpected line ending after 'proxy', at line 4

Normalize legacy Caddyfiles in the entrypoint instead. Only rewrite when the
config cannot be used as-is, and on any failure exec caddy against the user's
original file so it reports a real error against what they wrote.

The bind rewrite is not cosmetic: an empty `bind {$ADDRESS}` adapts and
validates cleanly on caddy >= 2.9 but drops the whole HTTP site, so a
syntax-only shim would trade a restart loop for a container that boots clean
and serves nothing on :80.

The reference for correctness is the image published before #10106
(sha-989c9e6): whatever it adapts today is what self-hosters run, so the shim
must reproduce it byte for byte. docker/test-caddy-compat.sh asserts that over
five legacy variants, plus the :80 listener under an unset ADDRESS, every
--config spelling, relative and glob imports, and the no-op on the current
Caddyfile.

Details worth knowing:
- `to a b` becomes one `upstream` per address; `upstream a b` would be a single
  upstream with two dials, which is a different load-balancing topology.
- The rewrite lands next to the original, because caddy resolves `import`
  relative to the importing file and a glob import would otherwise silently
  expand to nothing.
- The image has no ENTRYPOINT and CMD ["caddy", ...], so an existing
  `command:` override starts with a `caddy` token the entrypoint absorbs.

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

* fix(self-host): route ws_mp and ws_debug to the extra gateway

reverse_proxy only reads its first argument as a matcher, so

  reverse_proxy /ws/* /ws_mp/* /ws_debug/* http://windmill_extra:3000

adapts to a single /ws/* route whose upstreams are `ws_mp/*:80`,
`ws_debug/*:80` and `windmill_extra:3000`. LSP therefore round-robins across
two garbage hostnames and connects only one time in three, while /ws_mp/* and
/ws_debug/* match no route at all and fall through to windmill_server:8000.

Use a named matcher so all three paths reach the gateway. Verified with traffic
against separate windmill_server and windmill_extra backends: before, /ws/lsp
fails and /ws_mp/room reaches windmill_server; after, all three reach the
gateway with the path preserved and /user/login still reaches windmill_server.

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

* chore(self-host): pin the caddy-l4 image to an explicit version

:latest and the bind-mounted ./Caddyfile it has to agree with are updated by
different mechanisms, so they drift. Publish an explicit version alongside
:latest and pin docker-compose.yml to it, so a checkout is self-consistent:
compose, Caddyfile and image version now move together in one commit.

CI fails the build when docker/caddy-l4.version and the docker-compose.yml pin
disagree, and runs the compatibility-shim tests before publishing. The path
filter now covers the entrypoint, the normalizer, the Caddyfile and
docker-compose.yml, so a change to any guarded input actually triggers the
workflow rather than leaving the check unrun.

:latest keeps being published, since existing deployments reference it and that
is how they pick up the compatibility shim.

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

* fix(self-host): make the caddy-l4 version tag publishable before the pin merges

docker-compose.yml pins an exact tag, but the version tag was gated on the
default branch, so the tag only appeared after the pin had already merged.
Between the merge and the build finishing, a fresh `docker compose up -d` off
main fails with "manifest unknown", and a failed build leaves main permanently
referencing an image that does not exist.

Drop the gate so the tag can be published from the branch via
workflow_dispatch before merging the pin. The version is immutable, so
republishing it from main is a no-op, and only pushes to main and manual
dispatch run this workflow, so a branch cannot claim the tag by accident.
:latest stays gated on main.

Also check the version file against the caddy version the Dockerfile pins.
Without it, a caddy bump that forgets the version file publishes a tag naming
the wrong caddy.

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

* fix(self-host): do not log Caddyfile contents from the compat shim

The shim logged a unified diff of the rewrite, which carries three lines of
context around each change. A Caddyfile is user-owned and can hold basic_auth
hashes, proxy Authorization headers or TLS provider tokens, and container logs
are routinely shipped off the host, so normalizing a customized config could
copy secrets into them. Reproduced with a basic_auth bcrypt hash landing in the
log as context around the bind rewrite.

Log the number of rewritten lines and the path to the rewritten file instead.
It sits next to the original, so an operator can diff it themselves.

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-16 16:39:33 +02:00
hugocasa 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 Fiszel cab3430e64 ci: link backend integration tests with mold to fix OOM (exit 143) (#10103)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 10:00:50 +02:00
Kobi Hikri 91b5a10504 ci: pin cpina/github-action-push-to-another-repository to a full commit SHA (#10119)
go_on_release.yml referenced this third-party action by the mutable @devel
branch in the step that holds secrets.DENO_PAT (a write-scoped PAT used to push
the generated go-client to another repo). Pinning to a full commit SHA (v1.7.3)
removes the mutable-ref supply-chain exposure, consistent with the other
SHA-pinned actions in the repo.
2026-07-15 09:52:50 +02:00
Ruben Fiszel eb7a2e048b ci: cap build jobs and disable incremental in backend tests to prevent OOM (#10118) 2026-07-15 09:50:16 +02:00
Ruben Fiszel 770ac2be9e fix(self-host): resolve caddy-l4 "unrecognized global option: layer4" error (#10106)
The self-hosted Caddy image relied on the abandoned
RussellLuo/caddy-ext/layer4 shim to provide the `layer4` Caddyfile
global option, alongside an old (May 2024) pin of mholt/caddy-l4 that
predated native Caddyfile support. This combination is fragile:

- If the image is ever built without the RussellLuo shim, the `layer4`
  global option disappears and Caddy fails with
  "unrecognized global option: layer4" — the reported bug.
- Bumping mholt/caddy-l4 to any version with native Caddyfile support
  makes both modules register `layer4`, panicking at startup with
  "global option 'layer4' already registered".

mholt/caddy-l4 now natively registers the `layer4` global option, so
drop the RussellLuo dependency entirely and switch the Caddyfile to the
native `route { proxy { upstream ... } }` syntax. The adapted layer4
JSON is byte-identical to the previous output, so runtime behavior is
unchanged.

Also bump the Caddy base image to 2.11.4 (required by current
caddy-l4) and add a path-filtered push trigger so the published
`:latest` image is rebuilt whenever the Caddy Dockerfile changes,
instead of only on manual dispatch (which is how `:latest` drifted out
of sync with the checked-in Caddyfile in the first place).

Fixes GIT-903

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 01:08:55 +02:00
Ruben Fiszel 89bb63cff5 ci: drop debuginfo in backend integration tests to prevent runner OOM (#10088)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 16:58:24 +02:00
Ruben Fiszel b4c834f3cd ci: run Codex/Pi review on fork PRs when a maintainer triggers it (#10069)
* ci: run Codex review on fork PRs when a maintainer triggers it

The fork skip in codex-pr-review.yml unconditionally bailed on
cross-repository PRs, so even a maintainer's /codex or /review comment
(routed through pr-review-commands.yml via workflow_call, gated by
check-write-access) skipped external PRs.

Gate the skip on the automatic pull_request trigger only, detected via
an empty INPUT_PR_NUMBER (the metadata step already branches on this at
the same step). The workflow_call path now reviews fork PRs; the auto
pull_request trigger still skips them.

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

* ci: run Pi review on fork PRs when a maintainer triggers it

Apply the same fork-skip gating as the Codex review: skip fork PRs only
on the automatic pull_request trigger (empty INPUT_PR_NUMBER), so a
maintainer's /pi or /review comment (workflow_call, gated by
check-write-access) reviews external PRs.

Claude's pr-ready-review.yml needs no change: it has no fork skip, checks
out main (not the fork ref), and reviews via gh pr diff/view with a
restricted tool allowlist, so it already handles fork PRs on the command
path.

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

* ci: harden fork-review path against secret exfiltration

Addresses the CI review of the fork-review enablement. On the fork path
(maintainer-triggered workflow_call for a cross-repository PR), the
reviewer ran an autonomous agent over the attacker-controlled merge
checkout with the EE token present, full-access sandbox, and the review
prompt itself read from that untrusted checkout — so a malicious fork
could rewrite the reviewer's own instructions to exfiltrate secrets.

For fork PRs only (detected via the is_fork step output):
- withhold WINDMILL_EE_PRIVATE_ACCESS: skip the EE access/checkout/
  substitution steps, so the private-repo token is never in the env.
- read REVIEW.md and the prompt file from the trusted base ref
  (git show origin/<base>:...) instead of the merge checkout.
- restrict the agent: Codex runs with -s workspace-write (network off)
  instead of danger-full-access; Pi drops the bash tool.

Non-fork PRs are unchanged.

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

* ci: redact provider credentials from fork review comments

The model call needs the provider credential in its environment/config, so a
network-disabled sandbox alone can't stop a prompt-injected fork review from
reading the key (Codex: $HOME/.codex/auth.json; Pi: /proc/self/environ) and
emitting it in the final message, which both workflows post verbatim. GitHub
Actions log masking does not cover comments posted via the API.

Strip the known credential values (OpenAI key + raw Codex auth JSON and its
nested tokens; DeepSeek key) from the review body before posting, closing the
comment as an exfiltration channel. Applied unconditionally since a credential
should never appear in a review comment regardless of trigger.

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

* ci: don't persist github.token in fork review checkout

actions/checkout writes github.token into .git/config (http.extraheader) by
default. The review agent can read the checked-out tree, so on the fork path a
prompt injection could exfiltrate that token (issue/PR write) via .git/config —
the provider-credential redaction added earlier didn't cover it.

Set persist-credentials: false on the merge-ref checkout so the token is never
written to disk. Safe on both paths: the only later git op is an unauthenticated
fetch from the public origin, EE checkout uses its own token, and gh uses
GH_TOKEN. Also redact github.token from the posted comment as defense-in-depth.

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

* ci: disable Pi project-local discovery on fork reviews

Pi auto-discovers and executes project-local .pi extensions (.ts/.js) at
startup with DEEPSEEK_API_KEY in its environment — before the --tools allowlist
applies — so a fork could add an extension that exfiltrates the key over the
network, which output redaction can't catch.

On the fork path (cwd is the fork checkout), pass --no-extensions to disable
extension discovery, plus --no-skills/--no-prompt-templates/--no-themes/
--no-context-files so fork-controlled skills, templates, themes, and
AGENTS.md/CLAUDE.md aren't auto-loaded into the reviewer's prompt as an
injection vector. Non-fork behavior unchanged.

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

* ci: use unguessable delimiter for untrusted PR metadata outputs

The PR title/body were written to $GITHUB_OUTPUT with a fixed heredoc
terminator (PR_BODY_EOF). A fork author could embed that terminator in their PR
body to close the heredoc early and append their own output lines — e.g.
is_fork=false, which (last-write-wins) overrides the real is_fork=true and puts
fork code back on the trusted path (EE checkout + substitute_ee_code.sh with the
private token, full-access agent).

Generate a per-run random delimiter (128 bits from /dev/urandom) for the title
and body heredocs so the terminator can't be predicted or embedded. Everything
else in the block is single-line and newline-free, so this closes the injection.

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

* ci: set PI_OFFLINE=1 on fork Pi reviews to block package resolution

--no-extensions only filters which resources are *loaded*; Pi still resolves
packages declared in a fork's .pi/settings.json first, running `npm install` /
the configured npmCommand and lifecycle scripts with DEEPSEEK_API_KEY in env and
network available — before the extension filter applies.

Set PI_OFFLINE=1 on the fork path so the resolver's installMissing() short-
circuits (returns false) for every missing package, skipping all install/clone/
lifecycle execution. It gates only startup network ops (installs, helper-binary
downloads), not the provider inference call, so the review still runs. Verified:
a fork .pi/settings.json with a malicious npmCommand does not execute under the
flag. Non-fork path unchanged.

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

* ci: run fork Pi review from an isolated dir to cut off project config

Root cause of the recurring fork-review exposure: Pi resolves every project
config from <cwd>/.pi — settings/packages, extensions, skills, themes, prompts,
SYSTEM.md, APPEND_SYSTEM.md — so running inside the fork checkout let a fork
inject any of them to execute code or rewrite the reviewer's system prompt with
DEEPSEEK_API_KEY in env. Per-flag opt-outs (--no-extensions, PI_OFFLINE, ...)
only covered discovered vectors one at a time (SYSTEM.md wasn't covered).

Discovery is cwd-based (single level, no walk-up; global fallback is the trusted
runner home), so run Pi from a fresh mktemp dir where no fork .pi/* is on the
path. The fork agent has no shell, so pre-compute the diff (base...head SHAs are
trusted) into the context file it reads; it may still read fork files by
absolute path for extra context — reads are safe, only config discovery and code
execution were the risk. Outputs now use absolute workspace paths since cwd
moved. The --no-* flags and PI_OFFLINE stay as belt-and-suspenders. Non-fork
path unchanged. Verified: a fork .pi/SYSTEM.md sentinel is not discovered from
the isolated cwd.

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

* ci: keep review artifacts outside the checkout to defeat symlink writes

Both workflows wrote generated files (final message, event stream, review
context, prior-comments) into $GITHUB_WORKSPACE. On the fork path the merge tree
is attacker-controlled, so a fork could commit any of those paths as a symlink
(e.g. codex-final-message.md -> ../../_actions/actions/github-script/v7/dist/
index.js). Our write would follow it and overwrite the next action's code, which
then executes with the provider credential and the write-capable GitHub token —
no prompt injection required.

Route every generated file through $RUNNER_TEMP, which is runner-created and
outside the checkout, so no fork-committed symlink is on the path:
- prior-comments.json and pr-review-context.md are written to RUNNER_TEMP; the
  context step reads prior-comments from there.
- The agent is given the context file's absolute RUNNER_TEMP path (appended to
  the prompt); prompt files updated to reference it instead of a checkout-
  relative path. Pi (no shell on forks) gets the diff pre-computed into that
  context file; the isolated-cwd hardening is retained.
- Codex writes -o to RUNNER_TEMP; Pi writes its events/final message there; both
  post steps read from RUNNER_TEMP.

Non-fork behavior is functionally unchanged (trusted checkout; same review
inputs, now sourced from RUNNER_TEMP).

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

* ci: condense fork-review comments to the 4-line limit

AGENTS.md requires each invariant stated in <=4 lines. Trim the security
comments added in this branch (fork-skip rationale, output delimiter, isolated
cwd, RUNNER_TEMP artifacts, credential redaction) to comply without dropping the
constraint each one records.

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-14 12:16:49 +02:00
Ruben Fiszel 4783c01bff ci: drop debuginfo in Windows backend tests to fix disk exhaustion (WIN-2162) (#10059)
The Windows integration-test build (`cargo test --all --features …`) fills
the runner's C: drive during linking. profile.dev leaves the (large)
windmill workspace crates at the default debug = 2, so full debug info is
emitted into every object file and embedded in each test binary — the
dominant consumer of the ~63GB free on the runner. The previous
split-debuginfo=off knob only suppressed the separate .pdb, leaving the
embedded debug info in place; it was borderline and the Rust 1.97.0 bump
(v1.755.0) pushed it over into a disk-full failure.

Set CARGO_PROFILE_DEV_DEBUG=0 and CARGO_PROFILE_TEST_DEBUG=0 so no debug
info is generated at all for the CI dev/test profiles. This supersedes
split-debuginfo=off (no debuginfo => no .pdb, no mspdbsrv type server) and
substantially shrinks the target dir. CI-only; local dev builds are
unaffected.

Fixes WIN-2162

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 08:50:19 +02:00
Ruben Fiszel 3e251db7c8 add local-review-codex skill and bump CI codex to gpt-5.6-sol (#10051)
* feat: add local-review-codex skill and bump CI codex to gpt-5.6-sol

Add a `/local-review-codex` skill that runs the same Codex review as the
codex-pr-review GitHub action, locally and scoped to unpushed work
(committed + uncommitted), so contributors can catch what CI would flag
before pushing. Same REVIEW.md policy, gpt-5.6-sol model, and xhigh
reasoning effort as CI; runs read-only so it cannot modify the tree.

Also bump the CI codex-pr-review job to model gpt-5.6-sol on Codex CLI
0.144.1 (from gpt-5.5 / 0.128.0), and document the new skill in AGENTS.md.

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

* fix(local-review-codex): use bash in docs and fall back to origin/main

Address CI review findings:
- Docs invoked the runner with `sh`, which ignores the Bash shebang and
  fails on `set -o pipefail` under Dash (/bin/sh on Debian/Ubuntu). Use
  `bash` and note it in SKILL.md.
- Default base `main` is unresolved in checkouts that only have
  `origin/main`; resolve through a local ref first, then fall back to the
  remote-tracking ref. Fix the misleading `git fetch` recovery hint.
- Pin the codex-not-found install hint to @0.144.1 to match the workflow.

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-11 06:37:39 +02:00
Ruben Fiszel d35402d08e chore: bump Rust to 1.97.0 in worker build images and CI (#10047)
Update the pinned Rust toolchain from 1.93.0 to 1.97.0 (latest stable,
released 2026-07-09) across the worker/server build Dockerfiles
(Dockerfile, docker/DockerfileFull, docker/DockerfileFullEe) and all CI
workflows that pin a toolchain.

Verified the backend compiles cleanly with 1.97.0 under `-D warnings`
(the default RUSTFLAGS used by actions-rust-lang/setup-rust-toolchain).

Fixes WIN-2155

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 23:35:41 +02:00
Ruben Fiszel 98013483c8 restore auto-review & command gating for private org members (#9958)
* fix(ci): gate auto-review on non-fork PR not author_association (skips private members)

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

* fix(ci): authorize private org members for command workflows via app-token gate

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-06 11:26:55 +02:00
Ruben Fiszel 4b1f2207b8 ci: replace expiring-PAT org membership gate with author_association (#9957)
* ci for broken links + fix broken links

* ci: replace expiring-PAT org membership gate with author_association

The shared check-org-membership.yml reusable workflow authenticated to the
GitHub API with the ORG_ACCESS_TOKEN PAT to confirm org membership. That PAT
expired ~1 year after issuance, so the API could no longer see private org
members and check-membership emitted is_member=false — silently skipping every
auto-review, command-triggered review, /ai, /plan, and git-command job while
still reporting success.

Gate on the event payload's author_association (OWNER/MEMBER/COLLABORATOR)
instead, which comes from the built-in GITHUB_TOKEN and never expires. The
trusted internal bot and existing draft/fork/command guards are preserved; the
workflow_call paths stay open as trusted upstream. Deletes the now-unused
reusable workflow.

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-06 10:08:25 +02:00
Ruben Fiszel b28f974e50 fix: opt out of Deno minimum-dependency-age for private npm registries (#9802)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:08:52 +02:00
Ruben Fiszel 4a8210d769 ci: check out windmill-ee-private for the Claude PR reviewer (#9796)
The Claude review workflow used a plain checkout, so the EE source (the *_ee.rs
files that live in windmill-ee-private and are symlinked/gitignored in this repo)
was absent — the reviewer could only see the CE surface and missed EE-only code
like windmill-queue/src/jobs_ee.rs. Mirror the EE-checkout the Codex/Pi review
workflows already do: read the PR head's backend/ee-repo-ref.txt via the API,
check out windmill-ee-private at that ref, and substitute the EE files in (copy).
Gated on WINDMILL_EE_PRIVATE_ACCESS being present.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:05:23 +00:00
centdix 9d61e4e59e feat: self-host docs search for chat, mcp, cli; drop inkeep (#9772)
* feat: self-host docs search for chat, mcp and cli; remove inkeep

Embed a vendored docs snapshot (llms.txt/llms-full.txt) in the backend and
serve ranking + page rendering from GET /api/docs/{search,page}. The AI chat,
the MCP searchDocs/readDocsPage tools, and 'wmill docs' all consume it, so docs
search works with no runtime egress and is no longer EE-gated. Removes the
inkeep proxy. EE companion deletes inkeep_ee.rs (ee-repo-ref bumped).

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

* refactor: name read_docs_page param `url` instead of `path`

search_docs returns each hit's `Source` URL, so the read tool now takes a
`url` argument to match — the AI/MCP loop reads "search gives a Source URL,
read takes that url" rather than copying a `Source:` URL into a `path` slot.
A bare `/docs/...` path is still accepted and canonicalized before lookup.

Regenerated openapi-deref, the MCP endpoint tools, and the frontend client.

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

* ci: add scheduled workflow to refresh the vendored docs snapshot

The backend embeds docs_snapshot/*.gz at build time, so the in-product docs
corpus is otherwise only as fresh as the last manual fetch.sh run. This adds a
weekly (and manually dispatchable) job that re-runs fetch.sh, sanity-checks the
result against truncation/garbage, and opens a PR via the internal app when the
snapshot changed — so a human reviews the docs diff before it rides into the
next release build.

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

* refactor: make docs tool-result strings caller-neutral

The search/page endpoints back three differently-named consumers (the AI chat
`read_docs_page` tool, the MCP `readDocsPage` tool, and the `wmill docs` CLI),
so the shared rendered text shouldn't name one of them. Refer to "the docs
page-reading tool" and its `url` argument instead, and add tests pinning the
caller-neutral follow-up guidance.

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

* chore: point ee-repo-ref at inkeep-removal companion rebased on EE main

The companion branch now carries only the inkeep_ee.rs deletion on top of EE
main (was based on the native-job-retry EE line, which polluted the EE PR diff).

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

* fix(docs): expose docs:read in token catalog; precompute lowercased corpus

Addresses two review nits on the self-hosted docs PR:

- docs:read was enforced (ScopeDomain::Docs) but missing from the token scope
  catalog (token.rs ALL_SCOPES), so it couldn't be selected when creating a
  standard scoped token in the UI — leaving scope-restricted CLI/MCP docs use
  effectively ungrantable. Add a read-only "Documentation" group (no write
  surface) and a test asserting it is exposed.
- search ran page.body.to_lowercase() on the whole corpus per query. Lowercase
  body/title/description once at parse time (into the OnceLock corpus) and scan
  the precomputed copies instead.

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

* chore: update ee-repo-ref to 27a4f41b8e5603d6e444efcfc420bd1c44a07eed

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

Previous ee-repo-ref: c7ec3a0c2fa38d4cb5e50bf0265eef4710de4860

New ee-repo-ref: 27a4f41b8e5603d6e444efcfc420bd1c44a07eed

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-06-25 16:32:07 +02:00
Ruben Fiszel fada673bb4 chore: bump uv to 0.11.24 in images and CI (#9759)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 13:58:08 +02:00
centdix b0ddcf31e4 ci: add path-gated AI agent + ai_evals smoke workflows (#9640)
* ci: add path-gated AI agent integration tests workflow

Runs integration_tests/ai_agent_tests against real LLM providers
(Anthropic/OpenAI/Google) only when AI-agent backend code or the tests
change, since runs make paid LLM calls. Adds a conftest fixture that
skips provider-parametrized cases whose API keys are absent, so CI
exercises only the providers it has secrets for.

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

* ci: add path-gated ai_evals global-mode smoke workflow

Runs the global AI chat eval (global-test1) across one cheap model per
provider (Anthropic/OpenAI/Google/DeepSeek) only when the eval harness or
copilot chat code change, since runs make paid LLM calls. Builds Windmill
CE from source as the AI proxy; global tools/drafts run in the Vitest
bridge. Gates on the deterministic draft pipeline (run succeeded +
produced a draft + used write_script), not the variable LLM judge score.

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

* ci: run AI smokes on PR ready-for-review instead of every push

Switch the pull_request trigger from `synchronize` (every commit) to
`ready_for_review`, with a job guard skipping draft PRs, so the paid LLM
runs only fire when a PR is marked ready to merge (plus push-to-main and
manual dispatch).

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

* fix(ai_evals): lazily load cli mode so non-cli evals skip the cli toolchain

The entrypoint eagerly imported modes/cli, which pulls the wmill CLI
guidance modules and their JSR deps (@cliffy/*). Global/flow/script/app
runs then crashed with "Cannot find module '@cliffy/ansi/colors'" when
the cli workspace deps were not installed. Import createCliModeRunner
dynamically inside runCliBenchmark instead.

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

* test(ai_agent): raise low max_completion_tokens to OpenAI's 16 minimum

OpenAI's /v1/responses rejects max_output_tokens < 16 with a 400, failing
test_low_max_tokens for openai. 16 still exercises a truncated response.

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

* ci: run ai_evals workflow on Node 22 for the frontend undici 8.x dep

The Vitest bridge loads frontend/node_modules/undici@8.x, which requires
Node >=22.19; Node 20 failed with "webidl.util.markAsUncloneable is not a
function" when loading vitest.config.ts.

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

* fix(ai_evals): run frontend evals autonomously + give global-test1 more turns

Frontend evals (flow/script/app/global) ran the production chat prompt, which
assumes an interactive human — so cheaper models burned their turn budget
asking for confirmation, waiting for approval, or presenting a plan, sometimes
hitting maxTurns without producing a draft. Append a shared autonomy note in
baseEvalRunner (the path all frontend modes share, mirroring cli mode): act
directly on clear requests; only ask on genuinely ambiguous ones (preserving
the askUserQuestion cases). Also raise global-test1's maxTurns 8 -> 10 so a
model that over-explores still converges.

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

* ci(ai_evals): watch draft/prompt deps outside copilot/

The global eval runs production frontend code in-process, so the smoke's
behavior depends on files outside frontend/src/lib/components/copilot/**:
the draft model (userDraft.svelte.ts, userDraftDbSyncer.svelte.ts), script
inference (infer.ts), and the chat system prompts ($system_prompts ->
system_prompts/auto-generated). Add them to both push and PR path filters so
a change there actually triggers the smoke that gates on draft production.

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

* fix: skip direct provider tests without credentials

* feat: add ai evals skip judge flag

* fix: simplify ai evals ci gate

* fix: simplify ai evals smoke gate

* fix: handle ai eval workflow triggers

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 12:41:31 +02:00
Ruben Fiszel 68cfa42e3d revert to opus for claude workflows 2026-06-14 00:31:27 +02:00
Ruben Fiszel 49561f9e49 update claude actions to fable 5 2026-06-09 17:54:17 +00:00
Ruben Fiszel 7031744a19 fix(nsjail): precompile python stdlib + raise download rlimit_as (#9429)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:47:19 +00:00
Ruben Fiszel 12e06bfa6b bump default sync script to hub/28238 (windmill-cli@1.712.0) for fork branch push (#9372)
The fork-branch deployment callback runs the hub script
sync-script-to-git-repo-windmill, which imports `windmill-cli` as a pinned
npm dependency and runs it in-process (it does NOT shell out to a PATH wmill).
hub/28236 pinned windmill-cli@1.706.1, whose `git-deploy --only-create-branch`
path returns early without pushing — so the fork branch was checked out
locally but never published to the remote. #9366 fixed the CLI and shipped it
as windmill-cli@1.712.0, but without a hub-script bump the running callback
still used 1.706.1.

Bump LATEST_GIT_SYNC_SCRIPT_PATH to hub/28238, which is identical to 28236
except it pins windmill-cli@1.712.0 (content + lockfile). This fixes
test_workspace_fork_creates_branch and production fork-branch creation.

Also add backend/windmill-common/src/workspaces.rs to the git-sync-test
path-gate so future script-path bumps trigger the e2e (the bump alone is not
otherwise covered by the gate).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 04:36:53 +00:00
Ruben Fiszel 85a128cc34 prevent windows backend tests from running out of disk space (#9325) 2026-05-26 10:15:45 +00:00
Ruben Fiszel a28a68258c add cli-sync workspace snapshot/load scripts (#9322)
* feat(fixtures): add cli-sync workspace snapshot/load scripts

* fix(fixtures): address review nits (env var password, mktemp, dead refs)

* fix(fixtures): address CI review (SIGPIPE, JSON escaping, doc/code drift)
2026-05-26 04:35:05 +00:00
Ruben Fiszel e3fbc20c29 remove unused workflow 2026-05-22 20:50:49 +00:00
Ruben Fiszel 9dbce4a8c4 ci: disable PDB generation in Windows backend tests (#9201)
The dev profile's split-debuginfo = "unpacked" is coerced to "packed" on
windows-msvc, so each test-binary link spawns the shared mspdbsrv.exe PDB
type server. With 12 parallel link jobs this races the type-server cap
(LNK1318 "LIMIT (12)") and exhausts the runner disk (LNK1180), recurringly
failing the Windows release CI. CI needs no debug info, so disable PDB
generation for the dev/test profiles in this job only.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 14:43:35 +00:00
Ruben Fiszel 8f95402850 use OPENAI_API_KEY for codex workflow 2026-05-15 13:15:02 +00:00
Ruben Fiszel b348119ab9 publish CLI skills + AGENTS.md to windmill-cli-docs for context7 (#9143)
* feat: publish CLI skills + AGENTS.md to windmill-cli-docs for context7

Auto-generates a public docs snapshot (AGENTS.md, full CLI reference,
all rendered skills) and pushes it to windmill-labs/windmill-cli-docs on
every release tag, so context7 can index Windmill CLI docs.

- generate.py: new --context7-dir flag rendering fully-resolved skills
  + AGENTS.md (extracted from cli/src/guidance/core.ts to avoid drift)
  + cli-commands.md + README.md + manifest.json into a docs-repo checkout.
  Preserves .git, .github, LICENSE, context7.json across regenerations.
- publish-cli-docs.yml: GitHub Action on v* tag and workflow_dispatch
  that regenerates the docs repo and pushes via the CLI_DOCS_DEPLOY_KEY
  SSH deploy key.

* fix: skip tag mirror on workflow_dispatch from non-tag ref

* docs: turn windmill-cli-docs README into a CLI quickstart

* fix: address PR review (target safety, regex anchor, concurrency, tag mirror)

- Refuse to wipe --context7-dir unless empty, has a context7 marker, or
  points at the windmill-cli-docs remote (P1, prevents typo blast).
- Anchor AGENTS.md template regex on `generateAgentsMdContent` so adding
  other template-returning functions to core.ts can't silently retarget it.
- Decode TS escapes in one pass to avoid order-sensitive mangling.
- Include Windmill version (from version.txt) in manifest.json so each
  snapshot is self-describing.
- Add concurrency group on the publish workflow.
- Always mirror version tag on tag pushes, even when content is unchanged,
  so the docs repo has a tag for every Windmill release.
- Expand preserve list with .gitignore, .gitattributes, CODEOWNERS.

* fix: validate manifest.json content, not just presence, before wipe
2026-05-13 07:11:24 +00:00
hugocasa bbef5c9dd4 ping PR author when auto-review verdict is not good to merge (#9101)
* feat(ci): ping PR author when auto-review verdict is not good to merge

* fix(ci): drop (unknown) author fallback and clarify verdict-line rule
2026-05-11 14:56:52 +00:00
Ruben Fiszel 1bf1477cf7 ci: run codex review on every follow-up commit 2026-05-05 20:25:41 +00:00