Files
windmill/cli/test/conf_branch_override_unit.test.ts
Ruben Fiszel 5b97092997 feat: unify CLI config to workspaces, deprecate gitBranches/environments (#8767)
* refactor: unify CLI config to workspaces, deprecate gitBranches/environments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: update frontend examples and regenerate system prompts for workspaces config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: update test files to use workspaces config instead of gitBranches

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: handle --branch with --base-url correctly in sync pull/push

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: warn when --workspace overrides auto-detected branch or misses config entry

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: show reason why workspace was selected in log message

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: clarify specificItems file naming uses gitBranch as suffix

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: rename branch-specific to workspace-specific, use workspace name as file suffix

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: rename branch-specific to workspace-specific, add comprehensive integration tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: simplify bind and init to be workspace-centric

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: make bind/unbind interactive with --workspace and --branch flags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: make bind interactive with profile selection, workspace name, and optional branch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: init offers to bind workspace using same flow as wmill workspace bind

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: skip backend git-sync check in init when no workspace was bound

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: skip all API calls in init when no workspace was bound

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: log when RT namespace is skipped, offer to generate it after bind

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: warn when no workspace bound during init

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: init git-sync check uses bound workspace, not active profile

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: init uses selected profile directly, avoids re-resolving and duplicate prompt

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: init skips requireLogin, uses bound profile token directly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: auto-pick or prompt workspace from config when no branch matches

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: show configured workspaces list and bind hint in resolution messages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: cache bound profile to avoid duplicate profile selection prompts in init

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: hoist boundProfile scope, add 2 comprehensive integration tests covering all flows

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: rt.d.ts prompt defaults to no when file exists, better description

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove empty overrides from generated config, add specificItems hint

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add inline comments for non-trivial fields, add overrides/promotionOverrides hints to bound workspaces

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: regenerate system prompts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-09 19:46:34 +00:00

145 lines
4.6 KiB
TypeScript

import { expect, test } from "bun:test";
import { getEffectiveSettings, type SyncOptions } from "../src/core/conf.ts";
// =============================================================================
// CONF.TS WORKSPACE OVERRIDE TESTS
// Tests for getEffectiveSettings with workspaceNameOverride parameter
// =============================================================================
test("getEffectiveSettings: applies workspace overrides when workspaceNameOverride is provided", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
workspaces: {
staging: {
overrides: {
includes: ["staging/**"],
skipVariables: true,
},
},
production: {
overrides: {
includes: ["prod/**"],
skipSecrets: true,
},
},
},
};
// Test with staging workspace override
const stagingSettings = await getEffectiveSettings(config, undefined, true, true, "staging");
expect(stagingSettings.includes).toEqual(["staging/**"]);
expect(stagingSettings.skipVariables).toEqual(true);
expect(stagingSettings.skipSecrets).toEqual(undefined);
// Test with production workspace override
const prodSettings = await getEffectiveSettings(config, undefined, true, true, "production");
expect(prodSettings.includes).toEqual(["prod/**"]);
expect(prodSettings.skipSecrets).toEqual(true);
expect(prodSettings.skipVariables).toEqual(undefined);
});
test("getEffectiveSettings: uses top-level settings when workspace has no overrides", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
skipVariables: true,
workspaces: {
staging: {
// No overrides defined
},
},
};
const settings = await getEffectiveSettings(config, undefined, true, true, "staging");
expect(settings.includes).toEqual(["f/**"]);
expect(settings.skipVariables).toEqual(true);
expect(settings.defaultTs).toEqual("bun");
});
test("getEffectiveSettings: uses top-level settings for unknown workspace", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
workspaces: {
staging: {
overrides: {
includes: ["staging/**"],
},
},
},
};
const settings = await getEffectiveSettings(config, undefined, true, true, "nonexistent");
expect(settings.includes).toEqual(["f/**"]);
expect(settings.defaultTs).toEqual("bun");
});
test("getEffectiveSettings: promotionOverrides take precedence when promotion specified", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
workspaces: {
production: {
overrides: {
includes: ["prod/**"],
},
promotionOverrides: {
includes: ["promoted/**"],
skipVariables: true,
},
},
},
};
// Test without promotion flag - should use regular overrides
const normalSettings = await getEffectiveSettings(config, undefined, true, true, "production");
expect(normalSettings.includes).toEqual(["prod/**"]);
expect(normalSettings.skipVariables).toEqual(undefined);
// Test with promotion flag - should use promotionOverrides
const promoSettings = await getEffectiveSettings(config, "production", true, true);
expect(promoSettings.includes).toEqual(["promoted/**"]);
expect(promoSettings.skipVariables).toEqual(true);
});
test("getEffectiveSettings: workspaceNameOverride works without workspaces config", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
};
// Should not throw even with workspaceNameOverride but no workspaces
const settings = await getEffectiveSettings(config, undefined, true, true, "staging");
expect(settings.includes).toEqual(["f/**"]);
expect(settings.defaultTs).toEqual("bun");
});
test("getEffectiveSettings: preserves all top-level settings in merged result", async () => {
const config: SyncOptions = {
defaultTs: "bun",
includes: ["f/**"],
excludes: ["*.test.ts"],
skipVariables: false,
skipResources: false,
skipFlows: false,
parallel: 4,
workspaces: {
staging: {
overrides: {
skipVariables: true, // Override just this one
},
},
},
};
const settings = await getEffectiveSettings(config, undefined, true, true, "staging");
expect(settings.defaultTs).toEqual("bun");
expect(settings.includes).toEqual(["f/**"]);
expect(settings.excludes).toEqual(["*.test.ts"]);
expect(settings.skipVariables).toEqual(true); // Overridden
expect(settings.skipResources).toEqual(false);
expect(settings.skipFlows).toEqual(false);
expect(settings.parallel).toEqual(4);
});