* feat(forks): handle triggers and schedules in wmill workspace merge
Closes#9001. Brings CLI parity with the merge UI by routing trigger and
schedule diffs through the existing workspace_diff tally infrastructure
and lifting the deploy logic into the shared windmill-utils-internal
module.
- Backend: extend tally + compare to all 10 trigger kinds + schedule;
new compare_two_trigger_or_schedule helper using to_jsonb minus runtime
ignore set; CompareSummary gains schedules_changed/triggers_changed.
- Operational-state invariant: fork operations never flip target's
mode/enabled. Triggers strip mode/enabled in both UI and CLI deploy
payloads (preserved by is_mode_unspecified on backend). Schedules drop
the setScheduleEnabled mirror entirely on merge — EditSchedule lacks
enabled by design.
- Shared module: DeployKind extended with schedule + per-kind triggers;
DeployProvider gains per-kind dispatch methods.
- Frontend: ~600 lines of client-side trigger-diff machinery deleted;
rows flow through comparison.diffs like every other kind. Diff drawer
returns full GET response stripped of runtime fields, matching backend
semantics. Default selection excludes triggers/schedules (opt-in).
- CLI (merge.ts): per-kind provider, GCP-specific transforms (audience
reset, base_endpoint with /api stripped to match frontend), summary
table rows for Schedules/Triggers, default-deselect mirroring the UI.
- Bumps windmill-utils-internal to 1.5.0 (new exports for trigger
per-kind dispatch); frontend depends on ^1.5.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(enterprise): clarify [ee] prefix applies whenever an EE companion PR exists
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to 6ee680c25e3413d928fc22002be6deb118092668
This commit updates the EE repository reference after PR #557 was merged in windmill-ee-private.
Previous ee-repo-ref: ad35a056627656fd426fb19856ea945955d4727f
New ee-repo-ref: 6ee680c25e3413d928fc22002be6deb118092668
Automated by sync-ee-ref workflow.
* fix(forks): preserve target state on merge update, mirror source on create
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(forks): strip server-managed trigger fields and honor --include with --skip-conflicts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* fix(cli): resolve cross-folder relative imports during lockgen on fresh DB
On a fresh workspace, lockfile generation for scripts that imported other
scripts via cross-folder relative imports (or barrel re-exporters) failed with
"Failed to find relative import" because the dep job's bun build hit the
server before any helper was deployed. Three independent bugs combined to
produce this:
1. wmill sync push --auto-metadata regenerated locks per script without
building a DoubleLinkedDependencyTree or calling uploadScripts, so
temp_script_refs was never sent to dependencies_async.
2. wmill script generate-metadata (the deprecated alias) had its own old
in-line implementation that bypassed the tree entirely.
3. The TypeScript WASM parser dropped re-exports (export * from, export { x }
from) when called with skip_type_only=false — the path used by
parse_relative_imports — so barrel files looked like leaves to the CLI's
dependency tree and their sibling helpers were missing from
temp_script_refs.
Fix:
- sync.ts: --auto-metadata mirrors generate-metadata's flow (dryRun pass to
populate tree → propagateStaleness → uploadScripts → real pass with tree).
- script.ts: deprecated wmill script generate-metadata now delegates to the
canonical generateMetadata, which already does the tree+upload dance.
- parser-ts: visit_export_all and visit_named_export had inverted skip_type_only
guards; aligned with visit_import_decl's pattern.
Includes 4 E2E tests reproducing each customer-hit failure path and a Rust
unit test for the re-export parser fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump windmill-parser-wasm-ts to 1.695.0
Pin the parser package to the version published with the re-export fix
(visit_export_all / visit_named_export skip_type_only=false) so the CLI
and frontend pick it up at the next release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cli): restore legacy stale-check in deprecated alias, add tree to gen pass
Delegating wmill script generate-metadata fully to the canonical handler
broke 4 workspace_deps_filter tests that rely on the legacy hash-with-deps
formula and the "No metadata to update" output string.
Restore the original in-line implementation (legacy stale-check preserved),
but add a DoubleLinkedDependencyTree + uploadScripts pass before the actual
generation step. The customer's bug only manifests on real lockgen, not on
the dry-run staleness check, so this preserves the existing test contract
while still fixing cross-folder relative imports for the deprecated alias.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The config module imports node:fs/promises (stat, mkdir), which breaks
non-Node bundlers like the Cloudflare Workers build of the hub. The
windmill SPA frontend got away with it via tree-shaking, but stricter
runtimes choke on the bare node: import even when unused.
Stop re-exporting ./config from the main entry and expose it via a
windmill-utils-internal/config subpath instead. CLI code already
deep-imports the source file, so it is unaffected. Bumps the package
to 1.4.0 and updates the frontend dependency to match.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump windmill-parser-wasm-ts, -py and -py-imports to 1.693.1 in
the CLI and frontend after publishing the new versions.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add workspace-shared ui/ folder reusable across raw apps
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add shared ui/ drawer in raw app editor sidebar
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: forward workspace shared ui/ to raw app editor iframe
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* all
* all
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: support S3Object input args in native SQL scripts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: review fixes from local-review
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* update parser
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: track dollar-quoted strings in SQL block splitter
Queries like `CREATE FUNCTION ... AS $$ ... ; ... $$ LANGUAGE plpgsql;`
were being shredded on every `;` inside the function body because the
SQL splitter's state machine didn't recognize PostgreSQL dollar-quoted
strings. Add an `InDollarQuote(tag)` state so `$$ ... $$` and
`$tag$ ... $tag$` regions are treated as a single quoted span.
Opt-in via a new `track_dollar_quotes` flag on `parse_sql_blocks`;
enabled for PostgreSQL and DuckDB, disabled for MySQL/Oracle/BigQuery/
Snowflake which don't support the syntax.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: make windmill-parser-wasm a self-contained workspace
The wasm parser crate is excluded from the backend workspace (its
nightly-only `cargo-features = ["panic-immediate-abort"]` would break
stable cargo on the whole workspace), but its manifest still used
`.workspace = true` inheritance — which fails with "failed to find a
workspace root" once the parent no longer considers it a member.
Declare the crate as its own workspace by adding `[workspace]`,
`[workspace.package]`, and `[workspace.dependencies]` tables. Mirror
the relevant entries from the parent `backend/Cargo.toml` (same
version specs, same path targets) so resolution stays byte-identical
to what the parent would have produced.
Also:
- Teach `.github/change-versions.sh` (+ mac variant) to update this
crate's own `Cargo.toml` version and bulk-bump the `windmill-*`
entries in its `Cargo.lock` on each release.
- Bump the frontend's pinned `windmill-parser-wasm-regex` to 1.688.0
to match the freshly-built package, and refresh `package-lock.json`.
- Regenerate the wasm crate's `Cargo.lock` from scratch (first build
under the new workspace re-resolves the full graph; target-gated
deps from sibling crates like `windmill-parser-py-imports` are
now recorded in the lockfile but not compiled when targeting
wasm32).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add GitHub as a native trigger service
Add GitHub webhooks as a native trigger, allowing users to trigger
scripts/flows from repository events (push, PR, issues, etc.) via
OAuth-based webhook management.
Backend:
- DB migration adding 'github' to native_trigger_service, TRIGGER_KIND,
and job_trigger_kind enums
- Full External trait implementation: create/update/delete/get webhooks,
per-trigger sync verification, webhook payload preparation
- Paginated repos endpoint (up to 1000 repos)
- OAuth flow with admin:repo_hook and read:user scopes
Frontend:
- GitHub trigger form with repo picker and MultiSelect event selector
- Workspace integration settings with setup instructions
- Trigger badge, editor, and wrapper integration
- GithubIcon updated to support size/class props (matching other icons)
- Hub template reference for starter scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: show GitHub in sidebar when triggers exist
Add github_used to the getUsedTriggers endpoint so the sidebar picks up
GitHub as an active trigger kind. Also document this step in the native-
trigger skill so future services don't miss it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: on-demand GitHub repo search instead of bulk fetch
Replace the upfront pagination through all repos with a debounced search
flow: load 30 most-recently-updated repos by default, then query GitHub's
/search/repositories API (scoped to the authenticated user via user:@me
and restricted to name matches via in:name) as the user types.
Frontend uses runed's Debounced + resource to wire the Select's filterText
to the backend query with 300ms debouncing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: request `repo` OAuth scope to list private GitHub repos
`admin:repo_hook` grants webhook management but not repo listing — so
/user/repos and /search/repositories returned only public repos. Switch
to `repo` (full repo scope, which is a superset and also covers webhook
management).
Users who already connected GitHub need to disconnect and reconnect to
pick up the broader scope.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* revert: fetch all GitHub repos upfront instead of searching on demand
Revert the debounced search flow — paginate through /user/repos (up to
1000) on form open. Simpler UX: repos are all there from the start, the
Select's built-in client-side filter handles finding one.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: typed 404 detection + add GitHub flow template reference
Replace fragile e.to_string().contains("404") matching with a proper
http_error_status helper that downcasts through anyhow to the typed
HttpRequestError and reads the StatusCode.
Also wire the hub flow template (id 80) into NATIVE_TRIGGER_SERVICES.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update GitHub script template hub ID to 28202
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: align GitHub trigger with Nextcloud/Google patterns
Addresses review feedback from Claude and cubic.
Backend:
- `delete()` now only swallows NotFound (DB missing row) and 404 (API
webhook already deleted); non-404/DB errors propagate so callers know
cleanup failed. Matches Nextcloud's delete pattern exactly.
- `get_owner_repo_from_db` returns `Result<Option<(String, String)>>`
instead of an error on missing row (matches Google's delete flow).
Frontend:
- `loading: boolean` (required) + `$bindable()` with no default — matches
Nextcloud, satisfies CLAUDE.md banned-pattern rule.
- Wrap `loadRepos()` in `$effect` reacting to `$workspaceStore` so repos
load once the store is available and refresh on workspace switch.
- Replace raw `fetch('/api/.../native_triggers/github/repos')` with the
generated `NativeTriggerService.listGithubRepos(...)` typed client.
Adds `/repos` route + `GithubRepoEntry` schema to openapi.yaml.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add CI test scripts with auto-trigger on deploy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: fix annotation parser early return and handle renames correctly
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: move CI test results to top of script/flow detail pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: improve CI test results spacing, icon, and remove pass label
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: support one-line annotation and use script/path format
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: move CI test trigger logic to EE
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: move CI badge next to New badge and add deduplicated CI summary
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add CI test e2e tests and fix nullable column annotations
Add integration tests for CI test annotation parsing (creates/removes
ci_test_reference rows) and the CI test results API (single + batch
endpoints). Add backend test for auto-trigger on deploy (private+python).
Fix sqlx LEFT JOIN LATERAL nullable column annotations in
get_ci_test_results and get_ci_test_results_batch queries — sqlx
cannot infer nullability from LATERAL subqueries, causing runtime
decode errors when no matching job exists.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix build/sqlx
* fix
* feat: CI test improvements and templates
- Fix windmill-dep-map/private feature propagation in worker, api-scripts,
and api-flows Cargo.toml so CI test triggers actually fire in EE mode
- Clone ci_test_reference rows during workspace fork
- Add polling to CiTestResults component (refetch every 3s while running)
- Add running state and auto-refresh to ForkWorkspaceBanner CI summary
- Add yellow "CI test" badge on script list rows and detail page
- Fix Library badge border color (remove indigo border override)
- Add CI Test TypeScript and CI Test Python templates in ScriptBuilder
- Update sqlx offline cache
- Add debug tracing for CI test trigger in worker_lockfiles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add missing children prop to WorkspaceDeployLayout
Fixes svelte-fast-check type error when passing named snippets as
children content inside the component tag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address PR review feedback
- Remove empty wrapper divs around CiTestResults, move mb-4 into component
- Add batch endpoint size cap (max 200 items)
- Add ON DELETE CASCADE to ci_test_reference workspace FK (new migration)
- Downgrade CI test trigger logs from info to debug
- Fix false-positive polling: only treat status='running' as running,
not null status (CiTestResults, CompareWorkspaces, ForkWorkspaceBanner)
- Fix test numbering in integration tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to latest EE commit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to d9d68c2406df0b59f413ea0b2cb24780a9817d04
This commit updates the EE repository reference after PR #516 was merged in windmill-ee-private.
Previous ee-repo-ref: d7ccd9b86da99ec056a0e8708e3637d64290387a
New ee-repo-ref: d9d68c2406df0b59f413ea0b2cb24780a9817d04
Automated by sync-ee-ref workflow.
* fix: treat queued jobs (job_id set, null status) as running
Jobs that have been pushed but not yet picked up by a worker have a
job_id but null status. Treat these as 'running' to avoid showing
misleading 'pass' badges or '0 passing'. Tests that were never
triggered (no job_id, null status) remain neutral/hidden.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: hugocasa <hugo@casademont.ch>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>