mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 00:02:03 +00:00
1722a7a2af
* fix(cli): use wmill.yaml key (not branch name) for workspace-specific filenames
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(cli): resolve --workspace as config key even with --base-url
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(integration): assert workspace config key drives filename suffix in git-sync
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Revert "test(integration): assert workspace config key drives filename suffix in git-sync"
This reverts commit 528993fe29.
* fix(cli): filter reserved keys and preserve validation-skip on non-config --workspace
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
183 lines
6.2 KiB
TypeScript
183 lines
6.2 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
import { execSync } from "node:child_process";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { stringify as yamlStringify } from "yaml";
|
|
|
|
import { resolveWsNameForGitBranch } from "../src/core/specific_items.ts";
|
|
import { findResourceFile } from "../src/commands/script/script.ts";
|
|
import { resolveWsNameForConfigFromFlags } from "../src/commands/sync/sync.ts";
|
|
import type { SyncOptions } from "../src/core/conf.ts";
|
|
|
|
// Integration tests covering the bug where workspace-specific filenames used
|
|
// the raw git branch name instead of the wmill.yaml workspace config key.
|
|
// A per-item helper (findResourceFile) now resolves the effective wsName from
|
|
// wmill.yaml before falling back to the branch name.
|
|
|
|
async function withGitRepoAndConfig(
|
|
config: unknown,
|
|
branch: string,
|
|
fn: (tempDir: string) => Promise<void>,
|
|
): Promise<void> {
|
|
const tempDir = await mkdtemp(path.join(os.tmpdir(), "wmill_wskey_"));
|
|
const originalCwd = process.cwd();
|
|
try {
|
|
// Set up a minimal git repo on the target branch so getCurrentGitBranch()
|
|
// returns the expected value. An initial commit is needed so HEAD points
|
|
// somewhere and `git rev-parse --abbrev-ref HEAD` succeeds.
|
|
execSync(`git init -q -b ${branch}`, { cwd: tempDir });
|
|
execSync(`git config user.email test@example.com`, { cwd: tempDir });
|
|
execSync(`git config user.name test`, { cwd: tempDir });
|
|
|
|
await writeFile(
|
|
path.join(tempDir, "wmill.yaml"),
|
|
yamlStringify(config),
|
|
);
|
|
|
|
execSync(`git add wmill.yaml && git commit -q -m init`, { cwd: tempDir });
|
|
|
|
process.chdir(tempDir);
|
|
await fn(tempDir);
|
|
} finally {
|
|
process.chdir(originalCwd);
|
|
await rm(tempDir, { recursive: true, force: true });
|
|
}
|
|
}
|
|
|
|
describe("resolveWsNameForGitBranch", () => {
|
|
test("returns the wmill.yaml config key for a branch matched via gitBranch field", async () => {
|
|
await withGitRepoAndConfig(
|
|
{
|
|
workspaces: {
|
|
myKey: { gitBranch: "main", workspaceId: "prod" },
|
|
},
|
|
},
|
|
"main",
|
|
async () => {
|
|
const wsName = await resolveWsNameForGitBranch("main");
|
|
expect(wsName).toEqual("myKey");
|
|
},
|
|
);
|
|
});
|
|
|
|
test("returns the wmill.yaml config key when the branch equals the key and gitBranch is not set", async () => {
|
|
await withGitRepoAndConfig(
|
|
{
|
|
workspaces: {
|
|
staging: { workspaceId: "stg_workspace" },
|
|
},
|
|
},
|
|
"staging",
|
|
async () => {
|
|
const wsName = await resolveWsNameForGitBranch("staging");
|
|
expect(wsName).toEqual("staging");
|
|
},
|
|
);
|
|
});
|
|
|
|
test("falls back to the branch name when no matching workspace entry exists", async () => {
|
|
await withGitRepoAndConfig(
|
|
{
|
|
workspaces: {
|
|
production: { gitBranch: "main" },
|
|
},
|
|
},
|
|
"feature-x",
|
|
async () => {
|
|
const wsName = await resolveWsNameForGitBranch("feature-x");
|
|
expect(wsName).toEqual("feature-x");
|
|
},
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("resolveWsNameForConfigFromFlags", () => {
|
|
test("--workspace matching a config key resolves, even with --base-url", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
workspace: "test",
|
|
baseUrl: "http://127.0.0.1:8080/",
|
|
workspaces: {
|
|
test: { gitBranch: "main" },
|
|
prod: { gitBranch: "main" },
|
|
},
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toEqual("test");
|
|
});
|
|
|
|
test("--workspace not in config with --base-url returns undefined (treat as ad-hoc credential)", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
workspace: "adhocWorkspaceId",
|
|
baseUrl: "https://other.windmill.dev/",
|
|
workspaces: {
|
|
test: { gitBranch: "main" },
|
|
},
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toBeUndefined();
|
|
});
|
|
|
|
test("--workspace matching config key resolves even without --base-url", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
workspace: "prod",
|
|
workspaces: { test: {}, prod: {} },
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toEqual("prod");
|
|
});
|
|
|
|
test("--branch takes precedence and looks up by gitBranch", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
branch: "main",
|
|
workspace: "someOtherKey",
|
|
workspaces: {
|
|
test: { gitBranch: "main" },
|
|
prod: { gitBranch: "release" },
|
|
},
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toEqual("test");
|
|
});
|
|
|
|
test("no flags returns undefined", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
workspaces: { test: {} },
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toBeUndefined();
|
|
});
|
|
|
|
test("reserved key 'commonSpecificItems' is not accepted as a config key", () => {
|
|
const opts: SyncOptions & { branch?: string; workspace?: string } = {
|
|
workspace: "commonSpecificItems",
|
|
workspaces: {
|
|
test: {},
|
|
commonSpecificItems: { variables: ["f/**"] } as any,
|
|
},
|
|
} as any;
|
|
expect(resolveWsNameForConfigFromFlags(opts)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("findResourceFile picks the wsName-named file, not the branch-named file", () => {
|
|
test("finds the workspace-specific resource file using the config key as suffix", async () => {
|
|
await withGitRepoAndConfig(
|
|
{
|
|
workspaces: {
|
|
myKey: { gitBranch: "main", workspaceId: "prod" },
|
|
},
|
|
},
|
|
"main",
|
|
async (tempDir) => {
|
|
// Only the config-key-named file exists on disk. A wmill without this
|
|
// fix would look for `f/foo.main.resource.yaml` (the branch name) and
|
|
// either miss this file or pick a stale branch-named file.
|
|
await mkdir(path.join(tempDir, "f"), { recursive: true });
|
|
await writeFile(
|
|
path.join(tempDir, "f/foo.myKey.resource.yaml"),
|
|
"value: {}\nresource_type: text\n",
|
|
);
|
|
|
|
const found = await findResourceFile("f/foo.resource.file.txt");
|
|
expect(found).toEqual("f/foo.myKey.resource.yaml");
|
|
},
|
|
);
|
|
});
|
|
});
|