fix: read the workspaces key from wmill.yaml - #43
Merged
Merged
Conversation
The extension only ever read `gitBranches` and looked branches up as map
keys. The CLI's primary key is now `workspaces`, where the key is the
workspace name and the branch comes from `gitBranch ?? name`, so a config
like `workspaces: { cm: { gitBranch: main, workspaceId: cm } }` was
invisible to the extension and no workspace switch happened.
Mirror the CLI resolution (windmill/cli/src/core/conf.ts):
- read `workspaces`, falling back to the deprecated `gitBranches`,
`environments` and `git_branches` keys in the CLI's priority order
- resolve the entry by effective git branch, skipping the reserved
`commonSpecificItems` key
- default `workspaceId` to the workspace name
- normalize both sides of the remote comparison via `new URL()`, the same
normalization the CLI applies when storing workspace profiles
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
On a `wm-fork/<base>/<id>` branch the CLI targets the fork workspace `wm-fork-<id>`, resolved from the branch name itself; wmill.yaml is only consulted for the base branch's entry, which supplies the remote, and the auth is reused from that workspace's saved profile. Mirror that. The CLI never persists a profile for a fork (it derives one in memory per command, see core/context.ts), so nothing gets synced into `additionalWorkspaces` for the extension to switch to. Register a derived entry instead — parent remote and token, fork workspace id, named `<parent>/wm-fork-<id>`. `syncVSCodeConfigFromCLI` rewrites `additionalWorkspaces` wholesale on every sync, so this re-runs after each one, which the existing call order already guarantees. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The existing tests only exercised pure functions; the decision logic in switchWorkspaceForBranch — profile matching, remote normalization, fork entry registration, the already-on-target early return — was untested, which is where the reported bug actually lived. Back the vscode stub's configuration with a mutable store so tests can drive the settings the extension reads and writes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two behaviours found while testing the branch switch. When several profiles share a remote and workspace id — the same workspace reached as different identities — the extension silently took the first. The CLI prompts once and remembers the answer in branch-profiles.json (core/branch-profiles.ts), so read that and follow it. Don't prompt when there's no remembered choice: this runs from the .git/HEAD watcher and on activation, so a QuickPick would appear because you ran `git checkout`, and `Windmill: Switch workspace` already exists for choosing deliberately. Fall back to the first match and name it in the notification instead. The workspaces config was only reloaded when the active editor changed, so editing wmill.yaml had no effect until you switched files — likely the next thing to hit anyone who has just corrected that file. Watch it and drop the cache. Reading the CLI config is best-effort: a failure there falls back to the first match rather than aborting the switch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
findCodebase returned undefined as soon as the first codebase in the list did not match, so with several codebases configured only the first was ever reachable — a file belonging to the second got no codebase and so no bundling. The CLI's own findCodebase (commands/sync/sync.ts) continues the loop; do the same. Found while covering config-manager; the regression test fails against the previous behaviour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fills the three gaps called out in the PR. Both git detection and config loading go through the vscode filesystem API rather than node's, so the stub grows an in-memory filesystem, open-document set and workspace folders; syncVSCodeConfigFromCLI does use node fs, so it runs against a real temporary config dir laid out the way the CLI writes it. Covers .git/HEAD parsing including worktree gitdir indirection (absolute and relative) and detached HEAD; the root-first wmill.yaml search and its precedence; unsaved editor buffers winning over disk; the CLI sync and its failure modes; getCurrentWorkspaceConfig and the synthetic main workspace; checkAndSwitchWorkspaceForGitBranch including a wmill.yaml that is not valid YAML; the web-environment guards that keep the webpack build from touching node fs; and the status bar. Statement coverage of the touched modules goes from 73% to 99%. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported by a customer: after moving their
wmill.yamlto the newworkspaceskey, the extension stopped picking up their workspace, loggingNo gitBranches configuration found in wmill.yamland staying on whichever workspace the CLI had active.The bug
The extension read exactly one key,
config["gitBranches"], and looked the branch up as a map key. Both are wrong against today's CLI (cli/src/core/conf.ts):workspaces;gitBranches/environments/git_branchesare deprecated aliases the CLI normalizes inreadConfigFile. The extension only knew the first alias, so the config was invisible.entry.gitBranch ?? name. Even via the legacy key,config["main"]would have missed an entry namedcm.getEffectiveWorkspaceId); the extension required it explicitly.I verified the published 0.2.60 build has the same code — the exact string the customer saw is in the shipped bundle, so nothing was lost in an unreleased change.
Also in here
Fork branches. On
wm-fork/<base>/<id>the CLI targets the fork workspacewm-fork-<id>, resolved from the branch name; wmill.yaml is consulted only for the base branch's entry, which supplies the remote, and auth is reused from that workspace's profile. The CLI never persists a fork profile (it derives one in memory per command,core/context.ts), so there's nothing forsyncVSCodeConfigFromCLIto pull in — the extension registers a derived entry itself, named<parent>/wm-fork-<id>, re-added after each sync sinceadditionalWorkspacesis rewritten wholesale.Ambiguous profiles. When several profiles share a remote and workspace id — the same workspace as different identities — the extension silently took the first. It now reads the choice the CLI remembered in
branch-profiles.json. It deliberately does not prompt when there's no remembered choice: this runs from the.git/HEADwatcher and on activation, so a QuickPick would appear because you rangit checkout. It falls back to the first match and names it in the notification;Windmill: Switch workspaceremains for choosing deliberately.Stale config. The workspaces config was only reloaded when the active editor changed, so editing
wmill.yamlhad no effect until you switched files — plausibly the next thing to hit anyone who has just corrected that file. Now watched.findCodebasereturnedundefinedat the first codebase that didn't match, making every codebase after the first unreachable. The CLI's ownfindCodebasecontinues the loop; this now does too. Found while covering the module — the regression test fails against the previous behaviour.Testing
161 tests (from 46).
tsc --noEmitclean,npm run lint0 errors with no new warnings, and both bundles build (esbuild node + webpack web).Statement coverage of the touched modules went from 73% to 99% (100% functions, 95% branches):
config/config-manager.tsconfig/branch-profiles.tsutils/git-utils.tsworkspace/workspace-manager.tsGit detection and config loading go through the vscode filesystem API rather than node's, so the test stub grew an in-memory filesystem, open-document set and workspace folders.
syncVSCodeConfigFromCLIdoes use nodefs, so it runs against a real temporary config dir laid out the way the CLI writes it — no fs mocking needed.Covered: config key precedence across all three deprecated aliases; branch matching via
gitBranchand via the name;switchWorkspaceForBranchend to end (profile match/non-match,workspaceIddefaulting, trailing-slash and unparseable-URL normalization, missingbaseUrl, already-on-target no-op, syntheticmain, failed settings write); the fork cases (derived entry contents, re-registration after a sync wipe, parent token rotation, unconfigured base branch, malformed fork branch not falling through to the parent); the ambiguity cases (remembered choice honored,configFolderpassed through, fallbacks, fork inheriting the chosen identity's token);.git/HEADparsing including worktree gitdir indirection both absolute and relative, detached HEAD, and unreadable HEAD; the root-firstwmill.yamlsearch and its precedence, plus unsaved editor buffers winning over disk; the CLI sync and its failure modes;checkAndSwitchWorkspaceForGitBranchincluding awmill.yamlthat isn't valid YAML; the web-environment guards that keep the webpack build from touching nodefs; and the status bar.The
branch-profiles.jsonlocation (<configDir>/0/, from the CLI'sgetStore("")) is exercised against a real file written in the CLI's layout, and was additionally verified against the actual file the CLI wrote on my machine.Three defects the tests caught and I fixed rather than shipped: the two fork-branch helpers disagreed on
wm-fork/main/(empty id), which would have silently targeted the parent workspace — they now derive from one parser; a failed CLI-config read aborted the whole switch through the outer catch, now best-effort; and thefindCodebasescan above.Uncovered by design:
workspace-manager.ts:233-234, a "no workspace folder" guard only reachable aftergetCurrentGitBranchalready succeeded — which itself requires a workspace folder; and the default-config-dir branch ofgetLastUsedProfile, which would read the developer's real~/.config/windmill.🤖 Generated with Claude Code