fix: codebases compatible with git sync (#5470)

This commit is contained in:
Ruben Fiszel
2025-03-11 19:38:55 +01:00
committed by GitHub
parent 4a23688705
commit bd7586a5ee
9 changed files with 202 additions and 162 deletions
+2 -2
View File
@@ -333,7 +333,7 @@ you to have it being synced automatically everyday.
## Environment Variables
| Environment Variable name | Default | Description | Api Server/Worker/All |
| ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | --- | ------ |
| ----------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| DATABASE_URL | | The Postgres database url. | All |
| WORKER_GROUP | default | The worker group the worker belongs to and get its configuration pulled from | Worker |
| MODE | standalone | The mode if the binary. Possible values: standalone, worker, server, agent | All |
@@ -352,7 +352,7 @@ you to have it being synced automatically everyday.
| GO_PATH | /usr/bin/go | The path to the go binary. | Worker |
| GOPRIVATE | | The GOPRIVATE env variable to use private go modules | Worker |
| GOPROXY | | The GOPROXY env variable to use | Worker |
| NETRC | | The netrc content to use a private go registry | Worker | | Worker |
| NETRC | | The netrc content to use a private go registry | Worker |
| PY_CONCURRENT_DOWNLOADS | 20 | Sets the maximum number of in-flight concurrent python downloads that windmill will perform at any given time. | Worker |
| PATH | None | The path environment variable, usually inherited | Worker |
| HOME | None | The home directory to use for Go and Bash , usually inherited | Worker |
+14 -12
View File
@@ -659,17 +659,6 @@ Windmill Community Edition {GIT_VERSION}
tracing::info!("received killpill for monitor job");
break;
},
_ = tokio::time::sleep(Duration::from_secs(30)) => {
monitor_db(
&db,
&base_internal_url,
server_mode,
worker_mode,
false,
tx.clone(),
)
.await;
},
notification = listener.recv() => {
match notification {
Ok(n) => {
@@ -857,7 +846,20 @@ Windmill Community Edition {GIT_VERSION}
}
}
};
}
},
_ = tokio::time::sleep(Duration::from_secs(30)) => {
tracing::info!("monitor task started");
monitor_db(
&db,
&base_internal_url,
server_mode,
worker_mode,
false,
tx.clone(),
)
.await;
tracing::info!("monitor task finished");
},
}
}
});
@@ -147,6 +147,7 @@ pub(crate) struct ArchiveQueryParams {
skip_secrets: Option<bool>,
skip_variables: Option<bool>,
skip_resources: Option<bool>,
skip_resource_types: Option<bool>,
include_schedules: Option<bool>,
include_triggers: Option<bool>,
include_users: Option<bool>,
@@ -280,6 +281,7 @@ pub(crate) async fn tarball_workspace(
plain_secret,
plain_secrets,
skip_resources,
skip_resource_types,
skip_secrets,
skip_variables,
include_schedules,
@@ -428,7 +430,7 @@ pub(crate) async fn tarball_workspace(
}
}
if !skip_resources.unwrap_or(false) {
if !skip_resource_types.unwrap_or(false) {
let resource_types = sqlx::query_as!(
ResourceType,
"SELECT * FROM resource_type WHERE workspace_id = $1",
+19 -13
View File
@@ -2,25 +2,31 @@ import { Codebase, SyncOptions } from "./conf.ts";
import { log } from "./deps.ts";
import { digestDir } from "./utils.ts";
export type SyncCodebase = Codebase & { digest: string };
export async function listSyncCodebases(
export type SyncCodebase = Codebase & { getDigest: () => Promise<string> };
export function listSyncCodebases(
options: SyncOptions
): Promise<SyncCodebase[]> {
): SyncCodebase[] {
const res: SyncCodebase[] = [];
const nb_codebase = options?.codebases?.length ?? 0;
if (nb_codebase > 0) {
log.info(`Found ${nb_codebase} codebases:`);
log.info(`Found ${nb_codebase} codebases: ${options?.codebases?.map((c) => c.relative_path).join(", ")}`);
}
for (const codebase of options?.codebases ?? []) {
let digest = await digestDir(
codebase.relative_path,
JSON.stringify(codebase)
);
if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
digest += ".tar";
}
log.info(`Codebase ${codebase.relative_path}, digest: ${digest}`);
res.push({ ...codebase, digest });
let _digest: string | undefined = undefined;
const getDigest: () => Promise<string> = async () => {
if (_digest == undefined) {
_digest = await digestDir(
codebase.relative_path,
JSON.stringify(codebase)
);
if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
_digest += ".tar";
}
log.info(`Codebase ${codebase.relative_path}, digest: ${_digest}`);
}
return _digest;
};
res.push({ ...codebase, getDigest });
}
return res;
+1
View File
@@ -10,6 +10,7 @@ export interface SyncOptions {
json?: boolean;
skipVariables?: boolean;
skipResources?: boolean;
skipResourceTypes?: boolean;
skipSecrets?: boolean;
includeSchedules?: boolean;
includeTriggers?: boolean;
+1 -1
View File
@@ -98,7 +98,7 @@ function findClosestRawReqs(
const TOP_HASH = "__flow_hash";
async function generateFlowHash(folder: string) {
const elems = await FSFSElement(path.join(Deno.cwd(), folder), []);
const elems = await FSFSElement(path.join(Deno.cwd(), folder), [], true);
const hashes: Record<string, string> = {};
for await (const f of elems.getChildren()) {
if (exts.some((e) => f.path.endsWith(e))) {
+9 -13
View File
@@ -9,6 +9,7 @@ export async function downloadZip(
plainSecrets: boolean | undefined,
skipVariables?: boolean,
skipResources?: boolean,
skipResourceTypes?: boolean,
skipSecrets?: boolean,
includeSchedules?: boolean,
includeTriggers?: boolean,
@@ -31,19 +32,14 @@ export async function downloadZip(
const zipResponse = await fetch(
workspace.remote +
"api/w/" +
workspace.workspaceId +
`/workspaces/tarball?archive_type=zip&plain_secret=${
plainSecrets ?? false
}&skip_variables=${skipVariables ?? false}&skip_resources=${
skipResources ?? false
}&skip_secrets=${skipSecrets ?? false}&include_schedules=${
includeSchedules ?? false
}&include_triggers=${includeTriggers ?? false}&include_users=${
includeUsers ?? false
}&include_groups=${includeGroups ?? false}&include_settings=${
includeSettings ?? false
}&include_key=${includeKey ?? false}&default_ts=${defaultTs ?? "bun"}`,
"api/w/" +
workspace.workspaceId +
`/workspaces/tarball?archive_type=zip&plain_secret=${plainSecrets ?? false
}&skip_variables=${skipVariables ?? false}&skip_resources=${skipResources ?? false
}&skip_secrets=${skipSecrets ?? false}&include_schedules=${includeSchedules ?? false
}&include_triggers=${includeTriggers ?? false}&include_users=${includeUsers ?? false
}&include_groups=${includeGroups ?? false}&include_settings=${includeSettings ?? false
}&include_key=${includeKey ?? false}&default_ts=${defaultTs ?? "bun"}&skip_resource_types=${skipResourceTypes ?? false}`,
{
headers: requestHeaders,
method: "GET",
+29 -32
View File
@@ -119,7 +119,7 @@ export async function findResourceFile(path: string) {
if (validCandidates.length > 1) {
throw new Error(
"Found two resource files for the same resource" +
validCandidates.join(", ")
validCandidates.join(", ")
);
}
if (validCandidates.length < 1) {
@@ -249,20 +249,20 @@ export async function handleFile(
let typed = opts?.skipScriptsMetadata
? undefined
: (
await parseMetadataFile(
remotePath,
opts
? {
...opts,
path,
workspaceRemote: workspace,
schemaOnly: codebase ? true : undefined,
}
: undefined,
globalDeps,
codebases
)
)?.payload;
await parseMetadataFile(
remotePath,
opts
? {
...opts,
path,
workspaceRemote: workspace,
schemaOnly: codebase ? true : undefined,
}
: undefined,
globalDeps,
codebases
)
)?.payload;
const workspaceId = workspace.workspaceId;
@@ -300,7 +300,7 @@ export async function handleFile(
}
if (typed && codebase) {
typed.codebase = codebase.digest;
typed.codebase = await codebase.getDigest();
}
const requestBodyCommon: NewScript = {
@@ -325,8 +325,7 @@ export async function handleFile(
has_preprocessor: typed?.has_preprocessor,
priority: typed?.priority,
concurrency_key: typed?.concurrency_key,
//@ts-ignore
codebase: codebase?.digest,
codebase: await codebase?.getDigest(),
timeout: typed?.timeout,
on_behalf_of_email: typed?.on_behalf_of_email,
};
@@ -348,19 +347,19 @@ export async function handleFile(
deepEqual(typed.schema, remote.schema) &&
typed.tag == remote.tag &&
(typed.ws_error_handler_muted ?? false) ==
remote.ws_error_handler_muted &&
remote.ws_error_handler_muted &&
typed.dedicated_worker == remote.dedicated_worker &&
typed.cache_ttl == remote.cache_ttl &&
typed.concurrency_time_window_s ==
remote.concurrency_time_window_s &&
remote.concurrency_time_window_s &&
typed.concurrent_limit == remote.concurrent_limit &&
Boolean(typed.restart_unless_cancelled) ==
Boolean(remote.restart_unless_cancelled) &&
Boolean(remote.restart_unless_cancelled) &&
Boolean(typed.visible_to_runner_only) ==
Boolean(remote.visible_to_runner_only) &&
Boolean(remote.visible_to_runner_only) &&
Boolean(typed.no_main_func) == Boolean(remote.no_main_func) &&
Boolean(typed.has_preprocessor) ==
Boolean(remote.has_preprocessor) &&
Boolean(remote.has_preprocessor) &&
typed.priority == Boolean(remote.priority) &&
typed.timeout == remote.timeout &&
//@ts-ignore
@@ -451,8 +450,7 @@ async function createScript(
});
} catch (e: any) {
throw Error(
`Script creation for ${body.path} with parent ${
body.parent_hash
`Script creation for ${body.path} with parent ${body.parent_hash
} was not successful: ${e.body ?? e.message} `
);
}
@@ -478,8 +476,7 @@ async function createScript(
});
if (req.status != 201) {
throw Error(
`Script snapshot creation was not successful: ${req.status} - ${
req.statusText
`Script snapshot creation was not successful: ${req.status} - ${req.statusText
} - ${await req.text()} `
);
}
@@ -491,8 +488,8 @@ export async function findContentFile(filePath: string) {
const candidates = filePath.endsWith("script.json")
? exts.map((x) => filePath.replace(".script.json", x))
: filePath.endsWith("script.lock")
? exts.map((x) => filePath.replace(".script.lock", x))
: exts.map((x) => filePath.replace(".script.yaml", x));
? exts.map((x) => filePath.replace(".script.lock", x))
: exts.map((x) => filePath.replace(".script.yaml", x));
const validCandidates = (
await Promise.all(
@@ -511,7 +508,7 @@ export async function findContentFile(filePath: string) {
if (validCandidates.length > 1) {
throw new Error(
"No content path given and more than one candidate found: " +
validCandidates.join(", ")
validCandidates.join(", ")
);
}
if (validCandidates.length < 1) {
@@ -864,7 +861,7 @@ export async function findGlobalDeps(): Promise<GlobalDeps> {
const pkgs: { [key: string]: string } = {};
const reqs: { [key: string]: string } = {};
const composers: { [key: string]: string } = {};
const els = await FSFSElement(Deno.cwd(), []);
const els = await FSFSElement(Deno.cwd(), [], false);
for await (const entry of readDirRecursiveWithIgnore((p, isDir) => {
p = SEP + p;
return (
@@ -927,7 +924,7 @@ async function generateMetadata(
} else {
const ignore = await ignoreF(opts);
const elems = await elementsToMap(
await FSFSElement(Deno.cwd(), codebases),
await FSFSElement(Deno.cwd(), codebases, false),
(p, isD) => {
return (
(!isD && !exts.some((ext) => p.endsWith(ext))) ||
+124 -88
View File
@@ -94,7 +94,8 @@ export function findCodebase(
async function addCodebaseDigestIfRelevant(
path: string,
content: string,
codebases: SyncCodebase[]
codebases: SyncCodebase[],
ignoreCodebaseChanges: boolean
): Promise<string> {
const isScript = path.endsWith(".script.yaml");
if (!isScript) {
@@ -115,7 +116,11 @@ async function addCodebaseDigestIfRelevant(
if (c) {
const parsed: any = yamlParseContent(path, content);
if (parsed && typeof parsed == "object") {
parsed["codebase"] = c.digest;
if (ignoreCodebaseChanges) {
parsed["codebase"] = undefined
} else {
parsed["codebase"] = await c.getDigest();
}
parsed["lock"] = "";
return yamlStringify(parsed, yamlOptions);
} else {
@@ -130,7 +135,8 @@ async function addCodebaseDigestIfRelevant(
export async function FSFSElement(
p: string,
codebases: SyncCodebase[]
codebases: SyncCodebase[],
ignoreCodebaseChanges: boolean
): Promise<DynFSElement> {
function _internal_element(
localP: string,
@@ -163,7 +169,8 @@ export async function FSFSElement(
const r = await addCodebaseDigestIfRelevant(
itemPath,
content,
codebases
codebases,
ignoreCodebaseChanges
);
return r;
},
@@ -345,7 +352,8 @@ function ZipFSElement(
zip: JSZip,
useYaml: boolean,
defaultTs: "bun" | "deno",
resourceTypeToFormatExtension: Record<string, string>
resourceTypeToFormatExtension: Record<string, string>,
ignoreCodebaseChanges: boolean
): DynFSElement {
async function _internal_file(
p: string,
@@ -356,12 +364,12 @@ function ZipFSElement(
)
? "flow"
: p.endsWith("app.json")
? "app"
: p.endsWith("script.json")
? "script"
: p.endsWith("resource.json")
? "resource"
: "other";
? "app"
: p.endsWith("script.json")
? "script"
: p.endsWith("resource.json")
? "resource"
: "other";
const isJson = p.endsWith(".json");
@@ -391,7 +399,7 @@ function ZipFSElement(
yield {
isDirectory: false,
path: path.join(finalPath, s.path),
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return s.content;
@@ -402,7 +410,7 @@ function ZipFSElement(
yield {
isDirectory: false,
path: path.join(finalPath, "flow.yaml"),
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return yamlStringify(flow, yamlOptions);
@@ -418,7 +426,7 @@ function ZipFSElement(
yield {
isDirectory: false,
path: path.join(finalPath, s.path),
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return s.content;
@@ -429,7 +437,7 @@ function ZipFSElement(
yield {
isDirectory: false,
path: path.join(finalPath, "app.yaml"),
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return yamlStringify(app, yamlOptions);
@@ -457,6 +465,9 @@ function ZipFSElement(
} else {
parsed["lock"] = undefined;
}
if (ignoreCodebaseChanges && parsed["codebase"]) {
parsed["codebase"] = undefined;
}
return useYaml
? yamlStringify(parsed, yamlOptions)
: JSON.stringify(parsed, null, 2);
@@ -494,7 +505,7 @@ function ZipFSElement(
r.push({
isDirectory: false,
path: removeSuffix(finalPath, ".json") + ".lock",
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return lock;
@@ -517,7 +528,7 @@ function ZipFSElement(
removeSuffix(finalPath, ".resource.json") +
".resource.file." +
formatExtension,
async *getChildren() {},
async *getChildren() { },
// deno-lint-ignore require-await
async getContentText() {
return fileContent;
@@ -578,19 +589,19 @@ export async function* readDirRecursiveWithIgnore(
// getContentBytes(): Promise<Uint8Array>;
getContentText(): Promise<string>;
}[] = [
{
path: root.path,
ignored: ignore(root.path, root.isDirectory),
isDirectory: root.isDirectory,
c: root.getChildren,
// getContentBytes(): Promise<Uint8Array> {
// throw undefined;
// },
getContentText(): Promise<string> {
throw undefined;
{
path: root.path,
ignored: ignore(root.path, root.isDirectory),
isDirectory: root.isDirectory,
c: root.getChildren,
// getContentBytes(): Promise<Uint8Array> {
// throw undefined;
// },
getContentText(): Promise<string> {
throw undefined;
},
},
},
];
];
while (stack.length > 0) {
const e = stack.pop()!;
@@ -653,9 +664,10 @@ export async function elementsToMap(
if (!skips.includeSettings && path === "settings" + ext) continue;
if (!skips.includeKey && path === "encryption_key") continue;
if (skips.skipResources && path.endsWith(".resource" + ext)) continue;
if (skips.skipResourceTypes && path.endsWith(".resource-type" + ext)) continue;
if (skips.skipVariables && path.endsWith(".variable" + ext)) continue;
if (skips.skipResources && path.endsWith(".resource" + ext)) continue;
if (skips.skipResources && isFileResource(path)) continue;
if (
@@ -704,6 +716,7 @@ export async function elementsToMap(
export interface Skips {
skipVariables?: boolean | undefined;
skipResources?: boolean | undefined;
skipResourceTypes?: boolean | undefined;
skipSecrets?: boolean | undefined;
skipScriptsMetadata?: boolean | undefined;
includeSchedules?: boolean | undefined;
@@ -721,13 +734,14 @@ async function compareDynFSElement(
json: boolean,
skips: Skips,
ignoreMetadataDeletion: boolean,
codebases: SyncCodebase[]
codebases: SyncCodebase[],
ignoreCodebaseChanges: boolean
): Promise<Change[]> {
const [m1, m2] = els2
? await Promise.all([
elementsToMap(els1, ignore, json, skips),
elementsToMap(els2, ignore, json, skips),
])
elementsToMap(els1, ignore, json, skips),
elementsToMap(els2, ignore, json, skips),
])
: [await elementsToMap(els1, ignore, json, skips), {}];
const changes: Change[] = [];
@@ -761,7 +775,9 @@ async function compareDynFSElement(
return yamlParseContent(k, v);
}
}
const codebaseChanges: Record<string, string> = {};
for (let [k, v] of Object.entries(m1)) {
const isScriptMetadata =
k.endsWith(".script.yaml") || k.endsWith(".script.json");
@@ -785,16 +801,19 @@ async function compareDynFSElement(
if (deepEqual(before, after)) {
continue;
}
if (before.codebase != undefined) {
delete before.codebase;
m2[k] = yamlStringify(before, yamlOptions);
}
if (after.codebase != undefined) {
if (before.codebase != after.codebase) {
codebaseChanges[k] = after.codebase;
if (!ignoreCodebaseChanges) {
if (before.codebase != undefined) {
delete before.codebase;
m2[k] = yamlStringify(before, yamlOptions);
}
if (after.codebase != undefined) {
if (before.codebase != after.codebase) {
codebaseChanges[k] = after.codebase;
}
delete after.codebase;
v = yamlStringify(after, yamlOptions);
}
delete after.codebase;
v = yamlStringify(after, yamlOptions);
}
if (skipMetadata) {
continue;
@@ -810,6 +829,7 @@ async function compareDynFSElement(
}
}
const remoteCodebase: Record<string, string> = {};
for (const [k] of Object.entries(m2)) {
if (m1[k] === undefined) {
@@ -827,34 +847,38 @@ async function compareDynFSElement(
}
}
for (const [k, v] of Object.entries(remoteCodebase)) {
const tsFile = k.replace(".script.yaml", ".ts");
if (
changes.find(
(c) => c.path == tsFile && (c.name == "edited" || c.name == "deleted")
)
) {
continue;
}
let c = findCodebase(tsFile, codebases);
if (c?.digest != v) {
changes.push({
name: "edited",
path: tsFile,
codebase: v,
before: m1[tsFile],
after: m2[tsFile],
});
if (!ignoreCodebaseChanges) {
for (const [k, v] of Object.entries(remoteCodebase)) {
const tsFile = k.replace(".script.yaml", ".ts");
if (
changes.find(
(c) => c.path == tsFile && (c.name == "edited" || c.name == "deleted")
)
) {
continue;
}
const c = findCodebase(tsFile, codebases);
if (await c?.getDigest() != v) {
changes.push({
name: "edited",
path: tsFile,
codebase: v,
before: m1[tsFile],
after: m2[tsFile],
});
}
}
}
for (const change of changes) {
const codebase = codebaseChanges[change.path];
if (!codebase) continue;
if (!ignoreCodebaseChanges) {
for (const change of changes) {
const codebase = codebaseChanges[change.path];
if (!codebase) continue;
const tsFile = change.path.replace(".script.yaml", ".ts");
if (change.name == "edited" && change.path == tsFile) {
change.codebase = codebase;
const tsFile = change.path.replace(".script.yaml", ".ts");
if (change.name == "edited" && change.path == tsFile) {
change.codebase = codebase;
}
}
}
@@ -960,6 +984,8 @@ export async function ignoreF(wmillconf: {
includes?: string[];
excludes?: string[];
extraIncludes?: string[];
skipResourceTypes?: boolean;
json?: boolean;
}): Promise<(p: string, isDirectory: boolean) => boolean> {
let whitelist: { approve(file: string): boolean } | undefined = undefined;
@@ -991,6 +1017,10 @@ export async function ignoreF(wmillconf: {
// new Gitignore.default({ initialRules: ignoreContent.split("\n")}).ignoreContent).compile();
return (p: string, isDirectory: boolean) => {
const ext = wmillconf.json ? ".json" : ".yaml";
if (!isDirectory && p.endsWith(".resource-type" + ext)) {
return wmillconf.skipResourceTypes ?? false;
}
return (
!isWhitelisted(p) &&
(isNotWmillFile(p, isDirectory) ||
@@ -1082,6 +1112,7 @@ export async function pull(opts: GlobalOptions & SyncOptions) {
opts.plainSecrets,
opts.skipVariables,
opts.skipResources,
opts.skipResourceTypes,
opts.skipSecrets,
opts.includeSchedules,
opts.includeTriggers,
@@ -1089,15 +1120,16 @@ export async function pull(opts: GlobalOptions & SyncOptions) {
opts.includeGroups,
opts.includeSettings,
opts.includeKey,
opts.defaultTs
opts.defaultTs,
))!,
!opts.json,
opts.defaultTs ?? "bun",
resourceTypeToFormatExtension
resourceTypeToFormatExtension,
true
);
const local = !opts.stateful
? await FSFSElement(Deno.cwd(), codebases)
: await FSFSElement(path.join(Deno.cwd(), ".wmill"), []);
? await FSFSElement(Deno.cwd(), codebases, true)
: await FSFSElement(path.join(Deno.cwd(), ".wmill"), [], true);
const changes = await compareDynFSElement(
remote,
local,
@@ -1105,7 +1137,8 @@ export async function pull(opts: GlobalOptions & SyncOptions) {
opts.json ?? false,
opts,
false,
codebases
codebases,
true
);
log.info(
@@ -1278,8 +1311,8 @@ function prettyChanges(changes: Change[]) {
log.info(
colors.yellow(
`~ ${getTypeStrFromPath(change.path)} ` +
change.path +
(change.codebase ? ` (codebase changed)` : "")
change.path +
(change.codebase ? ` (codebase changed)` : "")
)
);
if (change.before != change.after) {
@@ -1354,6 +1387,7 @@ export async function push(opts: GlobalOptions & SyncOptions) {
opts.plainSecrets,
opts.skipVariables,
opts.skipResources,
opts.skipResourceTypes,
opts.skipSecrets,
opts.includeSchedules,
opts.includeTriggers,
@@ -1361,14 +1395,15 @@ export async function push(opts: GlobalOptions & SyncOptions) {
opts.includeGroups,
opts.includeSettings,
opts.includeKey,
opts.defaultTs
opts.defaultTs,
))!,
!opts.json,
opts.defaultTs ?? "bun",
resourceTypeToFormatExtension
resourceTypeToFormatExtension,
false
);
const local = await FSFSElement(path.join(Deno.cwd(), ""), codebases);
const local = await FSFSElement(path.join(Deno.cwd(), "",), codebases, false);
const changes = await compareDynFSElement(
local,
remote,
@@ -1376,12 +1411,12 @@ export async function push(opts: GlobalOptions & SyncOptions) {
opts.json ?? false,
opts,
true,
codebases
codebases,
false
);
const globalDeps = await findGlobalDeps();
console.log("globalDeps", globalDeps);
const tracker: ChangeTracker = await buildTracker(changes);
@@ -1486,8 +1521,7 @@ export async function push(opts: GlobalOptions & SyncOptions) {
}
const groupedChangesArray = Array.from(groupedChanges.entries());
log.info(
`found changes for ${
groupedChangesArray.length
`found changes for ${groupedChangesArray.length
} items with a total of ${groupedChangesArray.reduce(
(acc, [_, changes]) => acc + changes.length,
0
@@ -1729,11 +1763,11 @@ export async function push(opts: GlobalOptions & SyncOptions) {
});
break;
case "mqtt_trigger":
await wmill.deleteMqttTrigger({
workspace: workspaceId,
path: removeSuffix(target, ".mqtt_trigger.json"),
});
break;
await wmill.deleteMqttTrigger({
workspace: workspaceId,
path: removeSuffix(target, ".mqtt_trigger.json"),
});
break;
case "sqs_trigger":
await wmill.deleteSqsTrigger({
workspace: workspaceId,
@@ -1800,8 +1834,7 @@ export async function push(opts: GlobalOptions & SyncOptions) {
}
log.info(
colors.bold.green.underline(
`\nDone! All ${changes.length} changes pushed to the remote workspace ${
workspace.workspaceId
`\nDone! All ${changes.length} changes pushed to the remote workspace ${workspace.workspaceId
} named ${workspace.name} (${(performance.now() - start).toFixed(0)}ms)`
)
);
@@ -1824,6 +1857,7 @@ const command = new Command()
.option("--skip-variables", "Skip syncing variables (including secrets)")
.option("--skip-secrets", "Skip syncing only secrets variables")
.option("--skip-resources", "Skip syncing resources")
.option("--skip-resource-types", "Skip syncing resource types")
// .option("--skip-scripts-metadata", "Skip syncing scripts metadata, focus solely on logic")
.option("--include-schedules", "Include syncing schedules")
.option("--include-triggers", "Include syncing triggers")
@@ -1853,6 +1887,8 @@ const command = new Command()
.option("--skip-variables", "Skip syncing variables (including secrets)")
.option("--skip-secrets", "Skip syncing only secrets variables")
.option("--skip-resources", "Skip syncing resources")
.option("--skip-resource-types", "Skip syncing resource types")
// .option("--skip-scripts-metadata", "Skip syncing scripts metadata, focus solely on logic")
.option("--include-schedules", "Include syncing schedules")
.option("--include-triggers", "Include syncing triggers")