Compare commits

..

1 Commits

Author SHA1 Message Date
hcourdent
4067425342 Result node message 2024-11-15 16:32:38 +01:00
27 changed files with 113 additions and 215 deletions

View File

@@ -1,13 +1,5 @@
# Changelog
## [1.425.0](https://github.com/windmill-labs/windmill/compare/v1.424.0...v1.425.0) (2024-11-15)
### Features
* Handle `pip install` by `uv` ([#4517](https://github.com/windmill-labs/windmill/issues/4517)) ([f240d13](https://github.com/windmill-labs/windmill/commit/f240d1322a3c1669dfb69ebda6d05effcca26ae3))
* **monitoring:** workspace critical alerts ([#4684](https://github.com/windmill-labs/windmill/issues/4684)) ([c32038a](https://github.com/windmill-labs/windmill/commit/c32038a76d9d00703d8b865af72f083ac43414e3))
## [1.424.0](https://github.com/windmill-labs/windmill/compare/v1.423.2...v1.424.0) (2024-11-14)

52
backend/Cargo.lock generated
View File

@@ -1032,9 +1032,9 @@ dependencies = [
[[package]]
name = "axum"
version = "0.7.8"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49c41b948da08fb481a94546cd874843adc1142278b0af4badf9b1b78599d68d"
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
dependencies = [
"async-trait",
"axum-core",
@@ -10610,7 +10610,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windmill"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"axum",
@@ -10652,7 +10652,7 @@ dependencies = [
[[package]]
name = "windmill-api"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"argon2",
@@ -10737,7 +10737,7 @@ dependencies = [
[[package]]
name = "windmill-api-client"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"base64 0.22.1",
"chrono",
@@ -10755,7 +10755,7 @@ dependencies = [
[[package]]
name = "windmill-audit"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"chrono",
"serde",
@@ -10768,7 +10768,7 @@ dependencies = [
[[package]]
name = "windmill-autoscaling"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"rsmq_async",
@@ -10783,7 +10783,7 @@ dependencies = [
[[package]]
name = "windmill-common"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"async-stream",
@@ -10830,7 +10830,7 @@ dependencies = [
[[package]]
name = "windmill-git-sync"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"regex",
"rsmq_async",
@@ -10845,7 +10845,7 @@ dependencies = [
[[package]]
name = "windmill-indexer"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"bytes",
@@ -10867,7 +10867,7 @@ dependencies = [
[[package]]
name = "windmill-macros"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"itertools 0.13.0",
"lazy_static",
@@ -10879,7 +10879,7 @@ dependencies = [
[[package]]
name = "windmill-parser"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"convert_case 0.6.0",
"serde",
@@ -10888,7 +10888,7 @@ dependencies = [
[[package]]
name = "windmill-parser-bash"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -10900,7 +10900,7 @@ dependencies = [
[[package]]
name = "windmill-parser-go"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"gosyn",
@@ -10912,7 +10912,7 @@ dependencies = [
[[package]]
name = "windmill-parser-graphql"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -10924,7 +10924,7 @@ dependencies = [
[[package]]
name = "windmill-parser-php"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"itertools 0.13.0",
@@ -10935,7 +10935,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"itertools 0.13.0",
@@ -10946,7 +10946,7 @@ dependencies = [
[[package]]
name = "windmill-parser-py-imports"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"async-recursion",
@@ -10964,7 +10964,7 @@ dependencies = [
[[package]]
name = "windmill-parser-rust"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@@ -10981,7 +10981,7 @@ dependencies = [
[[package]]
name = "windmill-parser-sql"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -10993,7 +10993,7 @@ dependencies = [
[[package]]
name = "windmill-parser-ts"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"lazy_static",
@@ -11011,7 +11011,7 @@ dependencies = [
[[package]]
name = "windmill-parser-wasm"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"getrandom 0.2.15",
@@ -11032,7 +11032,7 @@ dependencies = [
[[package]]
name = "windmill-parser-yaml"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"serde_json",
@@ -11042,7 +11042,7 @@ dependencies = [
[[package]]
name = "windmill-queue"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"async-recursion",
@@ -11075,7 +11075,7 @@ dependencies = [
[[package]]
name = "windmill-sql-datatype-parser-wasm"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"wasm-bindgen",
"wasm-bindgen-test",
@@ -11085,7 +11085,7 @@ dependencies = [
[[package]]
name = "windmill-worker"
version = "1.425.0"
version = "1.424.0"
dependencies = [
"anyhow",
"async-recursion",

View File

@@ -1,6 +1,6 @@
[package]
name = "windmill"
version = "1.425.0"
version = "1.424.0"
authors.workspace = true
edition.workspace = true
@@ -29,7 +29,7 @@ members = [
]
[workspace.package]
version = "1.425.0"
version = "1.424.0"
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
edition = "2021"

View File

@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.425.0
version: 1.424.0
title: Windmill API
contact:

View File

@@ -32,6 +32,7 @@ pub const GIT_VERSION: &str =
use crate::CRITICAL_ALERT_MUTE_UI_ENABLED;
use std::sync::atomic::Ordering;
#[cfg(feature = "enterprise")]
use crate::worker::CLOUD_HOSTED;
lazy_static::lazy_static! {
@@ -275,7 +276,7 @@ pub async fn report_critical_error(
// we ack_global if mute_global is true, or if mute_workspace is true
// but we ignore global mute setting for ack_workspace
let acknowledge_workspace = mute_workspace;
let acknowledge_global = mute_global || mute_workspace || ( workspace_id.is_some() && *CLOUD_HOSTED);
let acknowledge_global = mute_global || mute_workspace;
if let Err(err) = sqlx::query!(
"INSERT INTO alerts (alert_type, message, acknowledged, acknowledged_workspace, workspace_id, resource)

View File

@@ -416,32 +416,24 @@ pub async fn do_postgresql(
}
fn map_as_single_type<T>(
vec: Option<&Vec<Value>>,
vec: &Vec<Value>,
f: impl Fn(&Value) -> Option<T>,
) -> anyhow::Result<Option<Vec<Option<T>>>> {
if let Some(vec) = vec {
Ok(Some(
vec.into_iter()
.map(|v| {
// first option is if the value is of the right type (if none, will stop the collection and throw error)
// second option is if the value is null
// allow nulls in arrays
if matches!(v, Value::Null) {
Some(None)
} else {
f(v).map(Some)
}
})
.collect::<Option<Vec<Option<T>>>>()
.ok_or_else(|| anyhow::anyhow!("Mixed types in array"))?,
))
} else {
Ok(None)
}
) -> anyhow::Result<Vec<Option<T>>> {
vec.into_iter()
.map(|v| {
// allow nulls in arrays
if matches!(v, Value::Null) {
Some(None)
} else {
f(v).map(Some)
}
})
.collect::<Option<Vec<Option<T>>>>()
.ok_or_else(|| anyhow::anyhow!("Mixed types in array"))
}
fn convert_vec_val(
vec: Option<&Vec<Value>>,
vec: &Vec<Value>,
arg_t: &String,
) -> windmill_common::error::Result<Box<dyn ToSql + Sync + Send>> {
match arg_t.as_str() {
@@ -497,9 +489,7 @@ fn convert_vec_val(
.unwrap_or_default()
})
})?)),
"jsonb" | "json" => Ok(Box::new(
vec.map(|v| v.clone().into_iter().map(Some).collect_vec()),
)),
"jsonb" | "json" => Ok(Box::new(vec.clone().into_iter().map(Some).collect_vec())),
"bytea" => Ok(Box::new(map_as_single_type(vec, |v| {
v.as_str().map(|x| {
engine::general_purpose::STANDARD
@@ -522,32 +512,9 @@ fn convert_val(
match value {
Value::Array(vec) if arg_t.ends_with("[]") => {
let arg_t = arg_t.trim_end_matches("[]").to_string();
convert_vec_val(Some(vec), &arg_t)
convert_vec_val(vec, &arg_t)
}
Value::Null if arg_t.ends_with("[]") => {
let arg_t = arg_t.trim_end_matches("[]").to_string();
convert_vec_val(None, &arg_t)
}
Value::Null => match arg_t.as_str() {
"bool" | "boolean" => Ok(Box::new(None::<bool>)),
"char" | "character" => Ok(Box::new(None::<i8>)),
"smallint" | "smallserial" | "int2" | "serial2" => Ok(Box::new(None::<i16>)),
"int" | "integer" | "int4" | "serial" => Ok(Box::new(None::<i32>)),
"numeric" | "decimal" => Ok(Box::new(None::<Decimal>)),
"oid" => Ok(Box::new(None::<u32>)),
"bigint" | "bigserial" | "int8" | "serial8" => Ok(Box::new(None::<i64>)),
"real" | "float4" => Ok(Box::new(None::<f32>)),
"double" | "float8" => Ok(Box::new(None::<f64>)),
"uuid" => Ok(Box::new(None::<Uuid>)),
"date" => Ok(Box::new(None::<chrono::NaiveDate>)),
"time" | "timetz" => Ok(Box::new(None::<chrono::NaiveTime>)),
"timestamp" | "timestamptz" => Ok(Box::new(None::<chrono::NaiveDateTime>)),
"jsonb" | "json" => Ok(Box::new(None::<Option<Value>>)),
"bytea" => Ok(Box::new(None::<Vec<u8>>)),
"text" | "varchar" => Ok(Box::new(None::<String>)),
_ => Err(anyhow::anyhow!("Unsupported JSON null type"))?,
},
Value::Bool(s) if arg_t == "text" || arg_t == "varchar" => Ok(Box::new(s.to_string())),
Value::Null => Ok(Box::new(None::<bool>)),
Value::Bool(b) => Ok(Box::new(b.clone())),
Value::Number(n) if matches!(typ, Typ::Str(_)) => Ok(Box::new(n.to_string())),
Value::Number(n) if arg_t == "char" && n.is_i64() => {
@@ -616,11 +583,6 @@ fn convert_val(
.unwrap_or(vec![]);
Ok(Box::new(bytes))
}
Value::Object(_) if arg_t == "text" || arg_t == "varchar" => {
Ok(Box::new(serde_json::to_string(value).map_err(|err| {
Error::ExecutionErr(format!("Failed to convert JSON to text: {}", err))
})?))
}
Value::Object(_) => Ok(Box::new(value.clone())),
Value::String(s) => Ok(Box::new(s.clone())),
_ => Err(Error::ExecutionErr(format!(

View File

@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
export const VERSION = "v1.425.0";
export const VERSION = "v1.424.0";
export async function login(email: string, password: string): Promise<string> {
return await windmill.UserService.login({

View File

@@ -60,7 +60,7 @@ export {
// }
// });
export const VERSION = "1.425.0";
export const VERSION = "1.424.0";
const command = new Command()
.name("wmill")

View File

@@ -1,12 +1,12 @@
{
"name": "windmill-components",
"version": "1.425.0",
"version": "1.424.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "windmill-components",
"version": "1.425.0",
"version": "1.424.0",
"license": "AGPL-3.0",
"dependencies": {
"@anthropic-ai/sdk": "^0.32.1",

View File

@@ -1,6 +1,6 @@
{
"name": "windmill-components",
"version": "1.425.0",
"version": "1.424.0",
"scripts": {
"dev": "vite dev",
"build": "vite build",

View File

@@ -8,7 +8,6 @@
cleanValueProperties,
orderedJsonStringify,
orderedYamlStringify,
replaceFalseWithUndefined,
type Value
} from '$lib/utils'
import type { Script } from '$lib/gen'
@@ -55,9 +54,8 @@
diffViewer.closeDrawer()
}
function prepareDiff(data: Value) {
const metadata = structuredClone(cleanValueProperties(replaceFalseWithUndefined(data)))
const metadata = structuredClone(cleanValueProperties(data))
const content = metadata['content']
if (metadata['content'] !== undefined) {
metadata['content'] = 'check content diff'

View File

@@ -25,7 +25,6 @@
encodeState,
formatCron,
orderedJsonStringify,
replaceFalseWithUndefined,
sleep,
type Value
} from '$lib/utils'
@@ -295,21 +294,12 @@
// We need it for diff
await syncWithDeployed()
if (
deployedValue &&
$flowStore &&
orderedJsonStringify(deployedValue) ===
orderedJsonStringify(replaceFalseWithUndefined({ ...$flowStore, path: $pathStore }))
) {
// Handle through confirmation modal
confirmCallback = async () => {
await saveFlow(deploymentMsg)
} else {
// Handle through confirmation modal
confirmCallback = async () => {
await saveFlow(deploymentMsg)
}
// Open confirmation modal
open = true
}
// Open confirmation modal
open = true
}
}
async function syncWithDeployed() {
@@ -318,12 +308,18 @@
path: initialPath,
withStarredInfo: true
})
deployedValue = replaceFalseWithUndefined({
deployedValue = {
...flow,
starred: undefined,
id: undefined,
edited_at: undefined,
edited_by: undefined,
workspace_id: undefined
})
workspace_id: undefined,
archived: undefined,
same_worker: undefined,
visible_to_runner_only: undefined,
ws_error_handler_muted: undefined
}
deployedBy = flow.edited_by
}

View File

@@ -18,7 +18,6 @@
encodeState,
formatCron,
orderedJsonStringify,
replaceFalseWithUndefined,
type Value
} from '$lib/utils'
import Path from './Path.svelte'
@@ -279,28 +278,17 @@
// Fetch entire script, since we need it to show Diff
await syncWithDeployed()
if (
deployedValue &&
script &&
orderedJsonStringify({ ...deployedValue, hash: undefined }) ===
orderedJsonStringify(
replaceFalseWithUndefined({ ...script, hash: undefined, parent_hash: undefined })
)
) {
await editScript(stay, actual_parent_hash, deployMsg)
} else {
// Handle through confirmation modal
confirmCallback = async () => {
open = false
if (actual_parent_hash) {
await editScript(stay, actual_parent_hash, deployMsg)
} else {
sendUserToast('Could not fetch latest version of the script', true)
}
// Handle through confirmation modal
confirmCallback = async () => {
open = false
if (actual_parent_hash) {
await editScript(stay, actual_parent_hash, deployMsg)
} else {
sendUserToast('Could not fetch latest version of the script', true)
}
// Open confirmation modal
open = true
}
// Open confirmation modal
open = true
}
}
@@ -311,16 +299,20 @@
withStarredInfo: true
})
deployedValue = replaceFalseWithUndefined({
deployedValue = {
...latestScript,
starred: undefined,
workspace_id: undefined,
archived: undefined,
created_at: undefined,
created_by: undefined,
deleted: undefined,
extra_perms: undefined,
is_template: undefined,
lock: undefined,
lock_error_logs: undefined,
parent_hashes: undefined
})
}
deployedBy = latestScript.created_by
}
@@ -699,11 +691,8 @@
</Label>
<Label label="Path">
<svelte:fragment slot="header">
<Tooltip
documentationLink="https://www.windmill.dev/docs/core_concepts/roles_and_permissions#path"
>
The unique identifier of the script in the workspace that defines
permissions
<Tooltip documentationLink="https://www.windmill.dev/docs/core_concepts/roles_and_permissions#path">
The unique identifier of the script in the workspace that defines permissions
</Tooltip>
</svelte:fragment>
<Path

View File

@@ -41,8 +41,7 @@
copyToClipboard,
truncateRev,
orderedJsonStringify,
type Value,
replaceFalseWithUndefined
type Value
} from '../../../utils'
import type {
AppInput,
@@ -423,27 +422,13 @@
// We need it to show diff
// Handle through confirmation modal
await syncWithDeployed()
if (
deployedValue &&
savedApp &&
$app &&
orderedJsonStringify(deployedValue) ===
orderedJsonStringify(replaceFalseWithUndefined({
summary: $summary,
value: $app,
path: newPath || savedApp.draft?.path || savedApp.path,
policy
}))
) {
confirmCallback = async () => {
open = false
await updateApp(npath)
} else {
confirmCallback = async () => {
open = false
await updateApp(npath)
}
// Open confirmation modal
open = true
}
// Open confirmation modal
open = true
}
}
@@ -457,14 +442,15 @@
deployedBy = deployedApp.created_by
// Strip off extra information
deployedValue = replaceFalseWithUndefined({
deployedValue = {
...deployedApp,
starred: undefined,
id: undefined,
created_at: undefined,
created_by: undefined,
versions: undefined,
extra_perms: undefined
})
extra_perms: undefined //
}
}
async function updateApp(npath: string) {

View File

@@ -4,12 +4,7 @@
import { goto as gotoUrl } from '$app/navigation'
import Button from '../button/Button.svelte'
import type DiffDrawer from '$lib/components/DiffDrawer.svelte'
import {
cleanValueProperties,
orderedJsonStringify,
replaceFalseWithUndefined,
type Value
} from '$lib/utils'
import { cleanValueProperties, orderedJsonStringify, type Value } from '$lib/utils'
import { tick } from 'svelte'
import { page } from '$app/stores'
@@ -41,10 +36,7 @@
path: undefined
})
const current = cleanValueProperties({ ...(modifiedValue ?? {}), path: undefined })
if (
orderedJsonStringify(replaceFalseWithUndefined(draftOrDeployed)) ===
orderedJsonStringify(replaceFalseWithUndefined(current))
) {
if (orderedJsonStringify(draftOrDeployed) === orderedJsonStringify(current)) {
bypassBeforeNavigate = true
gotoUrl(goingTo)
} else {

View File

@@ -62,7 +62,7 @@
{:else if $selectedId === 'Input'}
<FlowInput {noEditor} disabled={disabledFlowInputs} />
{:else if $selectedId === 'Result'}
<p class="p-4 text-secondary">The result of the flow will be the result of the last node.</p>
<p class="p-4 text-secondary">Result of the flow will be the result of the last node.</p>
{:else if $selectedId === 'constants'}
<FlowConstants {noEditor} />
{:else if $selectedId === 'failure'}

View File

@@ -799,30 +799,6 @@ export type Value = {
[key: string]: any
}
export function replaceFalseWithUndefined(obj: any) {
return replaceFalseWithUndefinedRec(structuredClone(obj))
}
function replaceFalseWithUndefinedRec(obj: any) {
// Check if the input is an object and not null
if (obj !== null && typeof obj === 'object') {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// If the value is false, replace it with undefined
if (obj[key] === false) {
// delete obj[key];
obj[key] = undefined;
} else {
// If the value is an object, call the function recursively
replaceFalseWithUndefinedRec(obj[key]);
}
}
}
}
return obj
}
export function cleanValueProperties(obj: Value) {
if (typeof obj !== 'object') {
return obj

View File

@@ -129,7 +129,7 @@
...structuredClone(flowWithDraft.draft),
path: flowWithDraft.draft.path ?? flowWithDraft.path // backward compatibility for old drafts missing path
}
: undefined
: undefined
} as Flow & {
draft?: Flow
}

View File

@@ -4,8 +4,8 @@ verify_ssl = true
name = "pypi"
[packages]
wmill = ">=1.425.0"
wmill_pg = ">=1.425.0"
wmill = ">=1.424.0"
wmill_pg = ">=1.424.0"
sendgrid = "*"
mysql-connector-python = "*"
pymongo = "*"

View File

@@ -1,7 +1,7 @@
openapi: "3.0.3"
info:
version: 1.425.0
version: 1.424.0
title: OpenFlow Spec
contact:
name: Ruben Fiszel

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "windmill",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@@ -12,7 +12,7 @@
RootModule = 'WindmillClient.psm1'
# Version number of this module.
ModuleVersion = '1.425.0'
ModuleVersion = '1.424.0'
# Supported PSEditions
# CompatiblePSEditions = @()

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill"
version = "1.425.0"
version = "1.424.0"
description = "A client library for accessing Windmill server wrapping the Windmill client API"
license = "Apache-2.0"
homepage = "https://windmill.dev"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "wmill-pg"
version = "1.425.0"
version = "1.424.0"
description = "An extension client for the wmill client library focused on pg"
license = "Apache-2.0"
homepage = "https://windmill.dev"

View File

@@ -1,6 +1,6 @@
{
"name": "@windmill/windmill",
"version": "1.425.0",
"version": "1.424.0",
"exports": "./src/index.ts",
"publish": {
"exclude": ["!src", "./s3Types.ts", "./client.ts"]

View File

@@ -1,7 +1,7 @@
{
"name": "windmill-client",
"description": "Windmill SDK client for browsers and Node.js",
"version": "1.425.0",
"version": "1.424.0",
"author": "Ruben Fiszel",
"license": "Apache 2.0",
"devDependencies": {

View File

@@ -1 +1 @@
1.425.0
1.424.0