mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 08:01:26 +00:00
3cd0eac8c1
* deps: bump deno_core / deno_ast / swc to the goldilocks pin set; drop serde ceiling
Bumps every deno_* and swc_* workspace dep to a hand-picked "goldilocks"
combination that drops the serde =1.0.220 ceiling without crashing into
the rustls / aws-sdk resolver wall that the obvious deno v2.6.0 target
hits.
## What's the goldilocks set
| crate | old | new | source |
|------------------|----------|-----------|---------------------------------------|
| deno_core | 0.336.0 | 0.352.0 | deno v2.4.0 |
| deno_fetch | 0.214.0 | 0.233.0 | deno v2.4.0 |
| deno_tls | 0.177.0 | 0.196.0 | deno v2.4.0 (last permissive-rustls) |
| deno_console | 0.190.0 | 0.209.0 | deno v2.4.0 |
| deno_url | 0.190.0 | 0.209.0 | deno v2.4.0 |
| deno_webidl | 0.190.0 | 0.209.0 | deno v2.4.0 |
| deno_web | 0.221.0 | 0.240.0 | deno v2.4.0 |
| deno_io | 0.100.0 | 0.119.0 | deno v2.4.0 |
| deno_net | 0.182.0 | 0.201.0 | deno v2.4.0 |
| deno_permissions | 0.49.0 | 0.68.0 | deno v2.4.0 |
| deno_telemetry | 0.12.0 | 0.31.0 | deno v2.4.0 |
| deno_error | =0.5.5 | =0.6.1 | deno v2.4.0 |
| deno_ast | =0.44.0 | =0.51.0 | **override** — see "load-bearing" below |
| deno_fs | (new) | 0.119.0 | new workspace dep — FetchPermissions exposes deno_fs::CheckedPath / GetPath as public API |
| v8 | =130.0.7 | =137.1.0 | deno_core 0.352 transitive |
| swc_common | =0.37.5 | =14.0.4 | **the load-bearing pin** |
| swc_ecma_ast | =0.118.2 | =15.0.0 | matched set with swc_common 14.0.4 |
| swc_ecma_parser | =0.149.1 | =24.0.3 | matched set |
| swc_ecma_visit | =0.104.8 | =15.0.0 | matched set |
| serde | =1.0.220 | ^1 | **freed** (resolves to 1.0.228+) |
## Why this combination and not v2.6.0
The obvious target was deno v2.6.0 (with deno_ast 0.52 → swc_common 17,
well past the `__private` ceiling). That hits three resolver collisions:
1. libsqlite3-sys: deno_cache → rusqlite 0.37 → libsqlite3-sys 0.35
vs sqlx → libsqlite3-sys 0.30. **Already killed by PR #9110** —
we dropped deno_runtime, which is what pulled in deno_cache.
2. fqdn 0.4.6/0.4.7 yanked, required by deno_permissions 0.81.0. Solvable
by injecting the yanked entry into Cargo.lock manually but ugly.
3. rustls: deno_tls 0.198+ hard-pins `=0.23.28`, but aws-sdk-bedrockruntime
1.122.0 → aws-smithy-http-client 1.1.5 wants `^0.23.31`. Within-major
conflict, no resolver path. The unbeatable wall.
Goldilocks-set choice sidesteps (2) and (3) entirely:
- `deno_tls 0.196.0` was the last version before deno tightened
`rustls ^0.23.11` (range, accepts 0.23.31) to exact `=0.23.28`. With
^0.23.11, the resolver picks rustls 0.23.35 (latest 0.23 patch) which
satisfies both deno_tls's `>=0.23.11` and aws-sdk's `>=0.23.31`. Verified
empirically: lockfile has rustls 0.23.35 after this bump.
- `deno_permissions 0.68.0` (v2.4.0's pin) doesn't depend on fqdn at all.
The fqdn dep was added in a later deno_permissions release.
## Why deno_ast =0.51.0 specifically (not 0.48.0 from v2.4.0)
`swc_common 14.0.4` is the first patch that **drops the
`pub use serde::__private as serde;` line** in `src/private/mod.rs`. Older
14.0.x and all 0.37.5–13.x revisions still have it, and that line is
what was capping `serde = "=1.0.220"` (the workspace pin's "stuck because
of swc" comment). Empirically verified by inspecting the tarballs of
14.0.0 / 14.0.1 / 14.0.2 / 14.0.3 / 14.0.4:
14.0.0: has hack
14.0.1: has hack
14.0.2: has hack
14.0.3: has hack
14.0.4: NO HACK ← inflection point
`deno_ast 0.51.0` pins `swc_common =14.0.4` exactly — older deno_ast
versions pin earlier swc_common patches that still have the hack.
Notably, deno v2.4.0 itself pins `deno_ast =0.48.0` (swc_common 9.2.0,
still has hack) — we deliberately deviate from v2.4.0's deno_ast pin
to escape the swc serde wall, while keeping the rest of v2.4.0's pin
set for resolver compatibility with aws-sdk. deno_ast 0.51 was never
shipped in any deno release (v2.4.5 used 0.49, v2.5.0 jumped to 0.50,
v2.6.0 to 0.52), but it's published on crates.io and compatible with
v2.4.0's deno_core 0.352.
## What this unblocks
- PR #9106's `serde = "=1.0.224"` bump variant can rebase onto this
and resolve cleanly (MaterializeInc/rust-postgres' `postgres-types`
needs `serde_core ^1.0.221`, which is satisfied now that we're on
serde 1.0.228).
- Future deno_* / swc_* bumps no longer need to argue about the serde
ceiling — it's gone.
## What changes in source code
This commit is Cargo.toml + Cargo.lock only. Source changes that the
new deno_core / deno_fetch API requires live in the follow-up commits:
- `parsers/windmill-parser-{ts,ts-asset,wac}`: swc 0.37 → 14
(`code.into()` ambiguity fix at 5 sites)
- `windmill-runtime-nativets/build.rs` + `src/lib.rs`: deno_core 0.336
→ 0.352 API moves (`init_ops_and_esm()` → `init()`,
`FetchPermissions` / `NetPermissions` trait signature updates,
`deno_tls::Proxy` enum shape change)
A companion change in windmill-ee-private adjusts
`otel_tracing_proxy_ee.rs:521` for `deno_telemetry::init`'s second arg
becoming by-value (was `&OtelConfig`).
* fix(parsers): adapt to swc_common 14 BytesStr ambiguity
swc 0.37.5 → 14.0.4 changed `SourceMap::new_source_file`'s `src` argument
from `String` to `impl Into<BytesStr>`. With `BytesStr` available, the
existing call sites' `code.into()` on a `&str` becomes ambiguous between
`Into<Bytes>` (from the bytes crate) and `Into<BytesStr>` (from
bytes_str). Switch to `code.to_string()` to produce an owned `String`
that satisfies `From<String> for BytesStr` unambiguously.
Five call sites across three crates:
- windmill-parser-ts/src/lib.rs (3 sites)
- windmill-parser-ts-asset/src/lib.rs (1 site)
- windmill-parser-wac/src/typescript.rs (1 site)
* fix(nativets): adapt to deno_core 0.352 / deno_fetch 0.233 API changes
The goldilocks deno bump (deno_core 0.336 → 0.352, deno_fetch 0.214 →
0.233, etc.) ripples through nativets' build.rs and src/lib.rs.
Source-level changes required:
## 1. `extension!` macro: `init_ops_and_esm()` and `init_ops()` removed
deno_core 0.352's `extension!` macro now generates a single `init()`
function on the extension struct (full: ops + esm), plus `lazy_init()`
(ops only, with `needs_lazy_init = true` and a contract that the
caller invokes `JsRuntime::lazy_init_extensions` after construction).
- `build.rs` (snapshot creation, wants both ops and esm baked in):
`X::init_ops_and_esm(...)` → `X::init(...)`.
- `src/lib.rs:create_nativets_runtime` (runtime, was using `init_ops()`
because the snapshot already provides esm): also → `X::init(...)`.
deno_core's snapshot path skips esm re-execution when the snapshot
provides them, so the esm registration is a no-op at runtime. This
is how deno's own v2.4.0 runtime works.
Avoided `lazy_init` because it requires plumbing
`JsRuntime::lazy_init_extensions(ext_args_vec)` correctly across the
codebase, which is invasive for no behavioural benefit.
## 2. Local `fetch` extension now declared in both build.rs and lib.rs
deno_core 0.352 validates extension order between snapshot and runtime.
Our snapshot's last extension is the local `fetch` ext (which provides
ext:fetch/src/runtime.js). To avoid a runtime panic:
"Extensions from snapshot loaded in wrong order: expected fetch but got windmill"
…the runtime extension list now ends with `fetch::init()` matching the
snapshot order. The macro requires the same `esm` argument to type-check,
even though the ESM is not re-executed at runtime (it's in the snapshot).
## 3. `FetchPermissions` and `NetPermissions` trait shape
`deno_fetch::FetchPermissions` (deno_fetch 0.233.0) added new methods
and changed signatures:
- `check_read` / `check_write`: now take `path: Cow<'a, Path>` plus
a new `get_path: &'a dyn deno_fs::GetPath` parameter, and return
`Result<deno_fs::CheckedPath<'a>, FsError>` instead of `Result<Cow<Path>, FsError>`.
- New `check_write` (didn't exist) and `check_net_vsock` methods.
`deno_net::NetPermissions` (deno_net 0.201.0) gained `check_vsock`
and `check_write_path` now takes `Cow<'_, Path>`.
For `build.rs`'s `PermissionsContainer` (used only during snapshot
creation, where permissions are never actually checked): all methods
`unreachable!("snapshotting")`.
For `src/lib.rs`'s `PermissionsContainer` (used at runtime — the
nativets policy is "allow everything"): `check_read` / `check_write`
return `Ok(CheckedPath::Unresolved(path))`, `check_*_vsock` return
`Ok(())`. Smoke tests confirm fetch/net/url/web/blob/timers/structuredClone
behaviour is intact end-to-end.
## 4. `deno_tls::Proxy` is now an enum
`deno_tls::Proxy` was a struct, is now an enum with `Http`, `Https`,
`Socks5` variants. Our call site uses HTTP proxies — switched the
struct literal `deno_tls::Proxy { url, basic_auth }` to
`deno_tls::Proxy::Http { url, basic_auth }`.
## 5. New `deno_fs` direct workspace dep
`FetchPermissions` exposes `deno_fs::CheckedPath` and `deno_fs::GetPath`
as part of its public API. We can't avoid naming `deno_fs` directly any
more. Pinned to 0.119.0 (v2.4.0's matched version, transitively present
already through deno_fetch). Added to workspace `[dependencies]` plus
nativets's `[dependencies]` and `[build-dependencies]`.
## Validation
`cargo check --features enterprise,deno_core,duckdb,license,python,rust,scoped_cache,parquet,private,private_registry_test,csharp,php,ruby,mysql,quickjs,mcp,run_inline`
→ clean.
`cargo test -p windmill-runtime-nativets smoke -- --ignored --skip smoke_net_`
→ 8 passed; 0 failed (the full local smoke suite covering fetch,
setTimeout/Promise.all, URL/SearchParams, Blob/btoa/atob, large payload
roundtrip, error propagation, concurrent isolates, TS enum/union
transpile).
Network smoke tests (`smoke_net_fetch_example_com`,
`smoke_net_fetch_json_and_headers`) not run as part of the validation
gate but expected to pass — the change preserves deno_fetch behaviour
through the trait surface.
* chore: update ee-repo-ref to pick up deno_telemetry::init by-value fix
Points at windmill-ee-private branch deps/bump-deno-and-swc-goldilocks
which contains the companion otel_tracing_proxy_ee.rs adjustment for
deno_telemetry 0.12 → 0.31 (second arg of `init` is now by-value).
EE-only file, doesn't affect OSS build.
* chore(nix): bump rusty_v8 in flake.nix to 137.1.0 to match Cargo.toml
Cargo.toml's v8 pin moved from =130.0.7 to =137.1.0 as part of the
deno_core 0.336 → 0.352 bump, but I missed the comment directly above
the version pin:
# Exact version NOTE: Do not forget to update version and hash in flake.nix
flake.nix provides the prebuilt librusty_v8 binary that the v8 crate
links against. A version mismatch would either fail to fetch (if the
137.1.0 release didn't exist) or cause link-time symbol mismatches.
Nix is used by rust-client-check.yml and rust_on_release.yml in CI,
plus the dev shell — stale flake pin breaks all of those.
Updates x86_64-linux's sha256 to match the actual hash of
librusty_v8_release_x86_64-unknown-linux-gnu.a.gz at the 137.1.0 tag.
Other targets (aarch64-linux, x86_64-darwin, aarch64-darwin) remain
as lib.fakeHash — they were already placeholders in the previous
pin, so we don't regress on them.
Caught by both cubic and Pi reviewers on PR #9111.
* docs(nativets): clarify snapshot-prefix rule in extension-order comment
Claude reviewer caught that the doc comment claimed the runtime
extension list matches the snapshot's order — implying an exact match.
The truth is more permissive: deno_core 0.352 requires the snapshot's
extension list to be a *prefix* of the runtime's, not an exact match.
Runtime is allowed to append extra extensions (which we do — the
windmill `ext` carrying our ops is the last entry at runtime but absent
from the snapshot).
The code is correct as-is; only the comment wording was misleading.
Also fixes the same wording in PR description.
573 lines
21 KiB
Nix
573 lines
21 KiB
Nix
{
|
|
inputs = {
|
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
rust-overlay.url = "github:oxalica/rust-overlay";
|
|
# Pin openapi-generator-cli to 7.10.0
|
|
nixpkgs-oapi-gen.url = "nixpkgs/2d068ae5c6516b2d04562de50a58c682540de9bf";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, flake-utils, rust-overlay, nixpkgs-oapi-gen }:
|
|
flake-utils.lib.eachDefaultSystem (system:
|
|
let
|
|
pkgs = import nixpkgs {
|
|
inherit system;
|
|
config.allowUnfree = true;
|
|
overlays = [ (import rust-overlay) ];
|
|
};
|
|
|
|
lib = pkgs.lib;
|
|
stdenv = pkgs.stdenv;
|
|
|
|
# ---------------------------------------------------------------
|
|
# Rust toolchain
|
|
# ---------------------------------------------------------------
|
|
|
|
rustStable = pkgs.rust-bin.stable.latest.default.override {
|
|
extensions = [ "rust-src" "rust-analyzer" "rustfmt" ];
|
|
};
|
|
|
|
patchedClang = pkgs.llvmPackages_18.clang.overrideAttrs (oldAttrs: {
|
|
postFixup = ''
|
|
# Copy the original postFixup logic but skip add-hardening.sh
|
|
${oldAttrs.postFixup or ""}
|
|
|
|
# Remove the line that substitutes add-hardening.sh
|
|
sed -i 's/.*source.*add-hardening\.sh.*//' $out/bin/clang
|
|
'';
|
|
});
|
|
|
|
# ---------------------------------------------------------------
|
|
# Native C/C++ dependencies (required to compile the backend)
|
|
# ---------------------------------------------------------------
|
|
|
|
nativeBuildDeps = with pkgs; [
|
|
# Crypto / TLS
|
|
openssl
|
|
openssl.dev
|
|
|
|
# XML / SAML (enterprise_saml feature)
|
|
libxml2.dev
|
|
xmlsec.dev
|
|
libxslt.dev
|
|
|
|
# FFI / codegen
|
|
libclang.dev
|
|
libffi # deno_ffi on macOS
|
|
|
|
# Networking / compression
|
|
curl.dev
|
|
zlib.dev
|
|
|
|
# Auth (kafka-gssapi, mssql-kerberos)
|
|
cyrus_sasl
|
|
krb5
|
|
|
|
# Misc
|
|
libtool
|
|
postgresql
|
|
|
|
# Build tooling
|
|
pkg-config
|
|
llvmPackages_18.clang # linker — pinned to 18 to avoid SIGSEGV with mold + newer clang
|
|
mold
|
|
cmake # required by rdkafka cmake-build
|
|
];
|
|
|
|
# ---------------------------------------------------------------
|
|
# Prebuilt V8 binary (must match version in Cargo.toml)
|
|
# ---------------------------------------------------------------
|
|
|
|
rustyV8Archive = let
|
|
version = "137.1.0";
|
|
target = stdenv.hostPlatform.rust.rustcTarget;
|
|
sha256 = {
|
|
x86_64-linux =
|
|
"sha256-Tiscfy2bzYGR3s0T+SC1IB3xWvTVpVcSEdjq3MCRoRw=";
|
|
aarch64-linux = lib.fakeHash;
|
|
x86_64-darwin = lib.fakeHash;
|
|
aarch64-darwin = lib.fakeHash;
|
|
}.${system};
|
|
in pkgs.fetchurl {
|
|
name = "librusty_v8-${version}";
|
|
url =
|
|
"https://github.com/denoland/rusty_v8/releases/download/v${version}/librusty_v8_release_${target}.a.gz";
|
|
inherit sha256;
|
|
};
|
|
|
|
# ---------------------------------------------------------------
|
|
# pkg-config search path for native libraries
|
|
# ---------------------------------------------------------------
|
|
|
|
pkgConfigPath = lib.makeSearchPath "lib/pkgconfig" (with pkgs; [
|
|
openssl.dev
|
|
libxml2.dev
|
|
xmlsec.dev
|
|
libxslt.dev
|
|
cyrus_sasl.dev
|
|
krb5.dev
|
|
]);
|
|
|
|
# ---------------------------------------------------------------
|
|
# RPATH — embed Nix store library paths into compiled binaries
|
|
# ---------------------------------------------------------------
|
|
|
|
rpathLibs = lib.makeLibraryPath (with pkgs; [
|
|
openssl
|
|
libffi
|
|
cyrus_sasl
|
|
krb5
|
|
libxml2
|
|
xmlsec
|
|
libxslt
|
|
stdenv.cc.cc.lib
|
|
]);
|
|
|
|
# ---------------------------------------------------------------
|
|
# Bindgen configuration
|
|
# Bindgen uses libclang directly (not $CC), so we must explicitly
|
|
# provide all Nix header search paths.
|
|
# See: https://web.archive.org/web/20220523141208/https://hoverbear.org/blog/rust-bindgen-in-nix/
|
|
# ---------------------------------------------------------------
|
|
|
|
bindgenClangArgs = builtins.concatStringsSep " " ([
|
|
"-nostdinc"
|
|
(builtins.readFile "${stdenv.cc}/nix-support/libc-crt1-cflags")
|
|
(builtins.readFile "${stdenv.cc}/nix-support/libc-cflags")
|
|
(builtins.readFile "${stdenv.cc}/nix-support/cc-cflags")
|
|
(builtins.readFile "${stdenv.cc}/nix-support/libcxx-cxxflags")
|
|
"-idirafter ${pkgs.libiconv}/include"
|
|
] ++ lib.optionals stdenv.cc.isClang [
|
|
"-idirafter ${stdenv.cc.cc}/lib/clang/${
|
|
lib.getVersion stdenv.cc.cc
|
|
}/include"
|
|
] ++ lib.optionals stdenv.cc.isGNU [
|
|
"-isystem ${stdenv.cc.cc}/include/c++/${lib.getVersion stdenv.cc.cc}"
|
|
"-isystem ${stdenv.cc.cc}/include/c++/${
|
|
lib.getVersion stdenv.cc.cc
|
|
}/${stdenv.hostPlatform.config}"
|
|
"-idirafter ${stdenv.cc.cc}/lib/gcc/${stdenv.hostPlatform.config}/${
|
|
lib.getVersion stdenv.cc.cc
|
|
}/include"
|
|
]);
|
|
|
|
# ---------------------------------------------------------------
|
|
# Build environment variables (shared by all shells that compile Rust)
|
|
# ---------------------------------------------------------------
|
|
|
|
buildEnvVars = {
|
|
PKG_CONFIG_PATH = pkgConfigPath;
|
|
RUSTY_V8_ARCHIVE = rustyV8Archive;
|
|
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
|
|
BINDGEN_EXTRA_CLANG_ARGS = bindgenClangArgs;
|
|
|
|
# Force clang 18 as cargo linker (stdenv may bring a newer clang that causes SIGSEGV with mold)
|
|
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER =
|
|
"${pkgs.llvmPackages_18.clang}/bin/clang";
|
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER =
|
|
"${pkgs.llvmPackages_18.clang}/bin/clang";
|
|
|
|
# Embed rpath so binaries find Nix store .so files at runtime
|
|
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS =
|
|
"-C link-arg=-fuse-ld=mold -C link-arg=-Wl,-rpath,${rpathLibs}";
|
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS =
|
|
"-C link-arg=-fuse-ld=mold -C link-arg=-Wl,-rpath,${rpathLibs}";
|
|
CARGO_HOST_RUSTFLAGS = "-C link-arg=-Wl,-rpath,${rpathLibs}";
|
|
|
|
# https://github.com/NixOS/nixpkgs/issues/370494 — jemalloc build fix
|
|
CFLAGS = "-Wno-error=int-conversion";
|
|
|
|
LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.zlib stdenv.cc.cc.lib ];
|
|
};
|
|
|
|
# ---------------------------------------------------------------
|
|
# OpenAPI generator (pinned)
|
|
# ---------------------------------------------------------------
|
|
|
|
openapi-generator-cli =
|
|
(import nixpkgs-oapi-gen { inherit system; }).openapi-generator-cli;
|
|
|
|
# ---------------------------------------------------------------
|
|
# Common worker runtimes (languages the worker executes)
|
|
# ---------------------------------------------------------------
|
|
|
|
commonRuntimes = with pkgs; [
|
|
deno
|
|
python3
|
|
python3Packages.pip
|
|
uv
|
|
go
|
|
bun
|
|
nushell
|
|
typescript
|
|
flock
|
|
];
|
|
|
|
# ---------------------------------------------------------------
|
|
# Runtime PATH env vars — tells the worker where to find interpreters
|
|
# ---------------------------------------------------------------
|
|
|
|
commonRuntimeVars = {
|
|
DENO_PATH = "${pkgs.deno}/bin/deno";
|
|
GO_PATH = "${pkgs.go}/bin/go";
|
|
BUN_PATH = "${pkgs.bun}/bin/bun";
|
|
NODE_PATH = "${pkgs.nodejs}/bin/node";
|
|
NODE_BIN_PATH = "${pkgs.nodejs}/bin/node";
|
|
UV_PATH = "${pkgs.uv}/bin/uv";
|
|
NU_PATH = "${pkgs.nushell}/bin/nu";
|
|
FLOCK_PATH = "${pkgs.flock}/bin/flock";
|
|
CARGO_PATH = "${rustStable}/bin/cargo";
|
|
BASH_PATH = "bash";
|
|
GIT_PATH = "${pkgs.git}/bin/git";
|
|
};
|
|
|
|
# ---------------------------------------------------------------
|
|
# Extra language runtimes (full shell only)
|
|
# ---------------------------------------------------------------
|
|
|
|
coursier = pkgs.fetchFromGitHub {
|
|
owner = "coursier";
|
|
repo = "launchers";
|
|
rev = "79d927f7586c09ca6d8cd01862adb0d9f9d88dff";
|
|
hash = "sha256-8E0WtDFc7RcqmftDigMyy1xXUkjgL4X4kpf7h1GdE48=";
|
|
};
|
|
|
|
rWithPackages = pkgs.rWrapper.override {
|
|
packages = with pkgs.rPackages; [ renv ];
|
|
};
|
|
|
|
extraRuntimes = with pkgs; [
|
|
dotnet-sdk_9
|
|
php
|
|
php84Packages.composer
|
|
ruby_3_4
|
|
jdk21
|
|
ansible
|
|
oracle-instantclient
|
|
];
|
|
|
|
extraRuntimeVars = {
|
|
JAVA_PATH = "${pkgs.jdk21}/bin/java";
|
|
JAVAC_PATH = "${pkgs.jdk21}/bin/javac";
|
|
COURSIER_PATH = "${coursier}/coursier";
|
|
DOTNET_PATH = "${pkgs.dotnet-sdk_9}/bin/dotnet";
|
|
DOTNET_ROOT = "${pkgs.dotnet-sdk_9}/share/dotnet";
|
|
PHP_PATH = "${pkgs.php}/bin/php";
|
|
COMPOSER_PATH = "${pkgs.php84Packages.composer}/bin/composer";
|
|
RUBY_PATH = "${pkgs.ruby_3_4}/bin/ruby";
|
|
RUBY_BUNDLE_PATH = "${pkgs.ruby_3_4}/bin/bundle";
|
|
RUBY_GEM_PATH = "${pkgs.ruby_3_4}/bin/gem";
|
|
ORACLE_LIB_DIR = "${pkgs.oracle-instantclient.lib}/lib";
|
|
ANSIBLE_PLAYBOOK_PATH = "${pkgs.ansible}/bin/ansible-playbook";
|
|
ANSIBLE_GALAXY_PATH = "${pkgs.ansible}/bin/ansible-galaxy";
|
|
CARGO_SWEEP_PATH = "${pkgs.cargo-sweep}/bin/cargo-sweep";
|
|
RSCRIPT_PATH = "${rWithPackages}/bin/Rscript";
|
|
};
|
|
|
|
# ---------------------------------------------------------------
|
|
# General dev environment variables
|
|
# ---------------------------------------------------------------
|
|
|
|
devEnvVars = {
|
|
NODE_ENV = "development";
|
|
NODE_OPTIONS = "--max-old-space-size=16384";
|
|
};
|
|
|
|
# Connection-specific defaults — set via shellHook so they respect
|
|
# pre-existing values (e.g. from webmux runtime.env / .env.local).
|
|
# Nix attrs are injected unconditionally and would override per-worktree
|
|
# values set by webmux before the interactive shell starts.
|
|
devShellHook = ''
|
|
export DATABASE_URL="''${DATABASE_URL:-postgres://postgres:changeme@127.0.0.1:5432/windmill?sslmode=disable}"
|
|
export REMOTE="''${REMOTE:-http://127.0.0.1:8000}"
|
|
export REMOTE_LSP="''${REMOTE_LSP:-http://127.0.0.1:3001}"
|
|
'';
|
|
|
|
# ---------------------------------------------------------------
|
|
# Helper scripts — base set (default + full)
|
|
# ---------------------------------------------------------------
|
|
|
|
helperScriptsBase = [
|
|
(pkgs.writeScriptBin "wm" ''
|
|
cd ./frontend
|
|
npm install
|
|
npm run ${
|
|
if stdenv.isDarwin then
|
|
"generate-backend-client-mac"
|
|
else
|
|
"generate-backend-client"
|
|
}
|
|
npm run dev "$@"
|
|
'')
|
|
(pkgs.writeScriptBin "wm-build" ''
|
|
cd ./frontend
|
|
npm install
|
|
npm run ${
|
|
if stdenv.isDarwin then
|
|
"generate-backend-client-mac"
|
|
else
|
|
"generate-backend-client"
|
|
}
|
|
npm run build "$@"
|
|
'')
|
|
(pkgs.writeScriptBin "wm-migrate" ''
|
|
cd ./backend
|
|
sqlx migrate run
|
|
'')
|
|
(pkgs.writeScriptBin "wm-reset" ''
|
|
sqlx database drop -f
|
|
sqlx database create
|
|
wm-migrate
|
|
'')
|
|
(pkgs.writeScriptBin "wm-minio" ''
|
|
set -e
|
|
cd ./backend
|
|
mkdir -p .minio-data/wmill
|
|
${pkgs.minio}/bin/minio server ./.minio-data --console-address ":9001"
|
|
'')
|
|
(pkgs.writeScriptBin "wm-minio-keys" ''
|
|
set -e
|
|
cd ./backend
|
|
${pkgs.minio-client}/bin/mc alias set 'wmill-minio-dev' 'http://localhost:9000' 'minioadmin' 'minioadmin'
|
|
if [[ -f .minio-data/secrets.txt ]] && [[ -s .minio-data/secrets.txt ]]; then
|
|
echo "Access keys already exist:"
|
|
cat .minio-data/secrets.txt
|
|
echo ""
|
|
echo "Keys loaded from: ./backend/.minio-data/secrets.txt"
|
|
else
|
|
echo "Creating new access keys..."
|
|
mkdir -p .minio-data
|
|
${pkgs.minio-client}/bin/mc admin accesskey create 'wmill-minio-dev' | tee .minio-data/secrets.txt
|
|
echo ""
|
|
echo 'New keys saved to: ./backend/.minio-data/secrets.txt'
|
|
fi
|
|
echo "bucket: wmill"
|
|
echo "endpoint: http://localhost:9000"
|
|
'')
|
|
];
|
|
|
|
# ---------------------------------------------------------------
|
|
# Helper scripts — extra (full shell only)
|
|
# ---------------------------------------------------------------
|
|
|
|
helperScriptsFull = [
|
|
(pkgs.writeScriptBin "wm-caddy" ''
|
|
cd ./frontend
|
|
xcaddy build "$@" \
|
|
--with github.com/mholt/caddy-l4@145ec36251a44286f05a10d231d8bfb3a8192e09 \
|
|
--with github.com/RussellLuo/caddy-ext/layer4@ab1e18cfe426012af351a68463937ae2e934a2a1
|
|
'')
|
|
(pkgs.writeScriptBin "wm-setup" ''
|
|
sqlx database create
|
|
wm-build
|
|
wm-caddy
|
|
wm-migrate
|
|
'')
|
|
(pkgs.writeScriptBin "wm-bench" ''
|
|
deno run -A benchmarks/main.ts -e admin@windmill.dev -p changeme "$@"
|
|
'')
|
|
];
|
|
|
|
# ---------------------------------------------------------------
|
|
# Shared inputs and settings for default + full shells
|
|
# ---------------------------------------------------------------
|
|
|
|
coreBuildInputs = nativeBuildDeps ++ commonRuntimes
|
|
++ [ rustStable openapi-generator-cli ] ++ (with pkgs; [
|
|
nodejs
|
|
git
|
|
sqlx-cli
|
|
cargo-watch
|
|
jq
|
|
gnused
|
|
|
|
# CLI tools (for AI agents and dev workflow)
|
|
gh
|
|
asciinema
|
|
mermaid-cli
|
|
]);
|
|
|
|
# Playwright: use Nix-provided browsers (version-matched to playwright-driver)
|
|
# Mermaid/Puppeteer: point at Nix chromium (Puppeteer respects this env var)
|
|
browserVars = {
|
|
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
|
|
PUPPETEER_EXECUTABLE_PATH = "${pkgs.chromium}/bin/chromium";
|
|
PUPPETEER_SKIP_DOWNLOAD = "true";
|
|
};
|
|
|
|
# Wrapper for the Nix-provided playwright CLI (version-matched to its browsers)
|
|
playwrightWrapper = pkgs.writeShellScriptBin "playwright" ''
|
|
export PLAYWRIGHT_BROWSERS_PATH="${pkgs.playwright-driver.browsers}"
|
|
exec ${pkgs.nodejs}/bin/node ${pkgs.playwright-driver}/cli.js "$@"
|
|
'';
|
|
|
|
# ---------------------------------------------------------------
|
|
# sandbox-env script — outputs env vars for browser tooling
|
|
# Usage: eval "$(sandbox-env)"
|
|
# ---------------------------------------------------------------
|
|
|
|
sandboxEnvScript = pkgs.writeShellScriptBin "sandbox-env" ''
|
|
echo "export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers}"
|
|
echo "export PUPPETEER_EXECUTABLE_PATH=${pkgs.chromium}/bin/chromium"
|
|
echo "export PUPPETEER_SKIP_DOWNLOAD=true"
|
|
'';
|
|
|
|
# ---------------------------------------------------------------
|
|
# pkg-config wrapper — bakes in the Nix pkg-config search path
|
|
# so sandbox profiles (buildEnv) work without setting env vars.
|
|
# ---------------------------------------------------------------
|
|
|
|
pkgConfigWrapper = pkgs.writeShellScriptBin "pkg-config" ''
|
|
export PKG_CONFIG_PATH="${pkgConfigPath}:$PKG_CONFIG_PATH"
|
|
exec ${pkgs.pkg-config}/bin/pkg-config "$@"
|
|
'';
|
|
|
|
# ---------------------------------------------------------------
|
|
# Installable sandbox profiles (nix profile install .#sandbox)
|
|
# ---------------------------------------------------------------
|
|
|
|
sandboxEnv = pkgs.buildEnv {
|
|
name = "windmill-sandbox";
|
|
paths = coreBuildInputs ++ helperScriptsBase ++ [
|
|
playwrightWrapper
|
|
sandboxEnvScript
|
|
pkgConfigWrapper
|
|
pkgs.chromium
|
|
];
|
|
};
|
|
|
|
sandboxFullEnv = pkgs.buildEnv {
|
|
name = "windmill-sandbox-full";
|
|
paths = coreBuildInputs ++ extraRuntimes ++ helperScriptsBase
|
|
++ helperScriptsFull ++ [
|
|
playwrightWrapper
|
|
sandboxEnvScript
|
|
pkgConfigWrapper
|
|
pkgs.chromium
|
|
pkgs.cargo-sweep
|
|
pkgs.xcaddy
|
|
pkgs.nsjail
|
|
];
|
|
};
|
|
|
|
in {
|
|
|
|
# =============================================================
|
|
# Installable profiles — for Docker / nix profile install
|
|
# Usage: nix profile install .#sandbox
|
|
# =============================================================
|
|
|
|
packages.sandbox = sandboxEnv;
|
|
packages.sandbox-full = sandboxFullEnv;
|
|
packages.default = sandboxEnv;
|
|
|
|
# =============================================================
|
|
# default — daily driver for backend + frontend development
|
|
# Usage: nix develop
|
|
# =============================================================
|
|
|
|
devShells.default = pkgs.mkShell (buildEnvVars // commonRuntimeVars // devEnvVars // browserVars // {
|
|
shellHook = devShellHook;
|
|
buildInputs = coreBuildInputs;
|
|
|
|
packages = helperScriptsBase ++ [ playwrightWrapper ];
|
|
});
|
|
|
|
# =============================================================
|
|
# full — all language runtimes, k8s tooling, specialized scripts
|
|
# Usage: nix develop .#full
|
|
# =============================================================
|
|
|
|
devShells.full = pkgs.mkShell (buildEnvVars // commonRuntimeVars // extraRuntimeVars // devEnvVars // browserVars // {
|
|
shellHook = devShellHook;
|
|
buildInputs = coreBuildInputs ++ extraRuntimes ++ (with pkgs; [
|
|
# Python extras
|
|
poetry
|
|
pyright
|
|
openapi-python-client
|
|
|
|
# LSP / editor
|
|
svelte-language-server
|
|
taplo
|
|
|
|
# Extra dev tools
|
|
cargo-sweep
|
|
|
|
# Kubernetes
|
|
minikube
|
|
kubectl
|
|
kubernetes-helm
|
|
conntrack-tools
|
|
cri-tools
|
|
|
|
# Extra
|
|
xcaddy
|
|
nsjail
|
|
]);
|
|
|
|
packages = helperScriptsBase ++ helperScriptsFull
|
|
++ [ playwrightWrapper ];
|
|
});
|
|
|
|
# =============================================================
|
|
# wasm — WASM target compilation (nightly Rust)
|
|
# Usage: nix develop .#wasm
|
|
# =============================================================
|
|
|
|
devShells.wasm = pkgs.mkShell (buildEnvVars // {
|
|
hardeningDisable = [ "all" ];
|
|
|
|
# Explicitly set paths for headers and linker
|
|
# DO NOT REMOVE - if absent, breaks wasm builds on NixOS.
|
|
shellHook = ''
|
|
export CC=${patchedClang}/bin/clang
|
|
'';
|
|
|
|
buildInputs = nativeBuildDeps ++ (with pkgs; [
|
|
(rust-bin.nightly.latest.default.override {
|
|
extensions = [ "rust-src" "rust-analyzer" ];
|
|
targets =
|
|
[ "wasm32-unknown-unknown" "wasm32-unknown-emscripten" ];
|
|
})
|
|
wasm-pack
|
|
deno
|
|
emscripten
|
|
nushell
|
|
nodejs
|
|
glibc_multi
|
|
]);
|
|
});
|
|
|
|
# =============================================================
|
|
# cli — lightweight Bun-based CLI development
|
|
# Usage: nix develop .#cli
|
|
# =============================================================
|
|
|
|
devShells.cli = pkgs.mkShell {
|
|
shellHook = ''
|
|
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
export FLAKE_ROOT="$(git rev-parse --show-toplevel)"
|
|
else
|
|
export FLAKE_ROOT="$PWD"
|
|
fi
|
|
'';
|
|
|
|
buildInputs = with pkgs; [ bun nodejs git ];
|
|
|
|
packages = [
|
|
(pkgs.writeScriptBin "wm-cli" ''
|
|
bun run $FLAKE_ROOT/cli/src/main.ts "$@"
|
|
'')
|
|
(pkgs.writeScriptBin "wm-cli-deps" ''
|
|
pushd $FLAKE_ROOT/cli/
|
|
${if stdenv.isDarwin then
|
|
"./gen_wm_client_mac.sh && ./windmill-utils-internal/gen_wm_client_mac.sh"
|
|
else
|
|
"./gen_wm_client.sh && ./windmill-utils-internal/gen_wm_client.sh"}
|
|
popd
|
|
'')
|
|
];
|
|
};
|
|
});
|
|
}
|