mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-17 08:03:06 +00:00
Merge remote-tracking branch 'origin/main' into hugo/resource-type-guidance
This commit is contained in:
@@ -77,8 +77,8 @@ const WORKSPACE_CONFIG_SCHEMA = {
|
||||
*/
|
||||
export const CONFIG_REFERENCE: ConfigOption[] = [
|
||||
// ── Core ──────────────────────────────────────────────────────────────
|
||||
{ name: "defaultTs", type: "string", enum: ["bun", "deno"], default: "bun", description: "Default TypeScript runtime for new scripts",
|
||||
inlineComment: "bun or deno" },
|
||||
{ name: "defaultTs", type: "string", enum: ["bun", "deno"], default: "bun", description: "TypeScript runtime of a plain .ts script (bun when absent)",
|
||||
skipInTemplate: true },
|
||||
{ name: "includes", type: "array", items: { type: "string" }, default: '["f/**"]', description: "Glob patterns for files to include in sync",
|
||||
templateValue: '\n - "f/**"', inlineComment: 'use ** for all, f/** for folder-scoped' },
|
||||
{ name: "extraIncludes", type: "array", items: { type: "string" }, default: "[]", description: "Additional glob patterns merged with includes (useful in workspace overrides)",
|
||||
|
||||
@@ -320,12 +320,6 @@ export async function readConfigFile(opts?: { warnIfMissing?: boolean }): Promis
|
||||
delete (conf as any)?.environments;
|
||||
delete conf?.git_branches;
|
||||
|
||||
if (conf?.defaultTs == undefined) {
|
||||
log.warn(
|
||||
"No defaultTs defined in your wmill.yaml. Using 'bun' as default."
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize global nonDottedPaths setting from config
|
||||
setNonDottedPaths(conf?.nonDottedPaths ?? false);
|
||||
|
||||
@@ -376,7 +370,6 @@ export const DEFAULT_SYNC_OPTIONS: Readonly<
|
||||
Required<
|
||||
Pick<
|
||||
SyncOptions,
|
||||
| "defaultTs"
|
||||
| "includes"
|
||||
| "excludes"
|
||||
| "codebases"
|
||||
@@ -401,7 +394,6 @@ export const DEFAULT_SYNC_OPTIONS: Readonly<
|
||||
>
|
||||
>
|
||||
> = {
|
||||
defaultTs: "bun",
|
||||
includes: ["f/**"],
|
||||
excludes: [],
|
||||
codebases: [],
|
||||
|
||||
@@ -10,4 +10,4 @@ export const WM_FORK_PREFIX = "wm-fork";
|
||||
// (e.g. utils.ts) can read it without importing main.ts and creating a circular
|
||||
// dependency (main → workspace → utils → main) that triggers a TDZ.
|
||||
// Re-exported from main.ts for backwards compatibility.
|
||||
export const VERSION = "1.829.0";
|
||||
export const VERSION = "1.830.0";
|
||||
|
||||
@@ -34,10 +34,14 @@ export async function buildPermissionedAsContext(
|
||||
return undefined;
|
||||
}
|
||||
const user = await wmill.whoami({ workspace });
|
||||
// A superadmin acts as admin in every workspace, so the backend preserves
|
||||
// ownership for them even when their own `usr` row there is not an admin.
|
||||
const userIsAdminOrDeployer =
|
||||
user.is_admin || (user.groups ?? []).includes("wm_deployers");
|
||||
user.is_admin ||
|
||||
user.is_super_admin ||
|
||||
(user.groups ?? []).includes("wm_deployers");
|
||||
log.debug(
|
||||
`permissioned_as: user=${user.email}, is_admin=${user.is_admin}, groups=${JSON.stringify(user.groups)}, isAdminOrDeployer=${userIsAdminOrDeployer}`
|
||||
`permissioned_as: user=${user.email}, is_admin=${user.is_admin}, is_super_admin=${user.is_super_admin}, groups=${JSON.stringify(user.groups)}, isAdminOrDeployer=${userIsAdminOrDeployer}`
|
||||
);
|
||||
return {
|
||||
userCache: new Map(),
|
||||
|
||||
@@ -413,7 +413,7 @@ export async function pushWorkspaceSettings(
|
||||
const localOperatorSettings = localSettings.operator_settings && {
|
||||
...localSettings.operator_settings,
|
||||
};
|
||||
for (const key of ["builder_flows", "manage_schedules", "manage_triggers"] as const) {
|
||||
for (const key of ["builder_flows", "builder_apps", "manage_schedules", "manage_triggers"] as const) {
|
||||
const remote = settings.operator_settings?.[key];
|
||||
if (localOperatorSettings && localOperatorSettings[key] === undefined && remote !== undefined) {
|
||||
localOperatorSettings[key] = remote;
|
||||
|
||||
@@ -189,6 +189,8 @@ const LANG_ANNOTATIONS: Partial<Record<ScriptLanguage, string[]>> = {
|
||||
"py311",
|
||||
"py312",
|
||||
"py313",
|
||||
"py314",
|
||||
"py315",
|
||||
"sandbox",
|
||||
],
|
||||
bun: ["npm", "nodejs", "native", "nobundling", "sandbox"],
|
||||
@@ -208,7 +210,7 @@ const LANG_ANNOTATIONS: Partial<Record<ScriptLanguage, string[]>> = {
|
||||
*
|
||||
* `# py: <specifier>` is the exception the macro does not cover: the python
|
||||
* import parser reads it directly (`windmill-parser-py-imports`, alongside the
|
||||
* `py310`..`py313` flags) to pick the interpreter, which changes what resolves.
|
||||
* `py310`..`py315` flags) to pick the interpreter, which changes what resolves.
|
||||
*/
|
||||
export function hasLockAffectingAnnotation(
|
||||
scriptContent: string,
|
||||
|
||||
@@ -56,8 +56,6 @@ test("Init: createWorkspaceProfile includes defaults when no repositories exist"
|
||||
expect(Array.isArray(workspaceProfile.excludes)).toBeTruthy();
|
||||
expect(workspaceProfile.excludes.length).toEqual(0);
|
||||
|
||||
expect(workspaceProfile.defaultTs).toEqual('bun');
|
||||
|
||||
console.log('Workspace profile correctly includes default sync settings when no repositories exist');
|
||||
});
|
||||
|
||||
@@ -74,8 +72,6 @@ test("Init: verify DEFAULT_SYNC_OPTIONS has expected values", () => {
|
||||
expect(Array.isArray(DEFAULT_SYNC_OPTIONS.excludes)).toBeTruthy();
|
||||
expect(DEFAULT_SYNC_OPTIONS.excludes.length).toEqual(0);
|
||||
|
||||
expect(DEFAULT_SYNC_OPTIONS.defaultTs).toEqual('bun');
|
||||
|
||||
console.log('DEFAULT_SYNC_OPTIONS has expected values');
|
||||
});
|
||||
|
||||
@@ -178,7 +174,7 @@ test.skipIf(shouldSkipOnCI())("Init: --use-default bypasses backend settings che
|
||||
|
||||
// Should have default settings, not backend settings
|
||||
expect(wmillYaml).toContain("includes:\n - f/**");
|
||||
expect(wmillYaml).toContain("defaultTs: bun");
|
||||
expect(wmillYaml).not.toContain("defaultTs");
|
||||
|
||||
// Should NOT have backend-specific settings
|
||||
expect(wmillYaml.includes("f/should-be-ignored/**")).toEqual(false);
|
||||
|
||||
@@ -90,7 +90,6 @@ describe("generateCommentedTemplate", () => {
|
||||
|
||||
test("default values match expected defaults", () => {
|
||||
const config = parse(generateCommentedTemplate("main"));
|
||||
expect(config.defaultTs).toBe("bun");
|
||||
expect(config.skipSecrets).toBe(true);
|
||||
expect(config.nonDottedPaths).toBe(true);
|
||||
expect(config.codebases).toEqual([]);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Regression guard: a superadmin whose `usr` row in the workspace is not an
|
||||
* admin still preserves ownership on the backend, so the CLI must not refuse
|
||||
* their push as if it would reassign every item to them.
|
||||
*/
|
||||
|
||||
import { expect, test } from "bun:test";
|
||||
import { mockServices } from "./mock_services.ts";
|
||||
|
||||
mockServices({
|
||||
whoami: async () => ({
|
||||
email: "super@windmill.dev",
|
||||
username: "super",
|
||||
is_admin: false,
|
||||
is_super_admin: true,
|
||||
groups: [],
|
||||
}),
|
||||
});
|
||||
|
||||
const { buildPermissionedAsContext } = await import(
|
||||
"../src/core/permissioned_as.ts"
|
||||
);
|
||||
|
||||
test("a superadmin with a non-admin membership counts as able to preserve", async () => {
|
||||
const ctx = await buildPermissionedAsContext("w", "v1");
|
||||
expect(ctx?.userIsAdminOrDeployer).toBe(true);
|
||||
});
|
||||
@@ -10,7 +10,7 @@
|
||||
"bun",
|
||||
"deno"
|
||||
],
|
||||
"description": "Default TypeScript runtime for new scripts"
|
||||
"description": "TypeScript runtime of a plain .ts script (bun when absent)"
|
||||
},
|
||||
"includes": {
|
||||
"type": "array",
|
||||
|
||||
Reference in New Issue
Block a user