mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 08:02:47 +00:00
Merge remote-tracking branch 'origin/main' into glm/edit-view-ai-sessions
Main landed `operatingWorkspace.svelte.ts`, a general seam for "the workspace this subtree acts on", and rolled it out across ~230 files, deleting the `triggerWorkspace` and `rawAppWorkspace` seams it subsumes. `detailWorkspace.ts` was the same idea for the detail pages, so it goes the same way: ScriptDetail and FlowDetail now call `setOperatingWorkspace(() => workspace)`, and the eight shared components this branch had threaded through `getDetailWorkspace()` take main's version wholesale. PersistentScriptDrawer was outside main's rollout and is converted here. `ToolReloadEffect.items` now means main's page-item tabs, so the View-side reload set is named `deployed`. `resolvePreviewTab` grew `pageitem`/`pagelist` slots and a `workspacePageHref` switch on main; `viewer` slots into both. The flow detail body lives in FlowDetail.svelte on this branch, so main's four changes to `/flows/get` (chat wrapper `h-full min-h-0`, the padded notices wrapper, the `!chatInputEnabled` description gate, `frame="none"`) are ported there by hand. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CoC4MCs3BhVV1DyevrVc7N
This commit is contained in:
@@ -210,7 +210,7 @@ the diff first — `git diff --name-only main...HEAD` answers most of these.
|
||||
**Flip without asking** when it is self-contained: a single-file fix, test-only, docs-only, one
|
||||
call site, no new public surface.
|
||||
|
||||
Unattended (webmux oneshot) there is nobody to ask, so the judgement holds and the action
|
||||
Unattended (a one-shot run) there is nobody to ask, so the judgement holds and the action
|
||||
degrades: flip the self-contained ones, and leave the rest at a clean draft with a line in the PR
|
||||
description saying why — `left in draft: adds a migration, wants a human look before ready`.
|
||||
Don't flip a wide-blast-radius change just because the round came back clean, and don't ask a
|
||||
|
||||
+79
-1
@@ -1,4 +1,13 @@
|
||||
# Basic set up for three package managers
|
||||
# Weekly, grouped version updates for every shipped manifest, plus one grouped
|
||||
# security-update PR per manifest. Security-update PRs have no open-PR limit, so
|
||||
# without an `applies-to: security-updates` group each alert would get its own PR.
|
||||
# Bun has no security updates: /cli alerts are fixed through its version group.
|
||||
#
|
||||
# Deliberately NOT covered here:
|
||||
# - /rust-client: Cargo.toml is generated and gitignored
|
||||
# - /backend/parsers/windmill-parser-wasm: excluded from the workspace, needs nightly cargo
|
||||
# - /benchmarks/pulumi: one-off load-test infrastructure, not shipped
|
||||
# - /integration_tests: CI-only
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
@@ -13,12 +22,32 @@ updates:
|
||||
directory: "/frontend"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
# minor + patch bumps in one PR; majors in their own PR so they can be
|
||||
# reviewed separately without blocking the routine bumps
|
||||
frontend-deps:
|
||||
patterns: ["*"]
|
||||
update-types: ["minor", "patch"]
|
||||
frontend-majors:
|
||||
patterns: ["*"]
|
||||
update-types: ["major"]
|
||||
frontend-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for cargo
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/backend"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
# majors stay as individual PRs: they usually need code changes
|
||||
cargo-deps:
|
||||
patterns: ["*"]
|
||||
update-types: ["minor", "patch"]
|
||||
cargo-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for Docker
|
||||
- package-ecosystem: "docker"
|
||||
@@ -31,3 +60,52 @@ updates:
|
||||
directory: "/python-client/wmill"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
python-client-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for the CLI (bun.lock)
|
||||
- package-ecosystem: "bun"
|
||||
directory: "/cli"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
cli-deps:
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for the YAML validator
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/windmill-yaml-validator"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
yaml-validator-deps:
|
||||
patterns: ["*"]
|
||||
yaml-validator-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for the TypeScript client (devDependencies only)
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/typescript-client"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
typescript-client-deps:
|
||||
patterns: ["*"]
|
||||
typescript-client-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
# Maintain dependencies for multiplayer
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/multiplayer"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
multiplayer-deps:
|
||||
patterns: ["*"]
|
||||
multiplayer-security:
|
||||
applies-to: security-updates
|
||||
patterns: ["*"]
|
||||
|
||||
@@ -63,11 +63,11 @@ jobs:
|
||||
with:
|
||||
bun-version: 1.4.0
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
with:
|
||||
bun-version: 1.4.0
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
# Node 24 ships npm 11, which frontend/package-lock.json is authored
|
||||
# with; npm 10 rejects it ("Missing: picomatch@4.0.5 from lock file").
|
||||
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
# tests what production runs, instead of floating on the latest v2.x.
|
||||
deno-version: 2.2.1
|
||||
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: 1.21.5
|
||||
|
||||
@@ -75,11 +75,11 @@ jobs:
|
||||
with:
|
||||
bun-version: 1.4.0
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- uses: astral-sh/setup-uv@v6.2.1
|
||||
- uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.11.24"
|
||||
|
||||
|
||||
@@ -53,16 +53,16 @@ jobs:
|
||||
# Pin to the Deno version shipped in the runtime image (Dockerfile) so CI
|
||||
# tests what production runs, instead of floating on the latest v2.x.
|
||||
deno-version: 2.2.1
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: 1.21.5
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.4.0
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "24"
|
||||
- uses: astral-sh/setup-uv@v6.2.1
|
||||
- uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.11.24"
|
||||
- uses: shivammathur/setup-php@v2
|
||||
@@ -295,4 +295,4 @@ jobs:
|
||||
# never reaches it. Pin the target dir (matching the cache step above) so
|
||||
# its own tests run off this compile rather than a second bundled build.
|
||||
(cd windmill-duckdb-ffi-internal && export CARGO_TARGET_DIR="$PWD/target" && ./build_dev.sh && cargo test --release -p windmill_duckdb_ffi_internal)
|
||||
DENO_PATH=$(which deno) BUN_PATH=$(which bun) NODE_BIN_PATH=$(which node) GO_PATH=$(which go) UV_PATH=$(which uv) PHP_PATH=$(which php) COMPOSER_PATH=$(which composer) RUBY_PATH=$(which ruby) RUBY_BUNDLE_PATH=$(which bundle) RUBY_GEM_PATH=$(which gem) POWERSHELL_PATH=$(which pwsh) DOTNET_PATH=$(which dotnet) cargo test --features enterprise,deno_core,duckdb,license,python,rust,scoped_cache,parquet,private,private_registry_test,csharp,php,ruby,mysql,quickjs,mcp,run_inline --all -- --nocapture --test-threads=10
|
||||
DENO_PATH=$(which deno) BUN_PATH=$(which bun) NODE_BIN_PATH=$(which node) GO_PATH=$(which go) UV_PATH=$(which uv) PHP_PATH=$(which php) COMPOSER_PATH=$(which composer) RUBY_PATH=$(which ruby) RUBY_BUNDLE_PATH=$(which bundle) RUBY_GEM_PATH=$(which gem) POWERSHELL_PATH=$(which pwsh) DOTNET_PATH=$(which dotnet) cargo test --features enterprise,deno_core,duckdb,license,python,rust,scoped_cache,parquet,private,private_registry_test,csharp,php,ruby,mysql,quickjs,mcp,run_inline,smtp --all -- --nocapture --test-threads=10
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
sparse-checkout: |
|
||||
frontend/src
|
||||
.github/scripts
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "22.x"
|
||||
- name: Verify docs links are not 404
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
cache-workspaces: backend
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
@@ -143,7 +143,7 @@ jobs:
|
||||
cache-workspaces: backend
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
|
||||
@@ -40,11 +40,14 @@ jobs:
|
||||
# an author_association gate: the pull_request webhook payload reports private org
|
||||
# members as CONTRIBUTOR/NONE (only public members show as MEMBER), which silently
|
||||
# skips auto-review for every private member.
|
||||
# Dependabot-triggered runs get a separate secret scope, so this job has no API
|
||||
# key and cannot review. workflow_call stays open for an explicit request.
|
||||
if: |
|
||||
github.event_name == 'workflow_call' ||
|
||||
(
|
||||
github.event.pull_request.draft == false &&
|
||||
github.event.pull_request.head.repo.fork == false
|
||||
github.event.pull_request.head.repo.fork == false &&
|
||||
github.event.pull_request.user.login != 'dependabot[bot]'
|
||||
)
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -213,7 +216,7 @@ jobs:
|
||||
|
||||
- name: Set up Node.js
|
||||
if: steps.codex_config.outputs.enabled == 'true' && steps.pr.outputs.skip != 'true'
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ on:
|
||||
|
||||
jobs:
|
||||
notify_discord_when_pr_opened:
|
||||
if: (github.event.pull_request.draft == false) && (github.event.action == 'opened' || github.event.action == 'ready_for_review')
|
||||
# No thread is opened for Dependabot PRs, so nothing downstream may assume one.
|
||||
if: (github.event.pull_request.draft == false) && (github.event.action == 'opened' || github.event.action == 'ready_for_review') && (github.event.pull_request.user.login != 'dependabot[bot]')
|
||||
uses: ./.github/workflows/shareable-discord-notification.yml
|
||||
with:
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
@@ -28,7 +29,8 @@ jobs:
|
||||
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_AI_BOT_TOKEN }}
|
||||
|
||||
merge_success_emoji:
|
||||
if: github.event.action == 'closed'
|
||||
# Must match open_thread's exclusion: this reacts to a thread that was never created.
|
||||
if: github.event.action == 'closed' && github.event.pull_request.user.login != 'dependabot[bot]'
|
||||
uses: ./.github/workflows/shareable-discord-notification.yml
|
||||
with:
|
||||
PR_STATUS: "merged"
|
||||
|
||||
@@ -40,6 +40,11 @@ jobs:
|
||||
runs-on: ubicloud
|
||||
if: (github.event_name != 'workflow_dispatch') || (github.event.inputs &&
|
||||
!github.event.inputs.ee)
|
||||
# Jobs that build from, extract or retag this image must reference it by
|
||||
# this digest: concurrent main-branch runs push :dev too, so a tag run
|
||||
# reading :dev can ship a main build under the release version.
|
||||
outputs:
|
||||
digest: ${{ steps.docker_build.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -112,6 +117,8 @@ jobs:
|
||||
build_ee:
|
||||
runs-on: ubicloud
|
||||
if: (github.event_name != 'workflow_dispatch') || github.event.inputs.ee
|
||||
outputs:
|
||||
digest: ${{ steps.docker_build.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -192,31 +199,31 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
# pulling docker image with desired arch so that actions-docker-extract doesn't do it
|
||||
docker pull --platform "linux/$ARCH" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }}
|
||||
docker pull --platform "linux/$ARCH" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }}
|
||||
docker pull --platform "linux/$ARCH" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
docker pull --platform "linux/$ARCH" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
|
||||
- run: |
|
||||
# Checks the image is in docker prior to running actions-docker-extract. It fails if not
|
||||
# Also useful to visually check that the arch is the right opencontainers
|
||||
docker image inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }}
|
||||
docker image inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }}
|
||||
docker image inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
docker image inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
|
||||
- uses: shrink/actions-docker-extract@v3
|
||||
id: extract
|
||||
with:
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }}
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
path: "/usr/src/app/windmill"
|
||||
|
||||
- uses: shrink/actions-docker-extract@v3
|
||||
id: extract-duckdb-ffi-internal
|
||||
with:
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }}
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
path: "/usr/src/app/libwindmill_duckdb_ffi_internal.so"
|
||||
|
||||
- uses: shrink/actions-docker-extract@v3
|
||||
id: extract-ee
|
||||
with:
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }}
|
||||
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
path: "/usr/src/app/windmill"
|
||||
|
||||
- name: Rename binary with corresponding architecture
|
||||
@@ -373,8 +380,8 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Tag main and latest
|
||||
run: |
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
|
||||
|
||||
- uses: sigstore/cosign-installer@v4.1.2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
@@ -409,8 +416,8 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Tag main and latest for ee
|
||||
run: |
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:latest
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:main
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:latest
|
||||
docker buildx imagetools create ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:main
|
||||
|
||||
- uses: sigstore/cosign-installer@v4.1.2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
@@ -447,12 +454,18 @@ jobs:
|
||||
dockerhub-user: windmilllabs
|
||||
dockerhub-password: ${{ secrets.DOCKER_PAT }}
|
||||
|
||||
# Filed under main, not under the release tag this job runs on. The scanned image is
|
||||
# `-ee:main` and the Security tab only reads the default branch, so tag-only uploads
|
||||
# left main's last Docker Scout result at 2025-01-29: the tool showed as failing and
|
||||
# its alerts could never close. `sha` is the release commit, which is on main.
|
||||
- name: Upload SARIF result
|
||||
id: upload-sarif
|
||||
if: ${{ github.event_name != 'pull_request_target' }}
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: sarif.output.json
|
||||
ref: refs/heads/main
|
||||
sha: ${{ github.sha }}
|
||||
|
||||
# docker_scout_ee:
|
||||
# runs-on: ubicloud
|
||||
@@ -549,6 +562,8 @@ jobs:
|
||||
push: true
|
||||
sbom: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' }}
|
||||
file: "./docker/DockerfileCuda"
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
tags: |
|
||||
${{ steps.meta-ee-public.outputs.tags }}
|
||||
labels: |
|
||||
@@ -602,6 +617,8 @@ jobs:
|
||||
push: true
|
||||
sbom: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' }}
|
||||
file: "./docker/DockerfileSlim"
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
tags: |
|
||||
${{ steps.meta-ee-public.outputs.tags }}
|
||||
labels: |
|
||||
@@ -656,6 +673,8 @@ jobs:
|
||||
push: true
|
||||
sbom: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' }}
|
||||
file: "./docker/DockerfileSlimEe"
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
tags: |
|
||||
${{ steps.meta-ee-public.outputs.tags }}
|
||||
labels: |
|
||||
@@ -709,6 +728,8 @@ jobs:
|
||||
push: true
|
||||
sbom: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' }}
|
||||
file: "./docker/DockerfileFull"
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
|
||||
tags: |
|
||||
${{ steps.meta-public.outputs.tags }}
|
||||
labels: |
|
||||
@@ -761,6 +782,8 @@ jobs:
|
||||
push: true
|
||||
sbom: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name == 'push' }}
|
||||
file: "./docker/DockerfileFullEe"
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee@${{ needs.build_ee.outputs.digest }}
|
||||
tags: |
|
||||
${{ steps.meta-ee-public.outputs.tags }}
|
||||
labels: |
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubicloud-standard-8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: 24
|
||||
cache: "npm"
|
||||
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubicloud-standard-8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v4
|
||||
- uses: actions/setup-go@v7
|
||||
- name: install_jq
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubicloud-standard-8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20.x"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubicloud-standard-8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20.x"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
runs-on: ubicloud-standard-8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20.x"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
@@ -38,11 +38,14 @@ jobs:
|
||||
# an author_association gate: the pull_request webhook payload reports private org
|
||||
# members as CONTRIBUTOR/NONE (only public members show as MEMBER), which silently
|
||||
# skips auto-review for every private member.
|
||||
# Dependabot-triggered runs get a separate secret scope, so this job has no API
|
||||
# key and cannot review. workflow_call stays open for an explicit request.
|
||||
if: |
|
||||
github.event_name == 'workflow_call' ||
|
||||
(
|
||||
github.event.pull_request.draft == false &&
|
||||
github.event.pull_request.head.repo.fork == false
|
||||
github.event.pull_request.head.repo.fork == false &&
|
||||
github.event.pull_request.user.login != 'dependabot[bot]'
|
||||
)
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -206,7 +209,7 @@ jobs:
|
||||
|
||||
- name: Set up Node.js
|
||||
if: steps.pi_config.outputs.enabled == 'true' && steps.pr.outputs.skip != 'true'
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
|
||||
@@ -37,11 +37,14 @@ jobs:
|
||||
# an author_association gate: the pull_request webhook payload reports private org
|
||||
# members as CONTRIBUTOR/NONE (only public members show as MEMBER), which silently
|
||||
# skips auto-review for every private member.
|
||||
# Dependabot-triggered runs get a separate secret scope, so this job has no API
|
||||
# key and cannot review. workflow_call stays open for an explicit request.
|
||||
if: |
|
||||
github.event_name == 'workflow_call' ||
|
||||
(
|
||||
(github.event.pull_request.draft == false || github.event.pull_request.ready_for_review == true) &&
|
||||
github.event.pull_request.head.repo.fork == false
|
||||
github.event.pull_request.head.repo.fork == false &&
|
||||
github.event.pull_request.user.login != 'dependabot[bot]'
|
||||
)
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
ssh-key: ${{ secrets.CLI_DOCS_DEPLOY_KEY }}
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20.x"
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
# The interpreter is named explicitly: on a clean checkout uv picks the
|
||||
# runner's system python and stops with "not compatible with the locked
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
".": "1.814.0"
|
||||
".": "1.817.0"
|
||||
}
|
||||
|
||||
@@ -55,12 +55,23 @@ Open-source platform for internal tools, workflows, API integrations, background
|
||||
> defaults in this section apply only to a plain single checkout. **Discover the real
|
||||
> values before running anything** — see "Per-worktree ports and database" below.
|
||||
|
||||
**Check whether they are already running before starting anything.** In a webmux worktree
|
||||
(`$WEBMUX_WORKTREE_PATH` is set) the backend and frontend are already up in sibling tmux panes —
|
||||
use those, don't spawn your own. `tmux list-panes -t "$(tmux display-message -p -t "$TMUX_PANE"
|
||||
'#{window_id}')" -F '#{pane_index} #{pane_current_command}'` shows what is running; read its log
|
||||
with `tmux capture-pane`, and see `backend/AGENTS.md` to restart it with different cargo features.
|
||||
A second server started in your own shell fights the first one for the port. The commands below
|
||||
**Check whether they are already running before starting anything.** In a managed worktree the
|
||||
backend and frontend are already up in sibling panes — use those, don't spawn your own. A second
|
||||
server started in your own shell fights the first one for the port.
|
||||
|
||||
**herdr** is the worktree manager; `$HERDR_ENV=1` marks one of its panes. `herdr pane list
|
||||
--workspace "$HERDR_WORKSPACE_ID"` lists this worktree's panes — match on `cwd`, since the servers
|
||||
run from `backend/` and `frontend/` — and `herdr pane read <pane_id> --source recent-unwrapped
|
||||
--lines 50` reads one's log; `herdr --skill` prints the full reference for
|
||||
inspecting and driving panes and agents. The plugins that provision these worktrees live in the
|
||||
private `windmill-labs/windmill-herdr` — clone it and run `./setup.sh` to install them and the
|
||||
keybindings they need.
|
||||
|
||||
A worktree from the older **webmux** setup sets `$WEBMUX_WORKTREE_PATH` instead and is driven
|
||||
through tmux: `tmux list-panes -t "$(tmux display-message -p -t "$TMUX_PANE" '#{window_id}')" -F
|
||||
'#{pane_index} #{pane_current_command}'` for what is running, `tmux capture-pane` for a pane's log.
|
||||
|
||||
See `backend/AGENTS.md` to restart the backend with different cargo features. The commands below
|
||||
are for a plain checkout with nothing running.
|
||||
|
||||
- **Backend**: `cargo run` from `backend/` (API at http://localhost:8000)
|
||||
@@ -72,10 +83,16 @@ are for a plain checkout with nothing running.
|
||||
|
||||
### Per-worktree ports and database
|
||||
|
||||
In a webmux worktree the authoritative values live in
|
||||
`$(git rev-parse --git-dir)/webmux/runtime.env` — `BACKEND_PORT`, `FRONTEND_PORT`,
|
||||
`DATABASE_URL`, `CARGO_FEATURES`, `WM_DB_NAME`. Every pane sources it at startup. Read that
|
||||
first: it is not a `.env*` file, so the repo's secret-file read rules don't stand in the way.
|
||||
**`.env.local` in the worktree root holds the real values** — `BACKEND_PORT`, `FRONTEND_PORT`,
|
||||
`REMOTE`, `DATABASE_URL`, `CARGO_FEATURES`, `WM_DB_NAME`. Every manager writes those fields, so it
|
||||
is correct whichever one you are in. Read it with `cat .env.local` from a shell: the file-read
|
||||
tool denies every `.env.*` path, and `DATABASE_URL` is written with an `export` prefix that a
|
||||
`^DATABASE_URL=` grep misses.
|
||||
|
||||
herdr keeps nothing besides that file; its hooks write it and read it back. A webmux worktree
|
||||
additionally has `$(git rev-parse --git-dir)/webmux/runtime.env`, which every pane sources at
|
||||
startup and which carries the extras `.env.local` lacks: `WEBMUX_*`, `WM_CLONE_DB`,
|
||||
`USE_RUST_PLUGIN`.
|
||||
|
||||
In a plain checkout, fall back to `.env` / `.env.local` (repo root) and `backend/.env`.
|
||||
|
||||
@@ -84,19 +101,25 @@ hook. It is not a copy of the main dev instance: you get the `admins` workspace,
|
||||
`admin@windmill.dev` superadmin, the license key copied from the base database, and whatever the
|
||||
migrations seed — and none of your own workspaces, scripts, flows or apps. Create whatever a test
|
||||
needs. Cloning the base `windmill` database instead is
|
||||
opt-in per project via `WM_CLONE_DB` in `.webmux.yaml`; read the note there before turning it on.
|
||||
opt-in via `WM_CLONE_DB` (the `windmill.worktree` plugin's `config.env` under herdr, or
|
||||
`.webmux.yaml` under webmux); read the note in `.webmux.yaml` before turning it on.
|
||||
|
||||
The database is named after the **worktree directory, not the branch** (`scripts/worktree-common.sh`):
|
||||
`windmill_` + the directory basename with `-` → `_`, which Postgres then truncates at 63
|
||||
characters. Branch `hugo/win-2340-ai-agent-evals-standalone-agent-runs-and-eval-datasets` sits in
|
||||
a worktree directory named `win-2340-…`, so its database is
|
||||
`windmill_win_2340_ai_agent_evals_standalone_agent_runs_and_eval` — no `hugo_`, and the tail
|
||||
chopped. Take `WM_DB_NAME` from `runtime.env` instead of reconstructing the name. Read those, or
|
||||
discover from what is already running:
|
||||
characters. herdr creates the directory under `~/.herdr/worktrees/<repo>/` from the branch name
|
||||
with each `/` turned into `-`, so branch
|
||||
`hugo/win-2544-add-options-field-to-the-postgresql-resource-type` gets the database
|
||||
`windmill_hugo_win_2544_add_options_field_to_the_postgresql_reso` — the whole branch name, cut
|
||||
mid-word at the limit. The two drift apart as soon as the branch is renamed, and webmux named its
|
||||
directories after the ticket alone, so reconstructing the name from the branch you are on is
|
||||
wrong in both. Take `WM_DB_NAME` from `.env.local` instead. Read that, or discover from what is
|
||||
already running:
|
||||
|
||||
```bash
|
||||
# match on the worktree directory, truncated the way Postgres truncates it (63 - len('windmill_')):
|
||||
psql postgres://postgres:changeme@localhost:5432/postgres -tAc \
|
||||
"select datname from pg_database where datname like 'windmill%'" | grep "$(git branch --show-current | tr - _)"
|
||||
"select datname from pg_database where datname like 'windmill%'" \
|
||||
| grep -F "$(basename "$(git rev-parse --show-toplevel)" | tr '/-' '_' | cut -c1-54)"
|
||||
# the port the frontend actually proxies to (REMOTE of this worktree's vite):
|
||||
for p in $(pgrep -f vite); do case "$(readlink /proc/$p/cwd)" in *"$(basename "$(git rev-parse --show-toplevel)")"*)
|
||||
tr '\0' '\n' < /proc/$p/environ | grep -E '^REMOTE=|^PORT=';; esac; done
|
||||
|
||||
@@ -1,5 +1,93 @@
|
||||
# Changelog
|
||||
|
||||
## [1.817.0](https://github.com/windmill-labs/windmill/compare/v1.816.0...v1.817.0) (2026-09-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add workspace mentions to AI composer ([#11264](https://github.com/windmill-labs/windmill/issues/11264)) ([e7ba595](https://github.com/windmill-labs/windmill/commit/e7ba5954b69514d72c140f9b1e697fb2236df23e))
|
||||
* allow workspace-scoped dynamic custom tags ([#11283](https://github.com/windmill-labs/windmill/issues/11283)) ([efa7a0a](https://github.com/windmill-labs/windmill/commit/efa7a0a70af43f8827542059dd450326a9b88d62))
|
||||
* check dynamic worker tags on the tag they resolve to ([#11271](https://github.com/windmill-labs/windmill/issues/11271)) ([69fafb9](https://github.com/windmill-labs/windmill/commit/69fafb9262f90184e6c2dc9a84f1c3feeb9d9638))
|
||||
* deploy from the UI to a workspace on another instance ([#11245](https://github.com/windmill-labs/windmill/issues/11245)) ([4d12ea4](https://github.com/windmill-labs/windmill/commit/4d12ea461454f89367bd91daa7e8c39a89035507))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add missing credential fields to settings redaction lists ([#11272](https://github.com/windmill-labs/windmill/issues/11272)) ([2a40f25](https://github.com/windmill-labs/windmill/commit/2a40f25bda81d41b9f578338c85656744f59ebfc))
|
||||
* apply SSRF validation to workspace webhook URLs ([#11285](https://github.com/windmill-labs/windmill/issues/11285)) ([586699c](https://github.com/windmill-labs/windmill/commit/586699c4938b5203920a43e69a706310078b93f5))
|
||||
* apply token path scopes to the native trigger list ([#11281](https://github.com/windmill-labs/windmill/issues/11281)) ([faf7b22](https://github.com/windmill-labs/windmill/commit/faf7b22be0827738c90c1f3ed6cd3e214d6c63d3))
|
||||
* check workflow-as-code task tags against CUSTOM_TAGS ([#11273](https://github.com/windmill-labs/windmill/issues/11273)) ([2699d50](https://github.com/windmill-labs/windmill/commit/2699d5065ea3dfe985636733fb6022ca23187291))
|
||||
* clear the impersonation token from session storage on logout ([#11274](https://github.com/windmill-labs/windmill/issues/11274)) ([9936673](https://github.com/windmill-labs/windmill/commit/9936673ee62fb6dd929a654a6138aeca687c0fb7))
|
||||
* enforce token path scopes on GET /raw_apps/list ([#11284](https://github.com/windmill-labs/windmill/issues/11284)) ([9ad2c91](https://github.com/windmill-labs/windmill/commit/9ad2c91ddb661ab60ada9ec4039ef8d025602969))
|
||||
* keep a cancel that lands after a worker last read its queue row ([#11246](https://github.com/windmill-labs/windmill/issues/11246)) ([02006f3](https://github.com/windmill-labs/windmill/commit/02006f364a4217e967435d9e71d8617c03b65413))
|
||||
* size the AI chat output budget by model, not provider ([#11286](https://github.com/windmill-labs/windmill/issues/11286)) ([7d0f2ce](https://github.com/windmill-labs/windmill/commit/7d0f2ce3bf920a68f1ea22d59481d239947f1b51))
|
||||
* stop cutting DeepSeek chat turns off mid-thought ([#11282](https://github.com/windmill-labs/windmill/issues/11282)) ([5821700](https://github.com/windmill-labs/windmill/commit/58217006ece56bbaf0447af67cac487e72b928c7))
|
||||
* stop the raw app editor stealing focus in ai sessions ([#11287](https://github.com/windmill-labs/windmill/issues/11287)) ([7322143](https://github.com/windmill-labs/windmill/commit/732214361f36eb07d65854118bd053c96ce681fb))
|
||||
|
||||
## [1.816.0](https://github.com/windmill-labs/windmill/compare/v1.815.0...v1.816.0) (2026-09-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add an ACL editor for data table roles ([#11063](https://github.com/windmill-labs/windmill/issues/11063)) ([9994e03](https://github.com/windmill-labs/windmill/commit/9994e03bc75404503001a5db37e175b66e7371f2))
|
||||
* add per-model context window override in workspace AI settings ([#11232](https://github.com/windmill-labs/windmill/issues/11232)) ([c637b06](https://github.com/windmill-labs/windmill/commit/c637b06a548a5725aceb7504bcb62383d35614ac))
|
||||
* **ai-chat:** disclose an app's exposure on deploy, refuse drag-and-drop apps ([#11137](https://github.com/windmill-labs/windmill/issues/11137)) ([85b36a2](https://github.com/windmill-labs/windmill/commit/85b36a2de5f3fa08750b6d2ab8203f4b745cfdd2))
|
||||
* data table roles in the DB manager and raw apps ([#11139](https://github.com/windmill-labs/windmill/issues/11139)) ([e1e3692](https://github.com/windmill-labs/windmill/commit/e1e3692fbc82d50c021ef8bf8ca7019d760705f0))
|
||||
* drafts follow their item through a move; behind means base ≠ head ([#10577](https://github.com/windmill-labs/windmill/issues/10577)) ([f00b2fc](https://github.com/windmill-labs/windmill/commit/f00b2fcb1e65cb8f8e95d55f7cc58b816ac7d89d))
|
||||
* edit variables, resources and triggers in their own session tab ([#11206](https://github.com/windmill-labs/windmill/issues/11206)) ([6186a06](https://github.com/windmill-labs/windmill/commit/6186a0645d3f3e92e06b666a6b5774b8af2b488f))
|
||||
* let every EE instance set the announcement banner ([#11238](https://github.com/windmill-labs/windmill/issues/11238)) ([87761d1](https://github.com/windmill-labs/windmill/commit/87761d179799026ebaf9ed91bf589852b5453ee3))
|
||||
* snap-collapse the sidebar by dragging it to the left edge ([#11225](https://github.com/windmill-labs/windmill/issues/11225)) ([56a6ad3](https://github.com/windmill-labs/windmill/commit/56a6ad322e8354695a0a96eef9e83ffa135b3ad4))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* bump git sync hub scripts to cli 1.815.1 ([#11239](https://github.com/windmill-labs/windmill/issues/11239)) ([9e0e835](https://github.com/windmill-labs/windmill/commit/9e0e835c6876305d3a44902fb1432fd9c2348a7c))
|
||||
* check custom_instance_user can connect during instance database setup ([#11244](https://github.com/windmill-labs/windmill/issues/11244)) ([1b0f119](https://github.com/windmill-labs/windmill/commit/1b0f119c7b8ac2aacf2e2b4428c57f661df87ae5))
|
||||
* **cli:** read wmill.yaml from the branch a git-sync deploy writes to ([#11236](https://github.com/windmill-labs/windmill/issues/11236)) ([974b026](https://github.com/windmill-labs/windmill/commit/974b0265f85f9cfac65bbd2f6ebbcb0e966e3301))
|
||||
* guard data table migration routes against operators and unauthorized authors ([#11243](https://github.com/windmill-labs/windmill/issues/11243)) ([b742544](https://github.com/windmill-labs/windmill/commit/b7425443e1e08be029fc676047f727f84b646323))
|
||||
* tell the user when a draft conflict has stopped their edits saving ([#11241](https://github.com/windmill-labs/windmill/issues/11241)) ([d8ebbc0](https://github.com/windmill-labs/windmill/commit/d8ebbc06f5c56dad2570115700d640105d856c57))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* index audit logs by workspace and operation ([#11235](https://github.com/windmill-labs/windmill/issues/11235)) ([3b8c326](https://github.com/windmill-labs/windmill/commit/3b8c3264ecb33884420b1bdac9cae9c841e721a0))
|
||||
* keep the sessions page fast with many ai sessions ([#11224](https://github.com/windmill-labs/windmill/issues/11224)) ([4cbc944](https://github.com/windmill-labs/windmill/commit/4cbc944c0bcb938300c964437d745d15a3ea608f))
|
||||
* retire the legacy pre-partitioning audit table ([#11240](https://github.com/windmill-labs/windmill/issues/11240)) ([9f2685d](https://github.com/windmill-labs/windmill/commit/9f2685d788e624c9ed9db5cbaee456ea21af2b29))
|
||||
|
||||
## [1.815.0](https://github.com/windmill-labs/windmill/compare/v1.814.0...v1.815.0) (2026-09-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add a workspace toggle that adds its admins and developers to new forks ([#11215](https://github.com/windmill-labs/windmill/issues/11215)) ([9d335de](https://github.com/windmill-labs/windmill/commit/9d335de87a4dbaa51038d55afe8d980761dcdfaf))
|
||||
* add an instance setting to refuse a token in MCP URLs ([#11162](https://github.com/windmill-labs/windmill/issues/11162)) ([37e493a](https://github.com/windmill-labs/windmill/commit/37e493ae66ed5c000ecac492d60fc0fdf4bda71f))
|
||||
* **ai-chat:** render get_run through the run tools' card ([#11204](https://github.com/windmill-labs/windmill/issues/11204)) ([6f9c4dc](https://github.com/windmill-labs/windmill/commit/6f9c4dc29455d13b0e64af05c2d6aa8bd5ff4fd6))
|
||||
* **ai-chat:** tell the chat which kind of app it is looking at ([#11208](https://github.com/windmill-labs/windmill/issues/11208)) ([c8c06d8](https://github.com/windmill-labs/windmill/commit/c8c06d8f79774abf109192e71a8b6fc37c7937ba))
|
||||
* attach files to a flow chat message ([#11185](https://github.com/windmill-labs/windmill/issues/11185)) ([c4c9677](https://github.com/windmill-labs/windmill/commit/c4c9677982b75c63d98ebf85b1904e0c341ba957))
|
||||
* **auth:** 2 h login links and a click-to-sign-in page for emailed ones ([#11203](https://github.com/windmill-labs/windmill/issues/11203)) ([5639187](https://github.com/windmill-labs/windmill/commit/5639187fec6d517a72e82df49d63d7438301127c))
|
||||
* cap user token expiration with an instance setting ([#11159](https://github.com/windmill-labs/windmill/issues/11159)) ([9320312](https://github.com/windmill-labs/windmill/commit/9320312eac56f944c4d31504601293ab4e816ccc))
|
||||
* flow chat job-backed detail, smooth streaming and answer chrome ([#11186](https://github.com/windmill-labs/windmill/issues/11186)) ([e2a91ca](https://github.com/windmill-labs/windmill/commit/e2a91ca2b141a0bee64ddfafe3cbf3ff86b6fb35))
|
||||
* put a data table's connection under Postgres roles ([#11020](https://github.com/windmill-labs/windmill/issues/11020)) ([0e807fb](https://github.com/windmill-labs/windmill/commit/0e807fb1dd80d7536ec144cd49445abc7961e504))
|
||||
* render an AI agent result as its answer, not as raw JSON ([#11051](https://github.com/windmill-labs/windmill/issues/11051)) ([a089928](https://github.com/windmill-labs/windmill/commit/a08992834d45d0211336f4fc32c3421646ca47c5))
|
||||
* support $flow_expr[...] dynamic tags on flow steps ([#11170](https://github.com/windmill-labs/windmill/issues/11170)) ([48f0025](https://github.com/windmill-labs/windmill/commit/48f00259c5e7361d3553dbcb809461e1cde96f8f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** inline only the package version, not the whole package.json ([#11191](https://github.com/windmill-labs/windmill/issues/11191)) ([813e486](https://github.com/windmill-labs/windmill/commit/813e486e166ac6215364817a7732b66f8dc1d463))
|
||||
* keep instance groups when editing auto-invite ([#11217](https://github.com/windmill-labs/windmill/issues/11217)) ([df61dea](https://github.com/windmill-labs/windmill/commit/df61dea5fa8b18d1e0044dc0db6702b053d5119f))
|
||||
* key the large root font size on screen width, not window width ([#11216](https://github.com/windmill-labs/windmill/issues/11216)) ([3b4e13d](https://github.com/windmill-labs/windmill/commit/3b4e13d1c564c6195e30b55b0671f7533e3ce408))
|
||||
* re-encrypt git sync secrets on workspace key rotation ([#11218](https://github.com/windmill-labs/windmill/issues/11218)) ([f0d66a4](https://github.com/windmill-labs/windmill/commit/f0d66a42eba27502767423af0c08b2ca1f16e8df))
|
||||
* re-point cloned fork identities that name nobody in the fork ([#11161](https://github.com/windmill-labs/windmill/issues/11161)) ([9690c44](https://github.com/windmill-labs/windmill/commit/9690c4462cf264a5577b87d07d465b5442b4e09d))
|
||||
* register the job token with the sensitive log masking system ([#10943](https://github.com/windmill-labs/windmill/issues/10943)) ([53afecd](https://github.com/windmill-labs/windmill/commit/53afecd4588247bc1812d3e68a30db1f3c3b2724))
|
||||
* show the New menu's description panel only on hover ([#11199](https://github.com/windmill-labs/windmill/issues/11199)) ([ecd0a6c](https://github.com/windmill-labs/windmill/commit/ecd0a6c77bc3a057b8072dbb0aca731e8bd3d882))
|
||||
* stop picker listing a draft twice when drafts share a friendly path ([#11214](https://github.com/windmill-labs/windmill/issues/11214)) ([72507d5](https://github.com/windmill-labs/windmill/commit/72507d52a021de8101794ee8f4a3392be1ba20c7))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* count completed jobs on the v2_job_completed index with a timeout ([#11211](https://github.com/windmill-labs/windmill/issues/11211)) ([d1a2536](https://github.com/windmill-labs/windmill/commit/d1a25360b070994a31fb033707dbfde1fb553939))
|
||||
|
||||
## [1.814.0](https://github.com/windmill-labs/windmill/compare/v1.813.0...v1.814.0) (2026-09-17)
|
||||
|
||||
|
||||
|
||||
@@ -98,9 +98,11 @@ export async function runEval<THelpers, TOutput>(
|
||||
// Wrap tools to intercept fn calls for tracking.
|
||||
// Cast to ProductionTool since the eval Tool has a narrower toolCallbacks type
|
||||
// but the actual callbacks passed at runtime will satisfy both interfaces.
|
||||
// `fn` forwards `this`: the chat loop calls it on a per-iteration copy carrying the def the
|
||||
// model was sent, and a tool reading `this.def` must see that one, as it does in production.
|
||||
const wrappedTools = tools.map((tool) => ({
|
||||
...tool,
|
||||
fn: async (p: any) => {
|
||||
fn: async function (this: unknown, p: any) {
|
||||
toolCallsCount++;
|
||||
toolsCalled.push(tool.def.function.name);
|
||||
let argumentsText = "";
|
||||
@@ -120,7 +122,7 @@ export async function runEval<THelpers, TOutput>(
|
||||
toolName: tool.def.function.name,
|
||||
argumentsText,
|
||||
});
|
||||
return tool.fn(p);
|
||||
return tool.fn.call(this, p);
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import type {
|
||||
DataMetric,
|
||||
DataTableTables,
|
||||
DataTableTableSchema,
|
||||
EndpointTool,
|
||||
GetDraftForUserResponse,
|
||||
GetOwnDraftResponse,
|
||||
ListDraftsResponse,
|
||||
@@ -49,12 +48,16 @@ export interface BenchmarkWorkspaceFlow {
|
||||
export interface BenchmarkWorkspaceApp {
|
||||
path: string
|
||||
summary: string
|
||||
/** Defaults to true. Set false for a drag-and-drop app, which the chat can list
|
||||
* and read but has no tool to edit — its value is a grid, not files. */
|
||||
rawApp?: boolean
|
||||
value: {
|
||||
files: Record<string, string>
|
||||
runnables: Record<string, unknown>
|
||||
files?: Record<string, string>
|
||||
runnables?: Record<string, unknown>
|
||||
data?: unknown
|
||||
policy?: unknown
|
||||
custom_path?: unknown
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
@@ -994,7 +997,7 @@ function buildBenchmarkListableApp(app: BenchmarkWorkspaceApp): ListableApp {
|
||||
extra_perms: {},
|
||||
edited_at: BENCHMARK_TIMESTAMP,
|
||||
execution_mode: 'viewer',
|
||||
raw_app: true
|
||||
raw_app: app.rawApp ?? true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1012,123 +1015,10 @@ function buildBenchmarkApp(app: BenchmarkWorkspaceApp): AppWithLastVersion {
|
||||
execution_mode: 'viewer',
|
||||
extra_perms: {},
|
||||
custom_path: app.value.custom_path as string | undefined,
|
||||
raw_app: true
|
||||
raw_app: app.rawApp ?? true
|
||||
}
|
||||
}
|
||||
|
||||
// ============= API endpoint catalog (McpService.listMcpTools + raw fetch) =============
|
||||
// The global chat's API catalog tools list endpoints via McpService and execute
|
||||
// them with a plain relative fetch('/api/...'), which has no meaning in the
|
||||
// vitest environment. A representative slice of the real catalog is served here,
|
||||
// and `handleBenchmarkApiFetch` answers the executed calls.
|
||||
|
||||
const BENCHMARK_MCP_TOOLS: EndpointTool[] = [
|
||||
{
|
||||
name: 'listWorkers',
|
||||
description: 'List workers',
|
||||
instructions: 'List all workers with their last ping and job counts.',
|
||||
path: '/workers/list',
|
||||
method: 'GET',
|
||||
query_params_schema: {
|
||||
type: 'object',
|
||||
properties: { page: { type: 'integer' }, per_page: { type: 'integer' } }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'listQueue',
|
||||
description: 'List queued jobs',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/jobs/queue/list',
|
||||
method: 'GET',
|
||||
path_params_schema: {
|
||||
type: 'object',
|
||||
properties: { workspace: { type: 'string' } },
|
||||
required: ['workspace']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'getJob',
|
||||
description: 'get job',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/jobs_u/get/{id}',
|
||||
method: 'GET',
|
||||
path_params_schema: {
|
||||
type: 'object',
|
||||
properties: { workspace: { type: 'string' }, id: { type: 'string', format: 'uuid' } },
|
||||
required: ['workspace', 'id']
|
||||
},
|
||||
query_params_schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
no_logs: { type: 'boolean' },
|
||||
no_code: { type: 'boolean' },
|
||||
approval_token: { type: 'string' }
|
||||
},
|
||||
required: []
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'runScriptByPath',
|
||||
description: 'Run the deployed version of a script by path',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/jobs/run/p/{path}',
|
||||
method: 'POST',
|
||||
path_params_schema: {
|
||||
type: 'object',
|
||||
properties: { workspace: { type: 'string' }, path: { type: 'string' } },
|
||||
required: ['workspace', 'path']
|
||||
},
|
||||
body_schema: { type: 'object', properties: {} }
|
||||
},
|
||||
{
|
||||
name: 'runFlowByPath',
|
||||
description: 'Run the deployed version of a flow by path',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/jobs/run/f/{path}',
|
||||
method: 'POST',
|
||||
path_params_schema: {
|
||||
type: 'object',
|
||||
properties: { workspace: { type: 'string' }, path: { type: 'string' } },
|
||||
required: ['workspace', 'path']
|
||||
},
|
||||
body_schema: { type: 'object', properties: {} }
|
||||
},
|
||||
// Draft-covered endpoints, present so steering cases exercise the guard the
|
||||
// way production does (hidden from search, refused at call time).
|
||||
{
|
||||
name: 'getScriptByPath',
|
||||
description: 'Get a script by path',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/scripts/get/p/{path}',
|
||||
method: 'GET'
|
||||
},
|
||||
{
|
||||
name: 'createFlow',
|
||||
description: 'Create a flow',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/flows/create',
|
||||
method: 'POST'
|
||||
},
|
||||
{
|
||||
name: 'deleteSchedule',
|
||||
description: 'Delete a schedule',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/schedules/delete/{path}',
|
||||
method: 'DELETE'
|
||||
},
|
||||
{
|
||||
name: 'getVariable',
|
||||
description: 'Get a variable',
|
||||
instructions: '',
|
||||
path: '/w/{workspace}/variables/get/{path}',
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
|
||||
export function listBenchmarkMcpTools(): EndpointTool[] {
|
||||
return BENCHMARK_MCP_TOOLS
|
||||
}
|
||||
|
||||
/** A stand-in Windmill hub. `search_hub_scripts` and a `hub/` read go out over
|
||||
* relative `/api/...` fetches, which have no origin here, so without these the
|
||||
* hub tools throw and no case can exercise hub reuse. Serving fixtures rather
|
||||
@@ -1288,26 +1178,6 @@ const BENCHMARK_WORKERS = [
|
||||
}
|
||||
]
|
||||
|
||||
const BENCHMARK_JOB_GET_PATH = /^\/api\/w\/([^/]+)\/jobs_u\/get\/([^/]+)$/
|
||||
const BENCHMARK_RUN_BY_PATH = /^\/api\/w\/([^/]+)\/jobs\/run\/(p|f)\/([^/]+)$/
|
||||
|
||||
/** `executeEndpoint` sends a JSON string; anything else means no args were supplied. */
|
||||
function parseBenchmarkRequestBody(
|
||||
body: BodyInit | null | undefined
|
||||
): Record<string, unknown> | undefined {
|
||||
if (typeof body !== 'string') {
|
||||
return undefined
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(body)
|
||||
return typeof parsed === 'object' && parsed !== null
|
||||
? (parsed as Record<string, unknown>)
|
||||
: undefined
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/** True when `handleBenchmarkApiFetch` has an answer for this `/api/...` url.
|
||||
* Any other relative fetch must keep its normal (non-benchmark) behavior —
|
||||
* intercepting it with a synthetic 404 sends the model into retry loops. */
|
||||
@@ -1319,17 +1189,13 @@ export function hasBenchmarkApiHandler(url: string): boolean {
|
||||
const path = url.split('?')[0]
|
||||
return (
|
||||
path === '/api/workers/list' ||
|
||||
BENCHMARK_JOB_GET_PATH.test(path) ||
|
||||
BENCHMARK_RUN_BY_PATH.test(path) ||
|
||||
/^\/api\/w\/[^/]+\/jobs\/queue\/list$/.test(path) ||
|
||||
path === '/api/embeddings/query_hub_scripts' ||
|
||||
path.startsWith('/api/scripts/hub/get_full/') ||
|
||||
BENCHMARK_AI_MODELS_PATH.test(path)
|
||||
)
|
||||
}
|
||||
|
||||
/** Answer a relative `/api/...` fetch — from the API catalog executor, or from the
|
||||
* chat's hub tools. */
|
||||
/** Answer the relative `/api/...` fetches no mocked service covers. */
|
||||
export function handleBenchmarkApiFetch(url: string, init?: RequestInit): Response {
|
||||
const path = url.split('?')[0]
|
||||
if (path === '/api/workers/list') {
|
||||
@@ -1346,39 +1212,6 @@ export function handleBenchmarkApiFetch(url: string, init?: RequestInit): Respon
|
||||
?.aiProviders?.find((entry) => entry.path === resourcePath)
|
||||
return Response.json({ data: (seed?.models ?? []).map((id) => ({ id })) })
|
||||
}
|
||||
if (/^\/api\/w\/[^/]+\/jobs\/queue\/list$/.test(path)) {
|
||||
return Response.json([])
|
||||
}
|
||||
const jobGet = BENCHMARK_JOB_GET_PATH.exec(path)
|
||||
if (jobGet) {
|
||||
const id = decodeURIComponent(jobGet[2])
|
||||
const job = getBenchmarkCompletedJob(decodeURIComponent(jobGet[1]), id)
|
||||
if (!job) {
|
||||
return Response.json({ error: `Job not found for "${id}"` }, { status: 404 })
|
||||
}
|
||||
// The real endpoint lets a caller drop the bulky fields. Ignoring that here would
|
||||
// size the model's context off a payload it explicitly asked to shrink.
|
||||
const query = new URLSearchParams(url.split('?')[1] ?? '')
|
||||
if (query.get('no_logs') === 'true') {
|
||||
delete job.logs
|
||||
}
|
||||
if (query.get('no_code') === 'true') {
|
||||
delete job.raw_code
|
||||
}
|
||||
return Response.json(job)
|
||||
}
|
||||
const runByPath = BENCHMARK_RUN_BY_PATH.exec(path)
|
||||
if (runByPath) {
|
||||
const workspace = decodeURIComponent(runByPath[1])
|
||||
const runnablePath = decodeURIComponent(runByPath[3])
|
||||
const args = parseBenchmarkRequestBody(init?.body)
|
||||
// The real endpoint answers with the bare job id as text, not JSON.
|
||||
return new Response(
|
||||
runByPath[2] === 'f'
|
||||
? runBenchmarkFlowByPath({ workspace, path: runnablePath, args })
|
||||
: runBenchmarkScriptByPath({ workspace, path: runnablePath, args })
|
||||
)
|
||||
}
|
||||
if (path === '/api/embeddings/query_hub_scripts') {
|
||||
const text = new URLSearchParams(url.split('?')[1] ?? '').get('text') ?? ''
|
||||
return Response.json(searchBenchmarkHubScripts(text))
|
||||
|
||||
@@ -1,83 +1,18 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
|
||||
import {
|
||||
createBenchmarkCompletedJob,
|
||||
getBenchmarkCompletedJob,
|
||||
handleBenchmarkApiFetch,
|
||||
hasBenchmarkApiHandler,
|
||||
listBenchmarkMcpTools,
|
||||
resetBenchmarkMockBackend,
|
||||
registerBenchmarkWorkspaceRunnables
|
||||
} from './mockBackend'
|
||||
import { describe, expect, it } from 'bun:test'
|
||||
import { handleBenchmarkApiFetch, hasBenchmarkApiHandler } from './mockBackend'
|
||||
|
||||
const WORKSPACE = 'benchmark-api-ws'
|
||||
// `list_workers`'s client call is not faked, so its request really does leave as a relative
|
||||
// `/api/...` url that node's fetch cannot resolve. Without this route the tool throws instead
|
||||
// of answering.
|
||||
describe('benchmark API fetch handlers', () => {
|
||||
it('lists workers, the way list_workers reaches them', async () => {
|
||||
const url = '/api/workers/list?per_page=100'
|
||||
|
||||
// A catalog entry with no fetch handler is a dead end: the catalog executor builds a
|
||||
// relative `/api/...` url, the stub declines it, and node's fetch throws on the relative
|
||||
// url instead of returning a result the model can act on. Mutating entries are reachable
|
||||
// too — the eval runners define no `requestConfirmation`, so `call_api_endpoint` executes
|
||||
// unconfirmed.
|
||||
describe('benchmark API catalog', () => {
|
||||
beforeEach(() => resetBenchmarkMockBackend())
|
||||
afterEach(() => resetBenchmarkMockBackend())
|
||||
expect(hasBenchmarkApiHandler(url)).toBe(true)
|
||||
const body = await handleBenchmarkApiFetch(url).json()
|
||||
|
||||
it('answers every endpoint it advertises', () => {
|
||||
const unanswered = listBenchmarkMcpTools()
|
||||
.map((tool) =>
|
||||
`/api${tool.path.replace('{workspace}', WORKSPACE)}`.replace(/\{[^}]+\}/g, 'x')
|
||||
)
|
||||
.filter((url) => !hasBenchmarkApiHandler(url))
|
||||
|
||||
// The draft-covered entries are refused by name before any fetch, so they are
|
||||
// advertised without a handler on purpose.
|
||||
expect(unanswered).toEqual([
|
||||
`/api/w/${WORKSPACE}/scripts/get/p/x`,
|
||||
`/api/w/${WORKSPACE}/flows/create`,
|
||||
`/api/w/${WORKSPACE}/schedules/delete/x`,
|
||||
`/api/w/${WORKSPACE}/variables/get/x`
|
||||
])
|
||||
})
|
||||
|
||||
it('runs a deployed script by path, the way call_api_endpoint reaches it', async () => {
|
||||
registerBenchmarkWorkspaceRunnables(WORKSPACE, {
|
||||
scripts: [
|
||||
{
|
||||
path: 'f/evals/greet',
|
||||
summary: 'Greet',
|
||||
language: 'bun',
|
||||
content: 'export async function main() {}'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const res = handleBenchmarkApiFetch(
|
||||
`/api/w/${WORKSPACE}/jobs/run/p/${encodeURIComponent('f/evals/greet')}`,
|
||||
{ method: 'POST', body: JSON.stringify({ name: 'ada' }) }
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
const job = getBenchmarkCompletedJob(WORKSPACE, (await res.text()).trim())
|
||||
expect(job).toMatchObject({ success: true, args: { name: 'ada' } })
|
||||
})
|
||||
|
||||
it('serves a recorded job so a model can check the run it just started', async () => {
|
||||
const id = createBenchmarkCompletedJob({
|
||||
workspace: WORKSPACE,
|
||||
jobKind: 'preview',
|
||||
result: 'Hello, World!'
|
||||
})
|
||||
|
||||
const res = handleBenchmarkApiFetch(`/api/w/${WORKSPACE}/jobs_u/get/${id}`)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toMatchObject({
|
||||
id,
|
||||
success: true,
|
||||
result: 'Hello, World!'
|
||||
})
|
||||
})
|
||||
|
||||
it('404s an unknown job id instead of letting the fetch fall through', () => {
|
||||
expect(hasBenchmarkApiHandler(`/api/w/${WORKSPACE}/jobs_u/get/missing`)).toBe(true)
|
||||
expect(handleBenchmarkApiFetch(`/api/w/${WORKSPACE}/jobs_u/get/missing`).status).toBe(404)
|
||||
// The tool counts the list and maps over it, so it needs a bare array, not an envelope.
|
||||
expect(Array.isArray(body)).toBe(true)
|
||||
expect(body[0]).toMatchObject({ worker: expect.any(String), worker_group: expect.any(String) })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,8 +5,8 @@ import { mkdir, writeFile } from 'fs/promises'
|
||||
import { dirname, resolve } from 'path'
|
||||
import { handleBenchmarkApiFetch, hasBenchmarkApiHandler } from './mockBackend'
|
||||
|
||||
// The API catalog executor issues relative fetch('/api/...') calls, which have
|
||||
// no meaning in the vitest environment — serve the ones the benchmark handles.
|
||||
// Some tools reach the backend by relative fetch('/api/...'), which has no meaning
|
||||
// in the vitest environment — serve the ones the benchmark handles.
|
||||
// Every other relative fetch keeps its normal behavior (it fails the same way
|
||||
// it does without this stub) so unrelated tools see an unchanged environment.
|
||||
// The frontend builds API URLs from location.origin (fetchAvailableModels does), and node has no
|
||||
@@ -92,8 +92,7 @@ vi.mock('$lib/gen', async () => {
|
||||
runBenchmarkFlowPreview,
|
||||
runBenchmarkScriptByPath,
|
||||
runBenchmarkScriptPreview,
|
||||
updateBenchmarkDraft,
|
||||
listBenchmarkMcpTools
|
||||
updateBenchmarkDraft
|
||||
} = await import('./mockBackend')
|
||||
|
||||
function wrapService<T extends object>(target: T, overrides: Record<string, unknown>): T {
|
||||
@@ -434,12 +433,6 @@ vi.mock('$lib/gen', async () => {
|
||||
queryResourceTypes: async (data: { workspace: string }) =>
|
||||
hasBenchmarkWorkspace(data.workspace) ? [] : actual.ResourceService.queryResourceTypes(data)
|
||||
}),
|
||||
McpService: wrapService(actual.McpService, {
|
||||
listMcpTools: async (data: { workspace: string }) =>
|
||||
hasBenchmarkWorkspace(data.workspace)
|
||||
? listBenchmarkMcpTools()
|
||||
: actual.McpService.listMcpTools(data)
|
||||
}),
|
||||
VariableService: wrapService(actual.VariableService, {
|
||||
existsVariable: async (data: { workspace: string; path: string }) =>
|
||||
hasBenchmarkWorkspace(data.workspace)
|
||||
|
||||
+66
-29
@@ -1112,9 +1112,9 @@
|
||||
- opens the Kafka triggers page
|
||||
- does not write, deploy, or delete anything
|
||||
|
||||
- id: global-openpage7-compare-review
|
||||
- id: global-draft-does-not-open-compare
|
||||
prompt: |-
|
||||
Create a TypeScript script draft at f/evals/global/compare_review_demo that returns the string "ok" (no need to test it), then open the review page so I can look over the pending change and deploy it myself.
|
||||
Create a TypeScript script draft at f/evals/global/compare_review_demo that returns the string "ok" (no need to test it). I want to look over the change before it gets deployed.
|
||||
runtime:
|
||||
maxTurns: 8
|
||||
validate:
|
||||
@@ -1122,6 +1122,24 @@
|
||||
toolExpect:
|
||||
requiredToolsUsed:
|
||||
- write_script
|
||||
forbiddenToolsUsed:
|
||||
- open_page
|
||||
- deploy_workspace_item
|
||||
- delete_workspace_item
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- creates the script draft without opening any workspace page
|
||||
- does not deploy or delete anything
|
||||
|
||||
- id: global-openpage7-compare-fork-deploy
|
||||
prompt: |-
|
||||
I'm done with my changes in this fork and want to ship them to the parent workspace myself. Take me there.
|
||||
runtime:
|
||||
maxTurns: 6
|
||||
validate:
|
||||
draftCountExactly: 0
|
||||
toolExpect:
|
||||
requiredToolsUsed:
|
||||
- open_page
|
||||
forbiddenToolsUsed:
|
||||
- deploy_workspace_item
|
||||
@@ -1131,17 +1149,9 @@
|
||||
field: page
|
||||
stringIncludesAnyOf:
|
||||
- compare
|
||||
# The eval chat is untracked (no modified-items mask), so the model must scope
|
||||
# the review by passing the item it changed explicitly — an omitted mask would
|
||||
# preselect every pending change in the workspace.
|
||||
- tool: open_page
|
||||
field: items
|
||||
stringIncludesAnyOf:
|
||||
- f/evals/global/compare_review_demo
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- creates the script draft, then opens the Compare & Deploy review page instead of deploying itself
|
||||
- preselects only the created script on the review page
|
||||
- opens Compare & Deploy only because the user explicitly wants to deploy the fork into its parent
|
||||
- does not deploy or delete anything
|
||||
|
||||
- id: global-openpage8-runs-label-and-worker
|
||||
@@ -1919,11 +1929,10 @@
|
||||
- when the lookup fails, tells the user instead of inventing table names
|
||||
- does not write scripts or resources to answer a read-only question
|
||||
|
||||
# --- Dedicated tools preferred over the API catalog ---
|
||||
# The harness serves worker/queue reads itself (benchmark fetch handlers in
|
||||
# adapters/frontend), so these cases do not require an mcp-enabled eval backend.
|
||||
# The stale `api-catalog` in the id below is kept so results stay comparable
|
||||
# across benchmark runs.
|
||||
# --- Dedicated tools for workspace, run and instance state ---
|
||||
# The harness serves the worker read itself (a benchmark fetch handler in
|
||||
# adapters/frontend). The stale `api-catalog` in the id below is kept so
|
||||
# results stay comparable across benchmark runs.
|
||||
|
||||
- id: global-test30-api-catalog-workers
|
||||
prompt: |-
|
||||
@@ -1937,8 +1946,6 @@
|
||||
requiredToolsUsed:
|
||||
- list_workers
|
||||
forbiddenToolsUsed:
|
||||
- call_api_get
|
||||
- call_api_endpoint
|
||||
- write_script
|
||||
- deploy_workspace_item
|
||||
# Read-only workspace inspection produces no draft; validate via tool use.
|
||||
@@ -1990,13 +1997,11 @@
|
||||
requiredToolsUsed:
|
||||
- test_run_script
|
||||
forbiddenToolsUsed:
|
||||
- call_api_endpoint
|
||||
- deploy_workspace_item
|
||||
- delete_workspace_item
|
||||
# The judge only sees the drafts artifact and cannot observe runs, so it always
|
||||
# docks the prompt's "run it" requirement — validate deterministically instead:
|
||||
# draft content via valueIncludes, the test run via toolExpect (test_run_script
|
||||
# required, call_api_endpoint forbidden).
|
||||
# draft content via valueIncludes, the test run via toolExpect.
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- creates an AI draft of f/evals/global/format_greeting with the name uppercased in the greeting
|
||||
@@ -2014,13 +2019,11 @@
|
||||
requiredToolsUsed:
|
||||
- delete_workspace_item
|
||||
forbiddenToolsUsed:
|
||||
- call_api_endpoint
|
||||
- search_api_endpoints
|
||||
- write_script
|
||||
# Deletion produces no draft; validate via tool use.
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- deletes the deployed script via delete_workspace_item rather than a raw API endpoint
|
||||
- deletes the deployed script via delete_workspace_item
|
||||
|
||||
- id: global-test33-run-deployed-script-with-form
|
||||
prompt: |-
|
||||
@@ -2041,7 +2044,6 @@
|
||||
- read_workspace_item
|
||||
forbiddenToolsUsed:
|
||||
- test_run_script
|
||||
- call_api_endpoint
|
||||
- write_script
|
||||
- deploy_workspace_item
|
||||
# An empty form pushes the work back onto the user, so the prefill is part of
|
||||
@@ -2054,7 +2056,7 @@
|
||||
# Running produces no draft, and the judge cannot observe runs; validate via tool use.
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- runs the deployed script through run_script rather than a preview test run or a raw API endpoint
|
||||
- runs the deployed script through run_script rather than a preview test run
|
||||
- passes the name "ada" so the confirmation form comes up prefilled
|
||||
|
||||
- id: global-test34-run-with-secret-from-variable
|
||||
@@ -2113,7 +2115,6 @@
|
||||
- read_workspace_item
|
||||
forbiddenToolsUsed:
|
||||
- test_run_flow
|
||||
- call_api_endpoint
|
||||
- write_flow
|
||||
- deploy_workspace_item
|
||||
# An empty form pushes the work back onto the user, so the prefill is part of
|
||||
@@ -2126,7 +2127,7 @@
|
||||
# Running produces no draft, and the judge cannot observe runs; validate via tool use.
|
||||
skipJudge: true
|
||||
judgeChecklist:
|
||||
- runs the deployed flow through run_flow rather than a preview test run or a raw API endpoint
|
||||
- runs the deployed flow through run_flow rather than a preview test run
|
||||
- passes the customer "acme" so the confirmation form comes up prefilled
|
||||
|
||||
- id: global-test36-draft-flow-test-run-not-deployed
|
||||
@@ -2151,7 +2152,6 @@
|
||||
# version instead — the edit would not be in what ran.
|
||||
forbiddenToolsUsed:
|
||||
- run_flow
|
||||
- call_api_endpoint
|
||||
- deploy_workspace_item
|
||||
# The judge cannot observe runs, and the edit's content is already pinned by
|
||||
# global-test5 on this fixture; what this case guards is where the run went.
|
||||
@@ -2611,3 +2611,40 @@
|
||||
judgeChecklist:
|
||||
- runs the existing script rather than rewriting it
|
||||
- passes the GitHub resource as the bare string $res:f/evals/global/github_main
|
||||
|
||||
- id: global-drag-and-drop-app-not-editable
|
||||
prompt: |-
|
||||
Add a refresh button to the ops console app, and the same to the sales board app.
|
||||
initial: ai_evals/fixtures/frontend/global/initial/apps_code_and_drag_and_drop.json
|
||||
runtime:
|
||||
maxTurns: 12
|
||||
validate:
|
||||
# One request, two apps, only one of them editable: the code app must come back with a
|
||||
# draft and the drag-and-drop one must not. Refusing both, or editing both, fails here —
|
||||
# which is what makes this a test of the distinction rather than of caution.
|
||||
draftCountExactly: 1
|
||||
requiredDrafts:
|
||||
- type: app
|
||||
path: f/evals/global/ops_console
|
||||
forbiddenDrafts:
|
||||
- type: app
|
||||
path: f/evals/global/sales_board
|
||||
toolExpect:
|
||||
# Deliberately not constraining write_app_file/patch_app_file by argument: an entry there
|
||||
# fails when its tool was never called, so naming both would fail on whichever the model
|
||||
# did not pick. The draft assertions above cover the same ground, tool-agnostically.
|
||||
forbiddenToolsUsed:
|
||||
- init_app
|
||||
- deploy_workspace_item
|
||||
- delete_app_file
|
||||
- delete_app_runnable
|
||||
assistantExpect:
|
||||
# A refusal leaves no draft for the judge to read, so the explanation is checked here.
|
||||
# Only the app kind: substring tests cannot see paraphrase, and every wording of "I can't
|
||||
# edit it" defeats a fixed list.
|
||||
requiredMentionsAnyOf:
|
||||
- - drag-and-drop
|
||||
- drag and drop
|
||||
- low-code
|
||||
- no-code
|
||||
skipJudge: true
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"is_admin": true,
|
||||
"folders": ["evals"],
|
||||
"folders_read": ["evals"]
|
||||
},
|
||||
"workspace": {
|
||||
"apps": [
|
||||
{
|
||||
"path": "f/evals/global/sales_board",
|
||||
"summary": "Sales board",
|
||||
"rawApp": false,
|
||||
"value": {
|
||||
"grid": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "f/evals/global/ops_console",
|
||||
"summary": "Ops console",
|
||||
"value": {
|
||||
"files": {
|
||||
"/App.tsx": "export default function App() {\n\treturn <div>Ops console</div>\n}\n"
|
||||
},
|
||||
"runnables": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT s.hash as hash, dm.deployment_msg as deployment_msg, s.created_at as created_at, s.created_by as created_by\n FROM script s LEFT JOIN deployment_metadata dm ON s.hash = dm.script_hash\n WHERE s.workspace_id = $1 AND s.path = $2\n ORDER by s.created_at DESC\n LIMIT $3 OFFSET $4",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "hash",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "deployment_msg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "044310c0e7745867a24a9d3653ff29c87ce48ffd89fac070c8314556f884ce55"
|
||||
}
|
||||
+4
-4
@@ -1,22 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM v2_job_queue WHERE id = $1 RETURNING 1",
|
||||
"query": "SELECT 1 AS one FROM workspace_settings WHERE workspace_id = $1 FOR UPDATE",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "?column?",
|
||||
"name": "one",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "c92cc71e6d10c41368f7aa75b0799c2e1e9ca0ed33077ade8d7560e7cc21fa06"
|
||||
"hash": "06abbf945bee93349ff88f64906b96ea1e853ef202510281427cfa9beeff81b3"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings ws\n SET datatable = (\n SELECT jsonb_set(ws.datatable, '{datatables}', jsonb_object_agg(\n dt.key,\n CASE WHEN dt.value->'reference'->>'workspace_id' = $1\n AND dt.value->'reference'->>'datatable' = $2\n THEN jsonb_set(dt.value, '{reference,datatable}', to_jsonb($3::text))\n ELSE dt.value END\n ))\n FROM jsonb_each(ws.datatable->'datatables') dt\n )\n WHERE EXISTS (\n SELECT 1 FROM jsonb_each(COALESCE(ws.datatable->'datatables', '{}'::jsonb)) d\n WHERE d.value->'reference'->>'workspace_id' = $1\n AND d.value->'reference'->>'datatable' = $2\n )",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "06ce02cd7ce2f5a57355153edb573c242f9ba758db66e9a5e16f30e3e1494201"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE draft AS d\n SET path = $3::text,\n value = (\n SELECT CASE\n WHEN s.clean -> 'path' = to_jsonb($2::text)\n OR s.clean -> 'draft_path' = to_jsonb($2::text)\n THEN to_json(\n s.clean\n || CASE WHEN s.clean -> 'path' = to_jsonb($2::text)\n THEN jsonb_build_object('path', $3::text)\n ELSE '{}'::jsonb END\n || CASE WHEN s.clean -> 'draft_path' = to_jsonb($2::text)\n THEN jsonb_build_object('draft_path', $3::text)\n ELSE '{}'::jsonb END\n )\n ELSE d.value\n END\n FROM (SELECT replace(replace(replace(d.value::text, chr(92) || chr(92), chr(1)),\n chr(92) || 'u0000', ''), chr(1), chr(92) || chr(92))::jsonb AS clean) s\n )\n WHERE d.workspace_id = $1\n AND d.path = $2::text\n AND d.typ::text = ANY($4::text[])",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "09e3f8fa8a9e64048971983584bfa00ab137c70b73f381452cadfae6e1cda934"
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT value as \"value!: sqlx::types::Json<Box<serde_json::value::RawValue>>\",\n created_at, base\n FROM draft\n WHERE workspace_id = $1\n AND (email = $2 OR email IS NULL)\n AND path = $3\n AND typ = $4\n ORDER BY email NULLS LAST\n LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "value!: sqlx::types::Json<Box<serde_json::value::RawValue>>",
|
||||
"type_info": "Json"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "base",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
{
|
||||
"Custom": {
|
||||
"name": "draft_kind",
|
||||
"kind": {
|
||||
"Enum": [
|
||||
"script",
|
||||
"flow",
|
||||
"app",
|
||||
"raw_app",
|
||||
"resource",
|
||||
"variable",
|
||||
"trigger_schedule",
|
||||
"trigger_webhook",
|
||||
"trigger_default_email",
|
||||
"trigger_email",
|
||||
"trigger_http",
|
||||
"trigger_websocket",
|
||||
"trigger_postgres",
|
||||
"trigger_kafka",
|
||||
"trigger_nats",
|
||||
"trigger_mqtt",
|
||||
"trigger_sqs",
|
||||
"trigger_gcp",
|
||||
"trigger_azure",
|
||||
"trigger_poll",
|
||||
"trigger_cli",
|
||||
"trigger_nextcloud",
|
||||
"trigger_google",
|
||||
"trigger_github",
|
||||
"data_pipeline",
|
||||
"trigger_amqp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "0cc6770a81ecaecafe0d9b7100f94b329c4ec7978b016af4c964415e0c38396c"
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT permissioned_as, permissioned_as_email FROM v2_job\n WHERE id = $1 AND workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "permissioned_as",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "permissioned_as_email",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0d10e0fa5cf4033c7d93c9ed56be8209046007917f44da954eccf2188e5bff1f"
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE draft\n SET path = $3,\n -- Both path keys, not just the typed one: the editors mirror the\n -- typed path into the other while it differs from the row's path,\n -- and the loaders prefer the mirror — left naming the old location\n -- it un-does this move on the next save. `create_missing = false`\n -- on both, so a draft carrying only one keeps only one.\n value = to_json(\n jsonb_set(\n jsonb_set(\n CASE WHEN $7::text IS NULL THEN to_jsonb(value)\n ELSE jsonb_set(to_jsonb(value), ARRAY['summary'], to_jsonb($7::text))\n END,\n ARRAY[$5::text], to_jsonb($3::text), false\n ),\n ARRAY[$8::text], to_jsonb($3::text), false\n )\n )\n WHERE workspace_id = $1\n AND path = $2\n AND typ = $4\n AND email = $6\n -- A pre-sanitizer NUL escape makes `to_jsonb` raise 22P05. Excluded\n -- here so the statement can't 500; reported below instead. Unlike the\n -- passive carry, rewriting the value IS this operation, so skipping it\n -- silently would move the row and leave its typed path stale.\n AND position(chr(92) || 'u0000' in replace(value::text, chr(92) || chr(92), '')) = 0\n -- Skipped on a summary-only edit, where the \"target\" row is this\n -- row and the guard would refuse the update against itself.\n AND ($2 = $3 OR NOT EXISTS (\n SELECT 1 FROM draft o\n WHERE o.workspace_id = $1 AND o.path = $3 AND o.typ::text = ANY($9::text[])\n -- Of this kind only the caller's own row and the legacy one collide:\n -- teammates' drafts of one item share its path by design, but a deploy\n -- there wipes those two together, so a second would discard edits the\n -- caller never saw. The other app kind is a different item on the same\n -- deployed path, so it collides whoever owns it.\n AND (o.typ <> $4 OR o.email = $6 OR o.email IS NULL)\n ))\n RETURNING id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
{
|
||||
"Custom": {
|
||||
"name": "draft_kind",
|
||||
"kind": {
|
||||
"Enum": [
|
||||
"script",
|
||||
"flow",
|
||||
"app",
|
||||
"raw_app",
|
||||
"resource",
|
||||
"variable",
|
||||
"trigger_schedule",
|
||||
"trigger_webhook",
|
||||
"trigger_default_email",
|
||||
"trigger_email",
|
||||
"trigger_http",
|
||||
"trigger_websocket",
|
||||
"trigger_postgres",
|
||||
"trigger_kafka",
|
||||
"trigger_nats",
|
||||
"trigger_mqtt",
|
||||
"trigger_sqs",
|
||||
"trigger_gcp",
|
||||
"trigger_azure",
|
||||
"trigger_poll",
|
||||
"trigger_cli",
|
||||
"trigger_nextcloud",
|
||||
"trigger_google",
|
||||
"trigger_github",
|
||||
"data_pipeline",
|
||||
"trigger_amqp"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"TextArray"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0d9a83d77632bc0de19a48eddb7e6f80b2a41db4f1d352920d0c295ea3a018b1"
|
||||
}
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO datatable_migrations (workspace_id, datatable, timestamp, name, code_up, code_down) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (workspace_id, datatable, timestamp) DO UPDATE SET name = EXCLUDED.name, code_up = EXCLUDED.code_up, code_down = EXCLUDED.code_down WHERE NOT $7 OR (datatable_migrations.name = $8::text AND datatable_migrations.code_up = $9::text AND datatable_migrations.code_down IS NOT DISTINCT FROM $10::text)",
|
||||
"query": "INSERT INTO datatable_migrations (workspace_id, datatable, timestamp, name, code_up, code_down) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (workspace_id, datatable, timestamp) DO UPDATE SET name = EXCLUDED.name, code_up = EXCLUDED.code_up, code_down = EXCLUDED.code_down WHERE datatable_migrations.name = $7::text AND datatable_migrations.code_up = $8::text AND datatable_migrations.code_down IS NOT DISTINCT FROM $9::text",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -11,7 +11,6 @@
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Text",
|
||||
"Bool",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
@@ -19,5 +18,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2b93351b9c2c91272c3f69c9c8eba192d2e4d087c7d7db8d3b257bb864c8265d"
|
||||
"hash": "0f374865faa5bdf884345808a004ce891a85daa00e037aba4b65b60f87243bd3"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft_move WHERE email = $1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "11af34e5fe5b8ed59453d58628ed5fb3b2120835158f22d715b73460f6a55108"
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO remote_deploy_token\n (workspace_id, email, base_url, remote_workspace_id, token, remote_email, proxy_key,\n connected_at, member_since, target_changed_at)\n SELECT $1, $2, $3, $4, $5, $6, $7, $8, $9, $10\n WHERE $9::timestamptz IS NOT NULL\n OR EXISTS (SELECT 1 FROM token WHERE token_hash = $11)\n ON CONFLICT (workspace_id, email) DO UPDATE SET\n base_url = EXCLUDED.base_url, remote_workspace_id = EXCLUDED.remote_workspace_id,\n token = EXCLUDED.token, remote_email = EXCLUDED.remote_email,\n proxy_key = EXCLUDED.proxy_key, connected_at = EXCLUDED.connected_at,\n member_since = EXCLUDED.member_since, target_changed_at = EXCLUDED.target_changed_at\n WHERE remote_deploy_token.connected_at < EXCLUDED.connected_at\n RETURNING connected_at",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "connected_at",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Timestamptz",
|
||||
"Timestamptz",
|
||||
"Timestamptz",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "132bab72036874c33805ff194fce6641817d09528f9d1b7210abe9881b817710"
|
||||
}
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT s.hash as hash, dm.deployment_msg as deployment_msg, s.created_at as created_at\n FROM script s LEFT JOIN deployment_metadata dm ON s.hash = dm.script_hash\n WHERE s.workspace_id = $1 AND s.path = $2\n ORDER by s.created_at DESC",
|
||||
"query": "SELECT s.hash as hash, dm.deployment_msg as deployment_msg, s.created_at as created_at, s.created_by as created_by\n FROM script s LEFT JOIN deployment_metadata dm ON s.hash = dm.script_hash\n WHERE s.workspace_id = $1 AND s.path = $2\n ORDER by s.created_at DESC LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -17,6 +17,11 @@
|
||||
"ordinal": 2,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -28,8 +33,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "9a1483a81f5b086e0765d3d69483e29b09f66090e1f9d394564c16d921d2e66c"
|
||||
"hash": "148fbee57c6abbb6f361818c5b6bfc8a1db451d31dfddbb5be945b3551c8becb"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT remote_deploy_target FROM workspace_settings WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "remote_deploy_target",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "14cef81d324504d9cc90a9ffeb9f73daf9e09cac11685988bc861cc348a0c518"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE v2_job_queue q SET scheduled_for = now()\n FROM (SELECT id, scheduled_for FROM v2_job_queue WHERE id = $1 AND workspace_id = $2 FOR UPDATE) prev\n WHERE q.id = prev.id AND NOT q.running AND q.suspend = 0 AND q.canceled_by IS NULL\n AND q.scheduled_for > now()\n RETURNING prev.scheduled_for",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "scheduled_for",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1740f8bd6f9e084a470a775151e751e1317e7398dfaf1dfde5c57169cc146c9d"
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT a.id as app_id, av.id as version_id, dm.deployment_msg as deployment_msg,\n av.created_by as created_by, av.created_at as created_at\n FROM app a\n JOIN LATERAL (\n SELECT av2.id, COALESCE(v.ord, 0) AS ord\n FROM app_version av2\n LEFT JOIN unnest(a.versions) WITH ORDINALITY AS v(id, ord) ON v.id = av2.id\n WHERE av2.app_id = a.id\n ORDER BY ord DESC, av2.id DESC\n LIMIT $3 OFFSET $4\n ) page ON TRUE\n JOIN app_version av ON av.id = page.id\n LEFT JOIN deployment_metadata dm ON av.id = dm.app_version\n WHERE a.workspace_id = $1 AND a.path = $2\n ORDER BY page.ord DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "app_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "version_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "deployment_msg",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "18b38efcb141101192b372e7d7e7e47481877f3ab717682f3b84e665c95a5214"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "WITH legacy AS (\n DELETE FROM draft\n WHERE workspace_id = $1 AND path = $2 AND typ = $3 AND email IS NULL\n RETURNING value\n )\n INSERT INTO draft (workspace_id, email, path, typ, value, created_at)\n SELECT $1, $4, $2, $3, value, now() FROM legacy\n ON CONFLICT (workspace_id, path, typ, email) WHERE email IS NOT NULL\n DO UPDATE SET value = EXCLUDED.value, created_at = now()\n RETURNING 1 as \"one!\"",
|
||||
"query": "WITH legacy AS (\n DELETE FROM draft\n WHERE workspace_id = $1 AND path = $2 AND typ = $3 AND email IS NULL\n RETURNING value, base\n )\n INSERT INTO draft (workspace_id, email, path, typ, value, created_at, base)\n SELECT $1, $4, $2, $3, value, now(), base FROM legacy\n ON CONFLICT (workspace_id, path, typ, email) WHERE email IS NOT NULL\n DO UPDATE SET value = EXCLUDED.value, created_at = now(), base = EXCLUDED.base\n RETURNING 1 as \"one!\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -55,5 +55,5 @@
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "46f00a75b2e7e4ac70758a9687070f68bc0421f1aa228f80157adda63191d33b"
|
||||
"hash": "1c6859291963a9ca38d73f500213a575bfcd4469524f0dc8812470737759f02b"
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO workspace_settings (workspace_id, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, git_credentials, ducklake, dbt_warehouses, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler, public_app_execution_limit_per_minute, error_handler_fallback_to_instance_alerts, guest_access_enabled, guest_jwt_public_key, guest_jwt_jwks_url) SELECT $1, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, git_credentials, ducklake, dbt_warehouses, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler, public_app_execution_limit_per_minute, error_handler_fallback_to_instance_alerts, guest_access_enabled, guest_jwt_public_key, guest_jwt_jwks_url FROM workspace_settings WHERE workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "1d8ccd32266637d7f7915f92a8483dce0c9986f3847227c2f66daa84d4109d7d"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE remote_deploy_token SET token = $1\n WHERE workspace_id = $2 AND email = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "207db6c65949b85fda6d6289921bb04695b1c50e17755dad3bd162254f67458f"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO draft_move (workspace_id, typ, old_path, new_path, email)\n SELECT m.workspace_id, m.typ, m.old_path, $4, $5::text\n FROM draft_move m\n WHERE m.workspace_id = $1 AND m.typ::text = ANY($2::text[])\n AND m.new_path = $3 AND m.email IS NULL\n AND NOT EXISTS (\n SELECT 1 FROM draft_move o\n WHERE o.workspace_id = m.workspace_id AND o.typ = m.typ\n AND o.old_path = m.old_path AND o.email = $5::text\n )",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "232ff36c2d522383061cafbf9639698dbc44a18c0f016aae94a1705f06fd1e48"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings ws\n SET datatable = (\n SELECT jsonb_set(ws.datatable, '{datatables}', jsonb_object_agg(\n dt.key,\n CASE WHEN dt.value->'reference'->>'workspace_id' = $2\n THEN jsonb_set(dt.value, '{reference,workspace_id}', to_jsonb($1::text))\n ELSE dt.value END\n ))\n FROM jsonb_each(ws.datatable->'datatables') dt\n )\n WHERE jsonb_typeof(ws.datatable->'datatables') = 'object'\n AND ws.datatable::text LIKE '%\"reference\"%'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "297c7a40dfce729d44aa37bc7c65560517bd25e40c0752a00467829191e2eb98"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE capture_config SET server_id = NULL, last_server_ping = NULL\n WHERE workspace_id = $1 AND trigger_kind = 'postgres'\n AND (trigger_config->>'postgres_resource_path' = $2\n OR trigger_config->>'postgres_resource_path' LIKE $3)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2a391cc1bfcd2f75b46144a394c01237e09c3060da88170f1f6e06468309d213"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO usr (workspace_id, username, email, is_admin, created_at, operator, disabled, role, is_service_account, added_via)\n SELECT $1, username, email, is_admin, created_at, operator, disabled, role, is_service_account,\n CASE WHEN $3 THEN NULL ELSE added_via END\n FROM usr WHERE workspace_id = $2\n AND (NOT $3 OR (NOT operator AND NOT disabled AND NOT is_service_account))\n ON CONFLICT DO NOTHING",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Bool"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2d6b117324eaf076a0ed06d2cb0ce73279957d6a39fdc6b1ecb6e0a1e02f921f"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT add_admins_and_developers_to_forks FROM workspace_settings WHERE workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "add_admins_and_developers_to_forks",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "2f39fce0ee700117f3e4c066e0b56ee979e4c392970278304e80368b770bb7b4"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT COUNT(DISTINCT email) FROM usr WHERE is_service_account AND NOT disabled",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "count",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "3190736818379ad22628aae3c5a25ab0199084b35664cbb0a586917bfa0da075"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = $1)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "exists",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Name"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "334dbcd48fb59c96c62c2705ab2d1ce716cd52417f487cc1a8dd376017b2db7d"
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "WITH all_audit AS (SELECT username, operation, timestamp FROM audit_partitioned UNION ALL SELECT username, operation, timestamp FROM audit),\n active_users as (SELECT distinct username as email FROM all_audit WHERE timestamp > NOW() - INTERVAL '1 month' AND (operation = 'users.login' OR operation = 'oauth.login' OR operation = 'users.token.refresh')),\n active_authors as (SELECT distinct email FROM usr WHERE usr.operator IS false AND email IN (SELECT email FROM active_users)),\n active_authors_agg as (SELECT array_agg(email) as authors FROM active_authors),\n active_ops_agg as (SELECT array_agg(email) as operators from active_users WHERE email NOT IN (SELECT email FROM active_authors))\n SELECT active_authors_agg.authors, active_ops_agg.operators, array_length(active_authors_agg.authors, 1) as author_count, array_length(active_ops_agg.operators, 1) as operator_count FROM active_authors_agg, active_ops_agg",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "authors",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "operators",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "author_count",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "operator_count",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "359cd29f531d263a8cf7205e0869229a610767087f01e0154be8da0620fa114b"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT EXISTS(SELECT 1 FROM v2_job_queue WHERE id = $1 AND workspace_id = $2)",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "exists",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "372db51a00e5cf37f00af4b7962b30d71c74fffbba3f5ac6197c985fd73e5c11"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO draft_move (workspace_id, typ, old_path, new_path, email)\n SELECT $1, t::draft_kind, $3, $4, $5 FROM unnest($2::text[]) t",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"TextArray",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3a015ab279785a15f89c89d8c4d155e85370d4c2b7ed14fbb510919e7624ca1c"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM token WHERE token_prefix = 'GONE_TOKEN'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3a0ac41e645225bbe54b83f246500ca014154e76eb322646e7e4e753b6420acd"
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT email, token FROM remote_deploy_token\n WHERE workspace_id = $1 AND token <> '' FOR UPDATE",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "token",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3b6f1e9765de11ef2da0ec5388c72e4a01f50d48b76b90746eef72919c408e44"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE draft_move SET new_path = $4\n WHERE workspace_id = $1 AND typ::text = ANY($2::text[])\n AND new_path = $3 AND ($5::text IS NULL OR email = $5)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3db5f1d8ec1f8d867cf01c066876122e78f0c76a93a1d9860e8dff05d9a02c09"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE postgres_trigger SET server_id = NULL, last_server_ping = NULL\n WHERE workspace_id = $1\n AND (postgres_resource_path = $2 OR postgres_resource_path LIKE $3)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "4692810d2be817bbb5de9b476d68d695941bd4fb5ccef393e4da522ed479d601"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE schedule SET\n schedule = $1,\n timezone = $2,\n args = $3,\n on_failure = $4,\n on_failure_times = $5,\n on_failure_exact = $6,\n on_failure_extra_args = $7,\n on_recovery = $8,\n on_recovery_times = $9,\n on_recovery_extra_args = $10,\n on_success = $11,\n on_success_extra_args = $12,\n ws_error_handler_muted = $13,\n retry = $14,\n summary = $15,\n no_flow_overlap = $16,\n tag = $17,\n paused_until = $18,\n path = $19,\n workspace_id = $20,\n cron_version = COALESCE($21, cron_version),\n description = $22,\n dynamic_skip = $23,\n email = $24,\n edited_by = $25,\n permissioned_as = $26,\n labels = COALESCE($27, labels)\n WHERE path = $19 AND workspace_id = $20\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip,\n labels\n ",
|
||||
"query": "\n UPDATE schedule SET\n schedule = $1,\n timezone = $2,\n args = $3,\n on_failure = $4,\n on_failure_times = $5,\n on_failure_exact = $6,\n on_failure_extra_args = $7,\n on_recovery = $8,\n on_recovery_times = $9,\n on_recovery_extra_args = $10,\n on_success = $11,\n on_success_extra_args = $12,\n ws_error_handler_muted = $13,\n retry = $14,\n summary = $15,\n no_flow_overlap = $16,\n tag = $17,\n paused_until = $18,\n path = $19,\n workspace_id = $20,\n cron_version = COALESCE($21, cron_version),\n description = $22,\n dynamic_skip = $23,\n email = $24,\n edited_by = $25,\n edited_at = now(),\n permissioned_as = $26,\n labels = COALESCE($27, labels)\n WHERE path = $19 AND workspace_id = $20\n RETURNING\n workspace_id,\n path,\n edited_by,\n edited_at,\n schedule,\n timezone,\n enabled,\n script_path,\n is_flow,\n args AS \"args: _\",\n extra_perms,\n email,\n permissioned_as,\n error,\n on_failure,\n on_failure_times,\n on_failure_exact,\n on_failure_extra_args AS \"on_failure_extra_args: _\",\n on_recovery,\n on_recovery_times,\n on_recovery_extra_args AS \"on_recovery_extra_args: _\",\n on_success,\n on_success_extra_args AS \"on_success_extra_args: _\",\n ws_error_handler_muted,\n retry,\n no_flow_overlap,\n summary,\n description,\n tag,\n paused_until,\n cron_version,\n dynamic_skip,\n labels\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -236,5 +236,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "bd2609f999054c5a2a85f2aafe4005bc22731c27f0bf27b3b06ec426a05eda2e"
|
||||
"hash": "4d2c91937d87d385290b918af0238825cdd7784d0d611cd0069b15d11039ac56"
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT ws.workspace_id AS \"workspace_id!\", dt.key AS \"datatable!\"\n FROM workspace_settings ws\n CROSS JOIN LATERAL jsonb_each(COALESCE(ws.datatable->'datatables', '{}'::jsonb)) dt\n WHERE dt.value->'reference'->>'workspace_id' = $1\n AND dt.value->'reference'->>'datatable' = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id!",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "datatable!",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "5048e21546f9710697100100e1255ab103979433bc386d7c89d0e30db12bfd57"
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT clock_timestamp() AS \"started_at!\", s.remote_deploy_target,\n s.remote_deploy_target_changed_at,\n (SELECT u.created_at FROM usr u\n WHERE u.workspace_id = s.workspace_id AND u.email = $2) AS member_since\n FROM workspace_settings s WHERE s.workspace_id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "started_at!",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "remote_deploy_target",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "remote_deploy_target_changed_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "member_since",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "51e1741eb9e959945302fd6f7e8c621b9b03b92f6c20ab1bdd1637232f26952d"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO token (token_hash, token_prefix, token, email, label, super_admin, read_only)\n VALUES (encode(sha256('READ_ONLY_TOKEN'::bytea), 'hex'), 'READ_ONLY_', 'READ_ONLY_TOKEN',\n 'test@windmill.dev', 'read only', false, true)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "530fe81babd82e7b4a9142962c62750560e459acc7c83c48d47d7bdad29051be"
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT ws.workspace_id AS \"workspace_id!\", dt.key AS \"datatable!\"\n FROM workspace_settings ws\n CROSS JOIN LATERAL jsonb_each(COALESCE(ws.datatable->'datatables', '{}'::jsonb)) dt\n WHERE dt.value->'reference'->>'workspace_id' = $1\n AND dt.value->'reference'->>'datatable' = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id!",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "datatable!",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "538dd1779874e4003932d7f17750239c625f85e25b3364bf2edf566f518c8ee2"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings SET remote_deploy_target_changed_at = '2000-01-01'\n WHERE workspace_id = 'test-workspace'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "5517b714165f959a1df1a0ac9cbe848344974bc2271459ba4ae5952274c11429"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT username FROM usr WHERE workspace_id = $1 AND email = $2 AND disabled = false",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "username",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "58e5cfe9eb87bda9f7de87c403861b6e7b9d35a41594681e2a92a87359e6a018"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft_move dest\n WHERE dest.email = $1\n AND EXISTS (SELECT 1 FROM draft_move src\n WHERE src.email = $2\n AND src.workspace_id = dest.workspace_id\n AND src.old_path = dest.old_path\n AND src.typ = dest.typ)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "5959c60da91f1e62080a4455e2a4627cb1fd3d8c70210bf7f38cb222dd15d88f"
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT t.token, t.remote_email, t.proxy_key, t.connected_at FROM remote_deploy_token t\n JOIN workspace_settings s ON s.workspace_id = t.workspace_id\n WHERE t.workspace_id = $1 AND t.email = $2 AND t.base_url = $3\n AND t.remote_workspace_id = $4 AND t.token <> ''\n AND s.remote_deploy_target_changed_at IS NOT DISTINCT FROM t.target_changed_at\n AND (EXISTS (SELECT 1 FROM usr u WHERE u.workspace_id = t.workspace_id\n AND u.email = t.email AND u.created_at = t.member_since)\n OR EXISTS (SELECT 1 FROM password p WHERE p.email = t.email AND p.super_admin))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "remote_email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "proxy_key",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "connected_at",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "5b292c49ce6b64f4de61f74e18831b3f107fc6d0312ac3da9247a922bcb05b67"
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n UPDATE workspace_settings\n SET\n ai_config = source_ws.ai_config,\n large_file_storage = source_ws.large_file_storage,\n ducklake = source_ws.ducklake,\n dbt_warehouses = source_ws.dbt_warehouses,\n datatable = source_ws.datatable,\n git_app_installations = source_ws.git_app_installations\n FROM workspace_settings source_ws\n WHERE source_ws.workspace_id = $1\n AND workspace_settings.workspace_id = $2\n ",
|
||||
"query": "\n UPDATE workspace_settings\n SET\n ai_config = source_ws.ai_config,\n large_file_storage = source_ws.large_file_storage,\n ducklake = source_ws.ducklake,\n dbt_warehouses = source_ws.dbt_warehouses,\n datatable = source_ws.datatable,\n git_app_installations = source_ws.git_app_installations,\n add_admins_and_developers_to_forks = source_ws.add_admins_and_developers_to_forks\n FROM workspace_settings source_ws\n WHERE source_ws.workspace_id = $1\n AND workspace_settings.workspace_id = $2\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -11,5 +11,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a6decdebcd9750691f20f874b66a9c6f2ede08c33605c6a3c3dfc213a3eda76a"
|
||||
"hash": "5ccfbd0f345b9b86ca356008def6cc1011a49fc8d8ad046ac572e81cf8938995"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO remote_deploy_token\n (workspace_id, email, base_url, remote_workspace_id, token, remote_email, proxy_key,\n connected_at)\n VALUES ($1, $2, '', '', '', '', '', clock_timestamp())\n ON CONFLICT (workspace_id, email) DO UPDATE SET\n token = '', proxy_key = '', connected_at = clock_timestamp()",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6b58f2df413a867a44311fd779a2017c41b9a0e3985a25372e5f64723124e473"
|
||||
}
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM token_expiry_notification n\n USING token t\n WHERE n.token_hash = t.token_hash\n AND n.expiration > now()\n AND n.expiration <= now() + interval '7 days'\n RETURNING t.token_prefix, t.label, t.email, t.workspace_id",
|
||||
"query": "DELETE FROM token_expiry_notification n\n USING token t\n WHERE n.token_hash = t.token_hash\n AND n.expiration > now()\n AND n.expiration <= now() + make_interval(days => $1)\n RETURNING t.token_prefix, t.label, t.email, t.workspace_id",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -25,7 +25,9 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
"Left": [
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
@@ -34,5 +36,5 @@
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "94fd0a57cfc9341b2e9deae60506c6c06aa6934b87200da14231f12f65149cd3"
|
||||
"hash": "6c57c46c5a0462f379ed6a22ae97e363009177fdc45d795447a920f455f193cc"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO global_settings (name, value) VALUES ($1, $2)\n ON CONFLICT (name) DO UPDATE SET value = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6f9fb5d72f486358fa25d6887bd69b93910e028f140c07048f2c1c8d63ee6909"
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n WITH capped AS (\n SELECT timestamp, operation, resource, parameters\n FROM audit_partitioned\n WHERE workspace_id = 'admins'\n AND operation = 'workspace_fairness.capped'\n UNION ALL\n SELECT timestamp, operation, resource, parameters\n FROM audit\n WHERE workspace_id = 'admins'\n AND operation = 'workspace_fairness.capped'\n ORDER BY timestamp DESC\n LIMIT 200\n ), uncapped AS (\n SELECT timestamp, operation, resource, parameters\n FROM audit_partitioned\n WHERE workspace_id = 'admins'\n AND operation = 'workspace_fairness.uncapped'\n UNION ALL\n SELECT timestamp, operation, resource, parameters\n FROM audit\n WHERE workspace_id = 'admins'\n AND operation = 'workspace_fairness.uncapped'\n ORDER BY timestamp DESC\n LIMIT 200\n )\n SELECT timestamp AS \"timestamp!\",\n operation::text AS \"operation!\",\n resource AS workspace_id,\n parameters\n FROM (SELECT * FROM capped UNION ALL SELECT * FROM uncapped) e\n ORDER BY timestamp DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "timestamp!",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "operation!",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "workspace_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "parameters",
|
||||
"type_info": "Jsonb"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "6fcdb09cdd7fedd7e54fdc0e49203f453fc1b85272fe212c0e1bf0ebd28bf58a"
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT id, name, enabled, pwd FROM datatable_role",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "enabled",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "pwd",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "71ee2cb6661cca1fa4d8874a7f6d368347c59f36fd87df6dc7996152ccb84af0"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT EXISTS(SELECT 1 FROM usr WHERE email = $1 AND is_service_account IS true\n AND ($2::varchar IS NULL OR workspace_id = $2))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "exists",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "75e6b5cd52d63ac094c90abd1524bc7a919692a96b076b8aaf24d812723531c8"
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO draft (workspace_id, email, path, typ, value, created_at, base)\n VALUES ($1, $2, $3::text, $4,\n CASE WHEN $10::bool\n THEN to_json($5::text::jsonb || jsonb_strip_nulls(jsonb_build_object(\n 'path', CASE WHEN $5::text::jsonb -> 'path' = to_jsonb($11::text)\n THEN to_jsonb($3::text) END,\n 'draft_path', CASE WHEN $5::text::jsonb -> 'draft_path' = to_jsonb($11::text)\n THEN to_jsonb($3::text) END)))\n ELSE $5::text::json\n END,\n COALESCE($8::timestamptz, now()), $9)\n ON CONFLICT (workspace_id, path, typ, email) WHERE email IS NOT NULL\n DO UPDATE SET value = CASE\n WHEN NOT $10::bool\n OR position(chr(92) || 'u0000' in replace(draft.value::text, chr(92) || chr(92), '')) > 0\n THEN EXCLUDED.value\n ELSE to_json((to_jsonb(EXCLUDED.value) - 'path' - 'draft_path')\n || jsonb_strip_nulls(jsonb_build_object(\n 'path', to_jsonb(draft.value) -> 'path',\n 'draft_path', to_jsonb(draft.value) -> 'draft_path')))\n END,\n created_at = EXCLUDED.created_at,\n base = EXCLUDED.base\n WHERE $7::bool = true\n OR $6::timestamptz IS NULL\n OR draft.created_at <= $6::timestamptz\n RETURNING path, created_at",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "path",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text",
|
||||
{
|
||||
"Custom": {
|
||||
"name": "draft_kind",
|
||||
"kind": {
|
||||
"Enum": [
|
||||
"script",
|
||||
"flow",
|
||||
"app",
|
||||
"raw_app",
|
||||
"resource",
|
||||
"variable",
|
||||
"trigger_schedule",
|
||||
"trigger_webhook",
|
||||
"trigger_default_email",
|
||||
"trigger_email",
|
||||
"trigger_http",
|
||||
"trigger_websocket",
|
||||
"trigger_postgres",
|
||||
"trigger_kafka",
|
||||
"trigger_nats",
|
||||
"trigger_mqtt",
|
||||
"trigger_sqs",
|
||||
"trigger_gcp",
|
||||
"trigger_azure",
|
||||
"trigger_poll",
|
||||
"trigger_cli",
|
||||
"trigger_nextcloud",
|
||||
"trigger_google",
|
||||
"trigger_github",
|
||||
"data_pipeline",
|
||||
"trigger_amqp"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Text",
|
||||
"Timestamptz",
|
||||
"Bool",
|
||||
"Timestamptz",
|
||||
"Text",
|
||||
"Bool",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7761959d05fff8c314d04c1bc9fb4e84a61008dbec0995ae192f1b3a1c261579"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft_move\n WHERE workspace_id = $1 AND typ::text = ANY($2::text[])\n AND old_path IN ($3, $4) AND ($5::text IS NULL OR email = $5)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "797896e0152046844dbfee9d0e57e0055d742e44119bfb31ae7ff37a89b34d14"
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT ws.workspace_id AS \"workspace_id!\", dt.key AS \"datatable!\"\n FROM workspace_settings ws\n JOIN workspace w ON w.id = ws.workspace_id AND w.deleted = false\n CROSS JOIN LATERAL jsonb_each(COALESCE(ws.datatable->'datatables', '{}'::jsonb)) dt\n WHERE ws.workspace_id <> $1\n AND dt.value->'database'->>'resource_type' = 'instance'\n AND dt.value->'database'->>'resource_path' = $2\n ORDER BY ws.workspace_id, dt.key\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "workspace_id!",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "datatable!",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "79799b5a2e499df6c28e286c42b9ad2db940c2455ab19cc95e5198baf96d5629"
|
||||
}
|
||||
+8
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT workspace.id, workspace.name, usr.username, workspace_settings.color, workspace.parent_workspace_id,\n workspace.is_dev_workspace, workspace.dev_workspace_label,\n workspace.owner AS \"created_by?\",\n CASE WHEN usr.operator THEN workspace_settings.operator_settings ELSE NULL END as operator_settings,\n usr.disabled\n FROM workspace\n JOIN usr ON usr.workspace_id = workspace.id\n JOIN workspace_settings ON workspace_settings.workspace_id = workspace.id\n WHERE usr.email = $1 AND workspace.deleted = false",
|
||||
"query": "SELECT workspace.id, workspace.name, usr.username, workspace_settings.color, workspace.parent_workspace_id,\n workspace.is_dev_workspace, workspace.dev_workspace_label,\n workspace.owner AS \"created_by?\",\n CASE WHEN usr.operator THEN workspace_settings.operator_settings ELSE NULL END as operator_settings,\n usr.disabled, usr.is_service_account\n FROM workspace\n JOIN usr ON usr.workspace_id = workspace.id\n JOIN workspace_settings ON workspace_settings.workspace_id = workspace.id\n WHERE usr.email = $1 AND workspace.deleted = false",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -52,6 +52,11 @@
|
||||
"ordinal": 9,
|
||||
"name": "disabled",
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "is_service_account",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -69,8 +74,9 @@
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "88a134e4ca82d5ce0334977c7713021ae3e99a5a61ea1c944c1df1368746dfa5"
|
||||
"hash": "7b33adb5cf051bc123340982b97a80a96ee43e1c91d9907d50cc2ee14111623e"
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT flow_version.id, flow_version.created_at, flow_version.created_by, deployment_metadata.deployment_msg FROM flow_version\n LEFT JOIN deployment_metadata ON flow_version.id = deployment_metadata.flow_version\n WHERE flow_version.path = $1 AND flow_version.workspace_id = $2\n ORDER BY flow_version.created_at DESC\n LIMIT $3 OFFSET $4",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "deployment_msg",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "7ff60d155510303e307c47dcb6153ccaac72871eb68822d8e296c0d747e55f35"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM remote_deploy_token WHERE workspace_id = $1\n AND ($2::text IS NULL OR base_url <> $2 OR remote_workspace_id <> $3)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "81d5cceb2e405e1d17730dfa93a32f1bca7b235af9db581147d838454a4c9083"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO datatable_role (id, name, enabled, pwd) VALUES ($1, $2, $3, $4)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Bool",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "86af9d51a158ea5cb6161461ecddf2a63695f8cbf8af648da5a0a77a5b9d02ba"
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO draft (workspace_id, path, typ, value, created_at, email)\n SELECT $2, path, typ,\n CASE WHEN typ IN ('script', 'flow')\n THEN to_json(to_jsonb(value) - 'on_behalf_of')\n ELSE value END,\n created_at, email\n FROM draft\n WHERE workspace_id = $1 AND (email = $3 OR email IS NULL)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "87afd5289e54b6accda8a399ec3c66df3d19217059f62903be3c74eadb9c15d5"
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE remote_deploy_token SET token = $1 WHERE workspace_id = 'test-workspace'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8ce4461e7dd087782a239972c173786891eb99e9ba86b11cfb17d28856babd2e"
|
||||
}
|
||||
+9
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT\n workspace_id,\n slack_team_id,\n teams_team_id,\n teams_team_name,\n teams_team_guid,\n slack_name,\n slack_command_script,\n teams_command_script,\n slack_email,\n slack_oauth_client_id,\n slack_oauth_client_secret,\n customer_id,\n plan,\n webhook,\n ai_config,\n dbt_warehouses,\n large_file_storage,\n datatable,\n ducklake,\n git_sync,\n deploy_ui,\n default_app,\n default_scripts,\n mute_critical_alerts,\n color,\n operator_settings,\n git_app_installations,\n auto_invite,\n error_handler,\n success_handler,\n public_app_execution_limit_per_minute,\n error_handler_fallback_to_instance_alerts,\n guest_access_enabled,\n guest_jwt_public_key,\n guest_jwt_jwks_url\n FROM\n workspace_settings\n WHERE\n workspace_id = $1\n ",
|
||||
"query": "\n SELECT\n workspace_id,\n slack_team_id,\n teams_team_id,\n teams_team_name,\n teams_team_guid,\n slack_name,\n slack_command_script,\n teams_command_script,\n slack_email,\n slack_oauth_client_id,\n slack_oauth_client_secret,\n customer_id,\n plan,\n webhook,\n ai_config,\n dbt_warehouses,\n large_file_storage,\n datatable,\n ducklake,\n git_sync,\n deploy_ui,\n default_app,\n default_scripts,\n mute_critical_alerts,\n color,\n operator_settings,\n git_app_installations,\n auto_invite,\n error_handler,\n success_handler,\n public_app_execution_limit_per_minute,\n error_handler_fallback_to_instance_alerts,\n guest_access_enabled,\n guest_jwt_public_key,\n guest_jwt_jwks_url,\n add_admins_and_developers_to_forks\n FROM\n workspace_settings\n WHERE\n workspace_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -177,6 +177,11 @@
|
||||
"ordinal": 34,
|
||||
"name": "guest_jwt_jwks_url",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 35,
|
||||
"name": "add_admins_and_developers_to_forks",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -219,8 +224,9 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "dc4a57df3becc610f631ef22c116450390addbfae85fecc61c991d94167e6e99"
|
||||
"hash": "8ebe054b41793f1a7b85f1f8d29cd21d12fa1207b58bfc46249c250cdcdb5363"
|
||||
}
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM datatable_migrations WHERE workspace_id = $1 AND datatable = $2 AND timestamp = $3 RETURNING name",
|
||||
"query": "DELETE FROM datatable_migrations WHERE workspace_id = $1 AND datatable = $2 AND timestamp = $3 AND code_up = $4 AND code_down IS NOT DISTINCT FROM $5 RETURNING name",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -13,12 +13,14 @@
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8"
|
||||
"Int8",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3c057e0284f1219865b8f7dc6eb3c1293c4b72d0b52abeefd1e954617984a2d8"
|
||||
"hash": "91e2456814ac29534f5a1f65a3bb97462276930f0a83ffb458f7cb26035c8c3d"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE remote_deploy_token SET workspace_id = $1 WHERE workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "960d6eca64de008f821b1e96345530f057d91c0e0986fdc0de7d9a3ef0c143e2"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE remote_deploy_token SET connected_at = clock_timestamp() + interval '1 hour'\n WHERE workspace_id = 'test-workspace' AND email = 'test@windmill.dev'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "965f9fb9d73f21695cf9c4018107bf8dec0a9b1c38a6776f8b3db7f2f8a883b7"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft_move WHERE workspace_id = $1 AND typ::text = ANY($2::text[])\n AND (old_path = $3 OR (new_path = $3 AND $4::text IS NULL))",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9723edfd6de38cf0bf21123a46d88fa7d0b650b5cfd80c099f785f5e411062e5"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO global_settings (name, value) VALUES ($1, $2)\n ON CONFLICT (name) DO UPDATE SET value = $2, updated_at = now()",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Jsonb"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "975e404ac3a6258bb8220e122e3de094c7ab23330fdbc74d6e4ad472ddd3c820"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE v2_job_completed SET status = 'canceled'::job_status, canceled_by = $2, canceled_reason = $3 WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9a2345e35c9f44578aa7dde994fdde0be9e0d192e0aee224bff78d8bd2ccbd8b"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings SET remote_deploy_target = $1::jsonb,\n remote_deploy_target_changed_at = CASE\n WHEN remote_deploy_target IS DISTINCT FROM $1::jsonb THEN clock_timestamp()\n ELSE remote_deploy_target_changed_at END\n WHERE workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Jsonb",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9b61979cc78e8b7b63ffa6a59cf3d29ae8b924200c46da457a9346379c60fa9f"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings SET add_admins_and_developers_to_forks = $1 WHERE workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Bool",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9bd1995747f0073b3a866d1238e78f7e6dfa9185056f7731547ff05b8176b271"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft_move\n WHERE workspace_id = $1 AND typ::text = ANY($2::text[])\n AND new_path = $4 AND old_path <> $3 AND ($5::text IS NULL OR email = $5)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"TextArray",
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9d1b202844e6935e636d1570a92d46af4419dda9410ffc46f19bc38e56efe609"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT pg_advisory_xact_lock(hashtext('datatable_role_catalog'))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "pg_advisory_xact_lock",
|
||||
"type_info": "Void"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "9f663180166f53d117e794f3f3a5723a0a43db163ecca7d5a63d4e74ab1d3be1"
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT flow_version.id, flow_version.created_at, deployment_metadata.deployment_msg FROM flow_version \n LEFT JOIN deployment_metadata ON flow_version.id = deployment_metadata.flow_version\n WHERE flow_version.path = $1 AND flow_version.workspace_id = $2 \n ORDER BY flow_version.created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "created_at",
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "deployment_msg",
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "a0f1c0df6bc2f1fbca50edee90e42c94445536e201b322eda6f7a90bdf38f36a"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "UPDATE workspace_settings SET auto_invite = (COALESCE(auto_invite, '{}'::jsonb) - 'domain') || $1::jsonb WHERE workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Jsonb",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a1bcf143135ecb9f32709a56a353d3246dc238920c3e155caa9cf767246fa6fb"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user