windmill-cli 1.608.0 → 1.610.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/gen/core/OpenAPI.js +1 -1
- package/esm/gen/services.gen.js +101 -0
- package/esm/src/commands/script/script.js +2 -1
- package/esm/src/commands/sync/sync.js +34 -32
- package/esm/src/core/conf.js +45 -38
- package/esm/src/core/context.js +34 -22
- package/esm/src/core/specific_items.js +28 -10
- package/esm/src/main.js +1 -1
- package/esm/src/utils/resource_folders.js +3 -1
- package/package.json +1 -1
- package/types/gen/services.gen.d.ts +50 -1
- package/types/gen/services.gen.d.ts.map +1 -1
- package/types/gen/types.gen.d.ts +73 -0
- package/types/gen/types.gen.d.ts.map +1 -1
- package/types/src/commands/script/script.d.ts.map +1 -1
- package/types/src/commands/sync/sync.d.ts +5 -1
- package/types/src/commands/sync/sync.d.ts.map +1 -1
- package/types/src/core/conf.d.ts +1 -1
- package/types/src/core/conf.d.ts.map +1 -1
- package/types/src/core/context.d.ts +2 -2
- package/types/src/core/context.d.ts.map +1 -1
- package/types/src/core/specific_items.d.ts +3 -3
- package/types/src/core/specific_items.d.ts.map +1 -1
- package/types/src/main.d.ts +1 -1
- package/types/src/utils/resource_folders.d.ts.map +1 -1
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts +73 -0
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts.map +1 -1
package/esm/gen/core/OpenAPI.js
CHANGED
package/esm/gen/services.gen.js
CHANGED
|
@@ -1973,6 +1973,25 @@ export const editErrorHandler = (data) => {
|
|
|
1973
1973
|
mediaType: 'application/json'
|
|
1974
1974
|
});
|
|
1975
1975
|
};
|
|
1976
|
+
/**
|
|
1977
|
+
* edit success handler
|
|
1978
|
+
* @param data The data for the request.
|
|
1979
|
+
* @param data.workspace
|
|
1980
|
+
* @param data.requestBody WorkspaceSuccessHandler
|
|
1981
|
+
* @returns string status
|
|
1982
|
+
* @throws ApiError
|
|
1983
|
+
*/
|
|
1984
|
+
export const editSuccessHandler = (data) => {
|
|
1985
|
+
return __request(OpenAPI, {
|
|
1986
|
+
method: 'POST',
|
|
1987
|
+
url: '/w/{workspace}/workspaces/edit_success_handler',
|
|
1988
|
+
path: {
|
|
1989
|
+
workspace: data.workspace
|
|
1990
|
+
},
|
|
1991
|
+
body: data.requestBody,
|
|
1992
|
+
mediaType: 'application/json'
|
|
1993
|
+
});
|
|
1994
|
+
};
|
|
1976
1995
|
/**
|
|
1977
1996
|
* edit large file storage settings
|
|
1978
1997
|
* @param data The data for the request.
|
|
@@ -3456,6 +3475,88 @@ export const listResourceTypeNames = (data) => {
|
|
|
3456
3475
|
}
|
|
3457
3476
|
});
|
|
3458
3477
|
};
|
|
3478
|
+
/**
|
|
3479
|
+
* get npm package metadata from private registry
|
|
3480
|
+
* @param data The data for the request.
|
|
3481
|
+
* @param data.workspace
|
|
3482
|
+
* @param data._package npm package name
|
|
3483
|
+
* @returns unknown package metadata
|
|
3484
|
+
* @throws ApiError
|
|
3485
|
+
*/
|
|
3486
|
+
export const getNpmPackageMetadata = (data) => {
|
|
3487
|
+
return __request(OpenAPI, {
|
|
3488
|
+
method: 'GET',
|
|
3489
|
+
url: '/w/{workspace}/npm_proxy/metadata/{package}',
|
|
3490
|
+
path: {
|
|
3491
|
+
workspace: data.workspace,
|
|
3492
|
+
package: data._package
|
|
3493
|
+
}
|
|
3494
|
+
});
|
|
3495
|
+
};
|
|
3496
|
+
/**
|
|
3497
|
+
* resolve npm package version from private registry
|
|
3498
|
+
* @param data The data for the request.
|
|
3499
|
+
* @param data.workspace
|
|
3500
|
+
* @param data._package npm package name
|
|
3501
|
+
* @param data.tag version tag or reference
|
|
3502
|
+
* @returns unknown resolved version
|
|
3503
|
+
* @throws ApiError
|
|
3504
|
+
*/
|
|
3505
|
+
export const resolveNpmPackageVersion = (data) => {
|
|
3506
|
+
return __request(OpenAPI, {
|
|
3507
|
+
method: 'GET',
|
|
3508
|
+
url: '/w/{workspace}/npm_proxy/resolve/{package}',
|
|
3509
|
+
path: {
|
|
3510
|
+
workspace: data.workspace,
|
|
3511
|
+
package: data._package
|
|
3512
|
+
},
|
|
3513
|
+
query: {
|
|
3514
|
+
tag: data.tag
|
|
3515
|
+
}
|
|
3516
|
+
});
|
|
3517
|
+
};
|
|
3518
|
+
/**
|
|
3519
|
+
* get npm package file tree from private registry
|
|
3520
|
+
* @param data The data for the request.
|
|
3521
|
+
* @param data.workspace
|
|
3522
|
+
* @param data._package npm package name
|
|
3523
|
+
* @param data.version package version
|
|
3524
|
+
* @returns unknown package file tree
|
|
3525
|
+
* @throws ApiError
|
|
3526
|
+
*/
|
|
3527
|
+
export const getNpmPackageFiletree = (data) => {
|
|
3528
|
+
return __request(OpenAPI, {
|
|
3529
|
+
method: 'GET',
|
|
3530
|
+
url: '/w/{workspace}/npm_proxy/filetree/{package}/{version}',
|
|
3531
|
+
path: {
|
|
3532
|
+
workspace: data.workspace,
|
|
3533
|
+
package: data._package,
|
|
3534
|
+
version: data.version
|
|
3535
|
+
}
|
|
3536
|
+
});
|
|
3537
|
+
};
|
|
3538
|
+
/**
|
|
3539
|
+
* get specific file from npm package in private registry
|
|
3540
|
+
* @param data The data for the request.
|
|
3541
|
+
* @param data.workspace
|
|
3542
|
+
* @param data._package npm package name
|
|
3543
|
+
* @param data.version package version
|
|
3544
|
+
* @param data.filepath file path within package
|
|
3545
|
+
* @returns string file content
|
|
3546
|
+
* @throws ApiError
|
|
3547
|
+
*/
|
|
3548
|
+
export const getNpmPackageFile = (data) => {
|
|
3549
|
+
return __request(OpenAPI, {
|
|
3550
|
+
method: 'GET',
|
|
3551
|
+
url: '/w/{workspace}/npm_proxy/file/{package}/{version}/{filepath}',
|
|
3552
|
+
path: {
|
|
3553
|
+
workspace: data.workspace,
|
|
3554
|
+
package: data._package,
|
|
3555
|
+
version: data.version,
|
|
3556
|
+
filepath: data.filepath
|
|
3557
|
+
}
|
|
3558
|
+
});
|
|
3559
|
+
};
|
|
3459
3560
|
/**
|
|
3460
3561
|
* query resource types by similarity
|
|
3461
3562
|
* @param data The data for the request.
|
|
@@ -172,6 +172,7 @@ export async function handleFile(path, workspace, alreadySynced, message, opts,
|
|
|
172
172
|
continue;
|
|
173
173
|
}
|
|
174
174
|
log.info(`Adding file: ${file.path.substring(1)}`);
|
|
175
|
+
// deno-lint-ignore no-explicit-any
|
|
175
176
|
const fil = new File([file.contents], file.path.substring(1));
|
|
176
177
|
tarball.append(fil);
|
|
177
178
|
}
|
|
@@ -350,7 +351,7 @@ async function streamToBlob(stream) {
|
|
|
350
351
|
// Push the chunk to the array
|
|
351
352
|
chunks.push(value);
|
|
352
353
|
}
|
|
353
|
-
//
|
|
354
|
+
// deno-lint-ignore no-explicit-any
|
|
354
355
|
const blob = new Blob(chunks);
|
|
355
356
|
return blob;
|
|
356
357
|
}
|
|
@@ -10,7 +10,7 @@ import { handleFile } from "../script/script.js";
|
|
|
10
10
|
import { deepEqual, fetchRemoteVersion, isFileResource, isRawAppFile, isWorkspaceDependencies, } from "../../utils/utils.js";
|
|
11
11
|
import { getEffectiveSettings, mergeConfigWithConfigFile, validateBranchConfiguration, } from "../../core/conf.js";
|
|
12
12
|
import { fromBranchSpecificPath, getBranchSpecificPath, getSpecificItemsForCurrentBranch, isBranchSpecificFile, isCurrentBranchFile, isSpecificItem, } from "../../core/specific_items.js";
|
|
13
|
-
import { getCurrentGitBranch } from "../../utils/git.js";
|
|
13
|
+
import { getCurrentGitBranch, isGitRepository } from "../../utils/git.js";
|
|
14
14
|
import { removePathPrefix } from "../../types.js";
|
|
15
15
|
import { listSyncCodebases } from "../../utils/codebase.js";
|
|
16
16
|
import { generateScriptMetadataInternal, getRawWorkspaceDependencies, readLockfile, workspaceDependenciesPathToLanguageAndFilename, } from "../../utils/metadata.js";
|
|
@@ -27,8 +27,8 @@ function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
|
|
|
27
27
|
return Object.assign({}, effectiveOpts, cliOpts);
|
|
28
28
|
}
|
|
29
29
|
// Resolve effective sync options using branch-based configuration
|
|
30
|
-
async function resolveEffectiveSyncOptions(workspace, localConfig, promotion) {
|
|
31
|
-
return await getEffectiveSettings(localConfig, promotion);
|
|
30
|
+
async function resolveEffectiveSyncOptions(workspace, localConfig, promotion, branchOverride) {
|
|
31
|
+
return await getEffectiveSettings(localConfig, promotion, false, false, branchOverride);
|
|
32
32
|
}
|
|
33
33
|
export function findCodebase(path, codebases) {
|
|
34
34
|
if (!path.endsWith(".ts")) {
|
|
@@ -1014,7 +1014,7 @@ export async function* readDirRecursiveWithIgnore(ignore, root) {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
}
|
|
1016
1016
|
}
|
|
1017
|
-
export async function elementsToMap(els, ignore, json, skips, specificItems) {
|
|
1017
|
+
export async function elementsToMap(els, ignore, json, skips, specificItems, branchOverride) {
|
|
1018
1018
|
const map = {};
|
|
1019
1019
|
const processedBasePaths = new Set();
|
|
1020
1020
|
for await (const entry of readDirRecursiveWithIgnore(ignore, els)) {
|
|
@@ -1115,8 +1115,7 @@ export async function elementsToMap(els, ignore, json, skips, specificItems) {
|
|
|
1115
1115
|
}
|
|
1116
1116
|
// Handle branch-specific files - skip files for other branches
|
|
1117
1117
|
if (specificItems && isBranchSpecificFile(path)) {
|
|
1118
|
-
|
|
1119
|
-
if (!currentBranch || !isCurrentBranchFile(path)) {
|
|
1118
|
+
if (!isCurrentBranchFile(path, branchOverride)) {
|
|
1120
1119
|
// Skip branch-specific files for other branches
|
|
1121
1120
|
continue;
|
|
1122
1121
|
}
|
|
@@ -1153,9 +1152,10 @@ export async function elementsToMap(els, ignore, json, skips, specificItems) {
|
|
|
1153
1152
|
}
|
|
1154
1153
|
// Handle branch-specific path mapping after all filtering
|
|
1155
1154
|
if (specificItems) {
|
|
1156
|
-
|
|
1157
|
-
if (currentBranch && isCurrentBranchFile(path)) {
|
|
1155
|
+
if (isCurrentBranchFile(path, branchOverride)) {
|
|
1158
1156
|
// This is a branch-specific file for current branch
|
|
1157
|
+
// Safe to compute branch here since isCurrentBranchFile already validated it exists
|
|
1158
|
+
const currentBranch = branchOverride || getCurrentGitBranch();
|
|
1159
1159
|
const basePath = fromBranchSpecificPath(path, currentBranch);
|
|
1160
1160
|
if (isSpecificItem(basePath, specificItems)) {
|
|
1161
1161
|
// Map to base path for push operations
|
|
@@ -1183,13 +1183,13 @@ export async function elementsToMap(els, ignore, json, skips, specificItems) {
|
|
|
1183
1183
|
}
|
|
1184
1184
|
return map;
|
|
1185
1185
|
}
|
|
1186
|
-
async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetadataDeletion, codebases, ignoreCodebaseChanges, specificItems) {
|
|
1186
|
+
async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetadataDeletion, codebases, ignoreCodebaseChanges, specificItems, branchOverride) {
|
|
1187
1187
|
const [m1, m2] = els2
|
|
1188
1188
|
? await Promise.all([
|
|
1189
|
-
elementsToMap(els1, ignore, json, skips, specificItems),
|
|
1190
|
-
elementsToMap(els2, ignore, json, skips, specificItems),
|
|
1189
|
+
elementsToMap(els1, ignore, json, skips, specificItems, branchOverride),
|
|
1190
|
+
elementsToMap(els2, ignore, json, skips, specificItems, branchOverride),
|
|
1191
1191
|
])
|
|
1192
|
-
: [await elementsToMap(els1, ignore, json, skips, specificItems), {}];
|
|
1192
|
+
: [await elementsToMap(els1, ignore, json, skips, specificItems, branchOverride), {}];
|
|
1193
1193
|
const changes = [];
|
|
1194
1194
|
function parseYaml(k, v) {
|
|
1195
1195
|
if (k.endsWith(".script.yaml")) {
|
|
@@ -1573,12 +1573,12 @@ export async function pull(opts) {
|
|
|
1573
1573
|
if (opts.stateful) {
|
|
1574
1574
|
await ensureDir(path.join(dntShim.Deno.cwd(), ".wmill"));
|
|
1575
1575
|
}
|
|
1576
|
-
const workspace = await resolveWorkspace(opts);
|
|
1576
|
+
const workspace = await resolveWorkspace(opts, opts.branch);
|
|
1577
1577
|
await requireLogin(opts);
|
|
1578
1578
|
// Resolve effective sync options with branch awareness
|
|
1579
|
-
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts, opts.promotion);
|
|
1579
|
+
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts, opts.promotion, opts.branch);
|
|
1580
1580
|
// Extract specific items configuration before merging overwrites gitBranches
|
|
1581
|
-
const specificItems = getSpecificItemsForCurrentBranch(opts);
|
|
1581
|
+
const specificItems = getSpecificItemsForCurrentBranch(opts, opts.branch);
|
|
1582
1582
|
// Merge CLI flags with resolved settings (CLI flags take precedence only for explicit overrides)
|
|
1583
1583
|
opts = mergeCliWithEffectiveOptions(originalCliOpts, effectiveOpts);
|
|
1584
1584
|
const codebases = await listSyncCodebases(opts);
|
|
@@ -1597,7 +1597,7 @@ export async function pull(opts) {
|
|
|
1597
1597
|
const local = !opts.stateful
|
|
1598
1598
|
? await FSFSElement(dntShim.Deno.cwd(), codebases, true)
|
|
1599
1599
|
: await FSFSElement(path.join(dntShim.Deno.cwd(), ".wmill"), [], true);
|
|
1600
|
-
const changes = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems);
|
|
1600
|
+
const changes = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, opts.branch);
|
|
1601
1601
|
log.info(`remote (${workspace.name}) -> local: ${changes.length} changes to apply`);
|
|
1602
1602
|
// Handle JSON output for dry-run
|
|
1603
1603
|
if (opts.dryRun && opts.jsonOutput) {
|
|
@@ -1612,7 +1612,7 @@ export async function pull(opts) {
|
|
|
1612
1612
|
...(specificItems && isSpecificItem(change.path, specificItems)
|
|
1613
1613
|
? {
|
|
1614
1614
|
branch_specific: true,
|
|
1615
|
-
branch_specific_path: getBranchSpecificPath(change.path, specificItems),
|
|
1615
|
+
branch_specific_path: getBranchSpecificPath(change.path, specificItems, opts.branch),
|
|
1616
1616
|
}
|
|
1617
1617
|
: {}),
|
|
1618
1618
|
})),
|
|
@@ -1623,7 +1623,7 @@ export async function pull(opts) {
|
|
|
1623
1623
|
}
|
|
1624
1624
|
if (changes.length > 0) {
|
|
1625
1625
|
if (!opts.jsonOutput) {
|
|
1626
|
-
prettyChanges(changes, specificItems);
|
|
1626
|
+
prettyChanges(changes, specificItems, opts.branch);
|
|
1627
1627
|
}
|
|
1628
1628
|
if (opts.dryRun) {
|
|
1629
1629
|
log.info(colors.gray(`Dry run complete.`));
|
|
@@ -1642,7 +1642,7 @@ export async function pull(opts) {
|
|
|
1642
1642
|
// Determine if this file should be written to a branch-specific path
|
|
1643
1643
|
let targetPath = change.path;
|
|
1644
1644
|
if (specificItems && isSpecificItem(change.path, specificItems)) {
|
|
1645
|
-
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems);
|
|
1645
|
+
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems, opts.branch);
|
|
1646
1646
|
if (branchSpecificPath) {
|
|
1647
1647
|
targetPath = branchSpecificPath;
|
|
1648
1648
|
}
|
|
@@ -1776,7 +1776,7 @@ export async function pull(opts) {
|
|
|
1776
1776
|
...(specificItems && isSpecificItem(change.path, specificItems)
|
|
1777
1777
|
? {
|
|
1778
1778
|
branch_specific: true,
|
|
1779
|
-
branch_specific_path: getBranchSpecificPath(change.path, specificItems),
|
|
1779
|
+
branch_specific_path: getBranchSpecificPath(change.path, specificItems, opts.branch),
|
|
1780
1780
|
}
|
|
1781
1781
|
: {}),
|
|
1782
1782
|
})),
|
|
@@ -1792,13 +1792,13 @@ export async function pull(opts) {
|
|
|
1792
1792
|
console.log(JSON.stringify({ success: true, message: "No changes to apply", total: 0 }, null, 2));
|
|
1793
1793
|
}
|
|
1794
1794
|
}
|
|
1795
|
-
function prettyChanges(changes, specificItems) {
|
|
1795
|
+
function prettyChanges(changes, specificItems, branchOverride) {
|
|
1796
1796
|
for (const change of changes) {
|
|
1797
1797
|
let displayPath = change.path;
|
|
1798
1798
|
let branchNote = "";
|
|
1799
1799
|
// Check if this will be written as a branch-specific file
|
|
1800
1800
|
if (specificItems && isSpecificItem(change.path, specificItems)) {
|
|
1801
|
-
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems);
|
|
1801
|
+
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems, branchOverride);
|
|
1802
1802
|
if (branchSpecificPath) {
|
|
1803
1803
|
displayPath = branchSpecificPath;
|
|
1804
1804
|
branchNote = " (branch-specific)";
|
|
@@ -1875,12 +1875,12 @@ export async function push(opts) {
|
|
|
1875
1875
|
}
|
|
1876
1876
|
throw error;
|
|
1877
1877
|
}
|
|
1878
|
-
const workspace = await resolveWorkspace(opts);
|
|
1878
|
+
const workspace = await resolveWorkspace(opts, opts.branch);
|
|
1879
1879
|
await requireLogin(opts);
|
|
1880
1880
|
// Resolve effective sync options with branch awareness
|
|
1881
|
-
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts, opts.promotion);
|
|
1881
|
+
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts, opts.promotion, opts.branch);
|
|
1882
1882
|
// Extract specific items configuration BEFORE merging overwrites gitBranches
|
|
1883
|
-
const specificItems = getSpecificItemsForCurrentBranch(opts);
|
|
1883
|
+
const specificItems = getSpecificItemsForCurrentBranch(opts, opts.branch);
|
|
1884
1884
|
// Merge CLI flags with resolved settings (CLI flags take precedence only for explicit overrides)
|
|
1885
1885
|
opts = mergeCliWithEffectiveOptions(originalCliOpts, effectiveOpts);
|
|
1886
1886
|
const codebases = await listSyncCodebases(opts);
|
|
@@ -1907,7 +1907,7 @@ export async function push(opts) {
|
|
|
1907
1907
|
}
|
|
1908
1908
|
const remote = ZipFSElement((await downloadZip(workspace, opts.plainSecrets, opts.skipVariables, opts.skipResources, opts.skipResourceTypes, opts.skipSecrets, opts.includeSchedules, opts.includeTriggers, opts.includeUsers, opts.includeGroups, opts.includeSettings, opts.includeKey, opts.skipWorkspaceDependencies, opts.defaultTs)), !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, false);
|
|
1909
1909
|
const local = await FSFSElement(path.join(dntShim.Deno.cwd(), ""), codebases, false);
|
|
1910
|
-
const changes = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems);
|
|
1910
|
+
const changes = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, opts.branch);
|
|
1911
1911
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies();
|
|
1912
1912
|
const tracker = await buildTracker(changes);
|
|
1913
1913
|
const staleScripts = [];
|
|
@@ -1974,7 +1974,7 @@ export async function push(opts) {
|
|
|
1974
1974
|
...(specificItems && isSpecificItem(change.path, specificItems)
|
|
1975
1975
|
? {
|
|
1976
1976
|
branch_specific: true,
|
|
1977
|
-
branch_specific_path: getBranchSpecificPath(change.path, specificItems),
|
|
1977
|
+
branch_specific_path: getBranchSpecificPath(change.path, specificItems, opts.branch),
|
|
1978
1978
|
}
|
|
1979
1979
|
: {}),
|
|
1980
1980
|
})),
|
|
@@ -1985,7 +1985,7 @@ export async function push(opts) {
|
|
|
1985
1985
|
}
|
|
1986
1986
|
if (changes.length > 0) {
|
|
1987
1987
|
if (!opts.jsonOutput) {
|
|
1988
|
-
prettyChanges(changes, specificItems);
|
|
1988
|
+
prettyChanges(changes, specificItems, opts.branch);
|
|
1989
1989
|
}
|
|
1990
1990
|
if (opts.dryRun) {
|
|
1991
1991
|
log.info(colors.gray(`Dry run complete.`));
|
|
@@ -2083,7 +2083,7 @@ export async function push(opts) {
|
|
|
2083
2083
|
// For branch-specific resources, push to the base path on the workspace server
|
|
2084
2084
|
// This ensures branch-specific files are stored with their base names in the workspace
|
|
2085
2085
|
let serverPath = resourceFilePath;
|
|
2086
|
-
const currentBranch = getCurrentGitBranch();
|
|
2086
|
+
const currentBranch = opts.branch || (isGitRepository() ? getCurrentGitBranch() : null);
|
|
2087
2087
|
if (currentBranch && isBranchSpecificFile(resourceFilePath)) {
|
|
2088
2088
|
serverPath = fromBranchSpecificPath(resourceFilePath, currentBranch);
|
|
2089
2089
|
}
|
|
@@ -2099,7 +2099,7 @@ export async function push(opts) {
|
|
|
2099
2099
|
// Check if this is a branch-specific item and get the original branch-specific path
|
|
2100
2100
|
let originalBranchSpecificPath;
|
|
2101
2101
|
if (specificItems && isSpecificItem(change.path, specificItems)) {
|
|
2102
|
-
originalBranchSpecificPath = getBranchSpecificPath(change.path, specificItems);
|
|
2102
|
+
originalBranchSpecificPath = getBranchSpecificPath(change.path, specificItems, opts.branch);
|
|
2103
2103
|
}
|
|
2104
2104
|
await pushObj(workspace.workspaceId, change.path, oldObj, newObj, opts.plainSecrets ?? false, alreadySynced, opts.message, originalBranchSpecificPath);
|
|
2105
2105
|
if (stateTarget) {
|
|
@@ -2125,7 +2125,7 @@ export async function push(opts) {
|
|
|
2125
2125
|
// For branch-specific items, we read from branch-specific files but push to base server paths
|
|
2126
2126
|
let localFilePath = change.path;
|
|
2127
2127
|
if (specificItems && isSpecificItem(change.path, specificItems)) {
|
|
2128
|
-
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems);
|
|
2128
|
+
const branchSpecificPath = getBranchSpecificPath(change.path, specificItems, opts.branch);
|
|
2129
2129
|
if (branchSpecificPath) {
|
|
2130
2130
|
localFilePath = branchSpecificPath;
|
|
2131
2131
|
}
|
|
@@ -2330,7 +2330,7 @@ export async function push(opts) {
|
|
|
2330
2330
|
...(specificItems && isSpecificItem(change.path, specificItems)
|
|
2331
2331
|
? {
|
|
2332
2332
|
branch_specific: true,
|
|
2333
|
-
branch_specific_path: getBranchSpecificPath(change.path, specificItems),
|
|
2333
|
+
branch_specific_path: getBranchSpecificPath(change.path, specificItems, opts.branch),
|
|
2334
2334
|
}
|
|
2335
2335
|
: {}),
|
|
2336
2336
|
})),
|
|
@@ -2379,6 +2379,7 @@ const command = new Command()
|
|
|
2379
2379
|
.option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy")
|
|
2380
2380
|
.option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist")
|
|
2381
2381
|
.option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides")
|
|
2382
|
+
.option("--branch <branch:string>", "Override the current git branch (works even outside a git repository)")
|
|
2382
2383
|
// deno-lint-ignore no-explicit-any
|
|
2383
2384
|
.action(pull)
|
|
2384
2385
|
.command("push")
|
|
@@ -2411,6 +2412,7 @@ const command = new Command()
|
|
|
2411
2412
|
.option("--message <message:string>", "Include a message that will be added to all scripts/flows/apps updated during this push")
|
|
2412
2413
|
.option("--parallel <number>", "Number of changes to process in parallel")
|
|
2413
2414
|
.option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist")
|
|
2415
|
+
.option("--branch <branch:string>", "Override the current git branch (works even outside a git repository)")
|
|
2414
2416
|
// deno-lint-ignore no-explicit-any
|
|
2415
2417
|
.action(push);
|
|
2416
2418
|
export default command;
|
package/esm/src/core/conf.js
CHANGED
|
@@ -268,60 +268,67 @@ export async function validateBranchConfiguration(opts) {
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
// Get effective settings by merging top-level settings with branch-specific overrides
|
|
271
|
-
export async function getEffectiveSettings(config, promotion, skipBranchValidation, suppressLogs) {
|
|
271
|
+
export async function getEffectiveSettings(config, promotion, skipBranchValidation, suppressLogs, branchOverride) {
|
|
272
272
|
// Start with top-level settings from config
|
|
273
273
|
const { gitBranches, ...topLevelSettings } = config;
|
|
274
274
|
const effective = { ...topLevelSettings };
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
// Determine the branch to use: branchOverride takes precedence, then git detection
|
|
276
|
+
let currentBranch = null;
|
|
277
|
+
let originalBranchIfForked = null;
|
|
278
|
+
let rawGitBranch = null;
|
|
279
|
+
if (branchOverride) {
|
|
280
|
+
currentBranch = branchOverride;
|
|
281
|
+
// Note: "Using branch override" is logged in context.ts when resolving workspace
|
|
282
|
+
}
|
|
283
|
+
else if (isGitRepository()) {
|
|
284
|
+
rawGitBranch = getCurrentGitBranch();
|
|
285
|
+
originalBranchIfForked = getOriginalBranchForWorkspaceForks(rawGitBranch);
|
|
279
286
|
if (originalBranchIfForked) {
|
|
280
287
|
log.info(`Using overrides from original branch \`${originalBranchIfForked}\``);
|
|
281
288
|
currentBranch = originalBranchIfForked;
|
|
282
289
|
}
|
|
283
290
|
else {
|
|
284
|
-
currentBranch =
|
|
291
|
+
currentBranch = rawGitBranch;
|
|
285
292
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (!suppressLogs) {
|
|
299
|
-
log.info(`Applied settings from branch: ${promotion} (no promotionOverrides found)`);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
log.debug(`No promotion or regular overrides found for branch '${promotion}', using top-level settings`);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
log.debug("Not in a Git repository and no branch override provided, using top-level settings");
|
|
296
|
+
}
|
|
297
|
+
// If promotion is specified, use that branch's promotionOverrides or overrides
|
|
298
|
+
if (promotion && gitBranches && gitBranches[promotion]) {
|
|
299
|
+
const targetBranch = gitBranches[promotion];
|
|
300
|
+
// First try promotionOverrides, then fall back to overrides
|
|
301
|
+
if (targetBranch.promotionOverrides) {
|
|
302
|
+
Object.assign(effective, targetBranch.promotionOverrides);
|
|
303
|
+
if (!suppressLogs) {
|
|
304
|
+
log.info(`Applied promotion settings from branch: ${promotion}`);
|
|
304
305
|
}
|
|
305
306
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
gitBranches &&
|
|
309
|
-
gitBranches[currentBranch] &&
|
|
310
|
-
gitBranches[currentBranch].overrides) {
|
|
311
|
-
Object.assign(effective, gitBranches[currentBranch].overrides);
|
|
307
|
+
else if (targetBranch.overrides) {
|
|
308
|
+
Object.assign(effective, targetBranch.overrides);
|
|
312
309
|
if (!suppressLogs) {
|
|
313
|
-
|
|
314
|
-
? ` (because it is the origin of the workspace fork branch \`${branch}\`)`
|
|
315
|
-
: "";
|
|
316
|
-
log.info(`Applied settings for Git branch: ${currentBranch}${extraLog}`);
|
|
310
|
+
log.info(`Applied settings from branch: ${promotion} (no promotionOverrides found)`);
|
|
317
311
|
}
|
|
318
312
|
}
|
|
319
|
-
else
|
|
320
|
-
log.debug(`No
|
|
313
|
+
else {
|
|
314
|
+
log.debug(`No promotion or regular overrides found for branch '${promotion}', using top-level settings`);
|
|
321
315
|
}
|
|
322
316
|
}
|
|
323
|
-
|
|
324
|
-
|
|
317
|
+
// Otherwise use current branch overrides (existing behavior)
|
|
318
|
+
else if (currentBranch &&
|
|
319
|
+
gitBranches &&
|
|
320
|
+
gitBranches[currentBranch] &&
|
|
321
|
+
gitBranches[currentBranch].overrides) {
|
|
322
|
+
Object.assign(effective, gitBranches[currentBranch].overrides);
|
|
323
|
+
if (!suppressLogs) {
|
|
324
|
+
const extraLog = originalBranchIfForked
|
|
325
|
+
? ` (because it is the origin of the workspace fork branch \`${rawGitBranch}\`)`
|
|
326
|
+
: "";
|
|
327
|
+
log.info(`Applied settings for Git branch: ${currentBranch}${extraLog}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else if (currentBranch) {
|
|
331
|
+
log.debug(`No branch-specific overrides found for '${currentBranch}', using top-level settings`);
|
|
325
332
|
}
|
|
326
333
|
return effective;
|
|
327
334
|
}
|
package/esm/src/core/context.js
CHANGED
|
@@ -114,24 +114,35 @@ async function tryResolveWorkspace(opts) {
|
|
|
114
114
|
error: colors.red.underline("No explicit workspace given."),
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
-
export async function tryResolveBranchWorkspace(opts) {
|
|
118
|
-
|
|
119
|
-
if (!isGitRepository()) {
|
|
120
|
-
return undefined;
|
|
121
|
-
}
|
|
122
|
-
const rawBranch = getCurrentGitBranch();
|
|
123
|
-
if (!rawBranch) {
|
|
124
|
-
return undefined;
|
|
125
|
-
}
|
|
117
|
+
export async function tryResolveBranchWorkspace(opts, branchOverride) {
|
|
118
|
+
let rawBranch = null;
|
|
126
119
|
let currentBranch;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
currentBranch =
|
|
120
|
+
let originalBranchIfForked = null;
|
|
121
|
+
let workspaceIdIfForked = null;
|
|
122
|
+
if (branchOverride) {
|
|
123
|
+
// Use branch override directly
|
|
124
|
+
currentBranch = branchOverride;
|
|
125
|
+
log.info(`Using branch override: ${branchOverride}`);
|
|
132
126
|
}
|
|
133
127
|
else {
|
|
134
|
-
|
|
128
|
+
// Only try branch-based resolution if in a Git repository
|
|
129
|
+
if (!isGitRepository()) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
rawBranch = getCurrentGitBranch();
|
|
133
|
+
if (!rawBranch) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
originalBranchIfForked = getOriginalBranchForWorkspaceForks(rawBranch);
|
|
137
|
+
workspaceIdIfForked =
|
|
138
|
+
getWorkspaceIdForWorkspaceForkFromBranchName(rawBranch);
|
|
139
|
+
if (originalBranchIfForked) {
|
|
140
|
+
log.info(`Using original branch \`${originalBranchIfForked}\` for finding workspace profile from gitBranches section in wmill.yaml`);
|
|
141
|
+
currentBranch = originalBranchIfForked;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
currentBranch = rawBranch;
|
|
145
|
+
}
|
|
135
146
|
}
|
|
136
147
|
// Read wmill.yaml to check for branch workspace configuration
|
|
137
148
|
const config = await readConfigFile();
|
|
@@ -155,7 +166,7 @@ export async function tryResolveBranchWorkspace(opts) {
|
|
|
155
166
|
const matchingProfiles = allProfiles.filter((w) => w.remote === normalizedBaseUrl && w.workspaceId === workspaceId);
|
|
156
167
|
if (matchingProfiles.length === 0) {
|
|
157
168
|
// No matching profile exists - prompt to create one
|
|
158
|
-
return await createWorkspaceProfileInteractively(normalizedBaseUrl, workspaceId, currentBranch, opts, { rawBranch, isForked: !!originalBranchIfForked });
|
|
169
|
+
return await createWorkspaceProfileInteractively(normalizedBaseUrl, workspaceId, currentBranch, opts, { rawBranch: rawBranch ?? currentBranch, isForked: !!originalBranchIfForked });
|
|
159
170
|
}
|
|
160
171
|
// Handle multiple profiles - use special branch-aware logic
|
|
161
172
|
let selectedProfile;
|
|
@@ -186,7 +197,7 @@ export async function tryResolveBranchWorkspace(opts) {
|
|
|
186
197
|
}
|
|
187
198
|
return selectedProfile;
|
|
188
199
|
}
|
|
189
|
-
export async function resolveWorkspace(opts) {
|
|
200
|
+
export async function resolveWorkspace(opts, branchOverride) {
|
|
190
201
|
const cache = opts.__secret_workspace;
|
|
191
202
|
if (cache)
|
|
192
203
|
return cache;
|
|
@@ -239,12 +250,12 @@ export async function resolveWorkspace(opts) {
|
|
|
239
250
|
return dntShim.Deno.exit(-1);
|
|
240
251
|
}
|
|
241
252
|
}
|
|
242
|
-
const branch = getCurrentGitBranch();
|
|
253
|
+
const branch = branchOverride ?? getCurrentGitBranch();
|
|
243
254
|
// Try explicit workspace flag first (should override branch-based resolution). Unless it's a
|
|
244
|
-
// forked workspace, that we detect through the branch name
|
|
255
|
+
// forked workspace, that we detect through the branch name (only when not using branchOverride)
|
|
245
256
|
const res = await tryResolveWorkspace(opts);
|
|
246
257
|
if (!res.isError) {
|
|
247
|
-
if (!branch || !branch.startsWith(WM_FORK_PREFIX)) {
|
|
258
|
+
if (branchOverride || !branch || !branch.startsWith(WM_FORK_PREFIX)) {
|
|
248
259
|
return res.value;
|
|
249
260
|
}
|
|
250
261
|
else {
|
|
@@ -252,12 +263,13 @@ export async function resolveWorkspace(opts) {
|
|
|
252
263
|
}
|
|
253
264
|
}
|
|
254
265
|
// Try branch-based resolution (medium priority)
|
|
255
|
-
const branchWorkspace = await tryResolveBranchWorkspace(opts);
|
|
266
|
+
const branchWorkspace = await tryResolveBranchWorkspace(opts, branchOverride);
|
|
256
267
|
if (branchWorkspace) {
|
|
257
268
|
opts.__secret_workspace = branchWorkspace;
|
|
258
269
|
return branchWorkspace;
|
|
259
270
|
}
|
|
260
|
-
else {
|
|
271
|
+
else if (!branchOverride) {
|
|
272
|
+
// Only check for fork errors when not using branchOverride
|
|
261
273
|
const originalBranch = getOriginalBranchForWorkspaceForks(branch);
|
|
262
274
|
if (originalBranch) {
|
|
263
275
|
log.error(colors.red.bold(`Failed to resolve workspace profile for workspace fork. This most likely means that the original branch \`${originalBranch}\` where \`${branch}\` is originally forked from, is not setup in the wmill.yaml. You need to update the \`gitBranches\` section for \`${originalBranch}\` to include workspaceId and baseUrl.`));
|
|
@@ -44,11 +44,18 @@ function buildYamlTypePattern() {
|
|
|
44
44
|
* Get the specific items configuration for the current git branch
|
|
45
45
|
* Merges commonSpecificItems with branch-specific specificItems
|
|
46
46
|
*/
|
|
47
|
-
export function getSpecificItemsForCurrentBranch(config) {
|
|
48
|
-
if (!
|
|
47
|
+
export function getSpecificItemsForCurrentBranch(config, branchOverride) {
|
|
48
|
+
if (!config.gitBranches) {
|
|
49
49
|
return undefined;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
// Use branch override if provided, otherwise detect from git
|
|
52
|
+
let currentBranch = null;
|
|
53
|
+
if (branchOverride) {
|
|
54
|
+
currentBranch = branchOverride;
|
|
55
|
+
}
|
|
56
|
+
else if (isGitRepository()) {
|
|
57
|
+
currentBranch = getCurrentGitBranch();
|
|
58
|
+
}
|
|
52
59
|
if (!currentBranch) {
|
|
53
60
|
return undefined;
|
|
54
61
|
}
|
|
@@ -173,11 +180,18 @@ export function fromBranchSpecificPath(branchSpecificPath, branchName) {
|
|
|
173
180
|
/**
|
|
174
181
|
* Get the branch-specific path for the current branch if the item should be branch-specific
|
|
175
182
|
*/
|
|
176
|
-
export function getBranchSpecificPath(basePath, specificItems) {
|
|
177
|
-
if (!
|
|
183
|
+
export function getBranchSpecificPath(basePath, specificItems, branchOverride) {
|
|
184
|
+
if (!specificItems) {
|
|
178
185
|
return undefined;
|
|
179
186
|
}
|
|
180
|
-
|
|
187
|
+
// Use branch override if provided, otherwise detect from git
|
|
188
|
+
let currentBranch = null;
|
|
189
|
+
if (branchOverride) {
|
|
190
|
+
currentBranch = branchOverride;
|
|
191
|
+
}
|
|
192
|
+
else if (isGitRepository()) {
|
|
193
|
+
currentBranch = getCurrentGitBranch();
|
|
194
|
+
}
|
|
181
195
|
if (!currentBranch) {
|
|
182
196
|
return undefined;
|
|
183
197
|
}
|
|
@@ -191,11 +205,15 @@ const branchPatternCache = new Map();
|
|
|
191
205
|
/**
|
|
192
206
|
* Check if a path is a branch-specific file for the current branch
|
|
193
207
|
*/
|
|
194
|
-
export function isCurrentBranchFile(path) {
|
|
195
|
-
if
|
|
196
|
-
|
|
208
|
+
export function isCurrentBranchFile(path, branchOverride) {
|
|
209
|
+
// Use branch override if provided, otherwise detect from git
|
|
210
|
+
let currentBranch = null;
|
|
211
|
+
if (branchOverride) {
|
|
212
|
+
currentBranch = branchOverride;
|
|
213
|
+
}
|
|
214
|
+
else if (isGitRepository()) {
|
|
215
|
+
currentBranch = getCurrentGitBranch();
|
|
197
216
|
}
|
|
198
|
-
const currentBranch = getCurrentGitBranch();
|
|
199
217
|
if (!currentBranch) {
|
|
200
218
|
return false;
|
|
201
219
|
}
|
package/esm/src/main.js
CHANGED
|
@@ -40,7 +40,7 @@ export { flow, app, script, workspace, resource, resourceType, user, variable, h
|
|
|
40
40
|
// console.error(JSON.stringify(event.error, null, 4));
|
|
41
41
|
// }
|
|
42
42
|
// });
|
|
43
|
-
export const VERSION = "1.
|
|
43
|
+
export const VERSION = "1.610.1";
|
|
44
44
|
// Re-exported from constants.ts to maintain backwards compatibility
|
|
45
45
|
export { WM_FORK_PREFIX } from "./core/constants.js";
|
|
46
46
|
const command = new Command()
|