Merge pull request #389 from pikasTech/ymalops-round23

ymal-first Round 23:LangBot/n8n target 默认值改由 YAML 声明
This commit is contained in:
Lyon
2026-06-14 20:25:08 +08:00
committed by GitHub
4 changed files with 47 additions and 14 deletions
+3
View File
@@ -7,6 +7,9 @@ metadata:
relatedIssues:
- 297
defaults:
targetId: G14
image:
repository: rockchin/langbot
tag: v4.10.1
+3
View File
@@ -7,6 +7,9 @@ metadata:
relatedIssues:
- 300
defaults:
targetId: G14
image:
repository: n8nio/n8n
tag: "1.123.55"
+22 -8
View File
@@ -53,6 +53,7 @@ interface LangBotConfig {
version: number;
kind: "platform-infra-langbot";
metadata: { id: string; owner: string; relatedIssues: number[] };
defaults: { targetId: string };
image: { repository: string; tag: string; pullPolicy: "Always" | "IfNotPresent" | "Never" };
dependencyImages: { postgresClient: string };
targets: LangBotTarget[];
@@ -127,7 +128,7 @@ interface PublicExposure {
}
interface CommonOptions {
targetId: string;
targetId: string | null;
full: boolean;
raw: boolean;
}
@@ -197,7 +198,7 @@ export async function runLangBotCommand(config: UniDeskConfig, args: string[]):
}
function parseCommonOptions(args: string[]): CommonOptions {
let targetId = "G14";
let targetId: string | null = null;
let full = false;
let raw = false;
for (let index = 0; index < args.length; index += 1) {
@@ -216,7 +217,7 @@ function parseCommonOptions(args: string[]): CommonOptions {
throw new Error(`unsupported langbot option: ${arg}`);
}
}
if (!/^[A-Za-z0-9._-]+$/u.test(targetId)) throw new Error("--target must be a simple target id");
if (targetId !== null && !/^[A-Za-z0-9._-]+$/u.test(targetId)) throw new Error("--target must be a simple target id");
return { targetId, full, raw };
}
@@ -226,7 +227,8 @@ function parseApplyOptions(args: string[]): ApplyOptions {
return arg !== "--confirm" && arg !== "--dry-run" && arg !== "--wait" && previous !== "--component" && previous !== "--lines" && previous !== "--path";
});
const common = parseCommonOptions(commonArgs);
if (args.some((arg) => !["--target", "--confirm", "--dry-run", "--wait", common.targetId].includes(arg) && !arg.startsWith("--target="))) {
const allowedArgs = ["--target", "--confirm", "--dry-run", "--wait", ...(common.targetId === null ? [] : [common.targetId])];
if (args.some((arg) => !allowedArgs.includes(arg) && !arg.startsWith("--target="))) {
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === "--target") {
@@ -298,6 +300,7 @@ function readLangBotConfig(): LangBotConfig {
const kind = stringField(root, "kind", "");
if (kind !== "platform-infra-langbot") throw new Error("config/platform-infra/langbot.yaml.kind must be platform-infra-langbot");
const metadata = objectField(root, "metadata", "");
const defaults = objectField(root, "defaults", "");
const image = objectField(root, "image", "");
const dependencyImages = objectField(root, "dependencyImages", "");
const runtime = objectField(root, "runtime", "");
@@ -316,6 +319,9 @@ function readLangBotConfig(): LangBotConfig {
owner: stringField(metadata, "owner", "metadata"),
relatedIssues: numberArrayField(metadata, "relatedIssues", "metadata"),
},
defaults: {
targetId: stringField(defaults, "targetId", "defaults"),
},
image: {
repository: stringField(image, "repository", "image"),
tag: stringField(image, "tag", "image"),
@@ -372,6 +378,7 @@ function readLangBotConfig(): LangBotConfig {
if (!isImageReference(`${config.image.repository}:${config.image.tag}`)) throw new Error("config/platform-infra/langbot.yaml.image must render a valid image reference");
if (!isImageReference(config.dependencyImages.postgresClient)) throw new Error("config/platform-infra/langbot.yaml.dependencyImages.postgresClient must be an image reference");
if (config.targets.length === 0) throw new Error("config/platform-infra/langbot.yaml.targets must not be empty");
assertKnownEnabledTarget(config.targets, config.defaults.targetId, "defaults.targetId");
return config;
}
@@ -422,9 +429,16 @@ function parseTarget(record: Record<string, unknown>, index: number): LangBotTar
};
}
function resolveTarget(langbot: LangBotConfig, targetId: string): LangBotTarget {
const target = langbot.targets.find((item) => item.id.toLowerCase() === targetId.toLowerCase());
if (target === undefined) throw new Error(`unknown LangBot target ${targetId}; known targets: ${langbot.targets.map((item) => item.id).join(", ")}`);
function assertKnownEnabledTarget(targets: LangBotTarget[], targetId: string, path: string): void {
const target = targets.find((item) => item.id.toLowerCase() === targetId.toLowerCase());
if (target === undefined) throw new Error(`config/platform-infra/langbot.yaml.${path} references unknown target ${targetId}; known targets: ${targets.map((item) => item.id).join(", ")}`);
if (!target.enabled) throw new Error(`config/platform-infra/langbot.yaml.${path} references disabled target ${target.id}`);
}
function resolveTarget(langbot: LangBotConfig, targetId: string | null): LangBotTarget {
const resolvedTargetId = targetId ?? langbot.defaults.targetId;
const target = langbot.targets.find((item) => item.id.toLowerCase() === resolvedTargetId.toLowerCase());
if (target === undefined) throw new Error(`unknown LangBot target ${resolvedTargetId}; known targets: ${langbot.targets.map((item) => item.id).join(", ")}`);
if (!target.enabled) throw new Error(`LangBot target ${target.id} is disabled in config/platform-infra/langbot.yaml`);
return target;
}
@@ -1000,7 +1014,7 @@ function prepareSecretMaterial(langbot: LangBotConfig): SecretMaterial {
export function readLangBotRuntimeConfig(): Record<string, unknown> {
const langbot = readLangBotConfig();
const target = resolveTarget(langbot, "G14");
const target = resolveTarget(langbot, null);
return {
publicBaseUrl: target.publicExposure.publicBaseUrl,
expectedNamespace: target.namespace,
+19 -6
View File
@@ -53,6 +53,7 @@ interface N8nConfig {
version: number;
kind: "platform-infra-n8n";
metadata: { id: string; owner: string; relatedIssues: number[] };
defaults: { targetId: string };
image: { repository: string; tag: string; pullPolicy: "Always" | "IfNotPresent" | "Never" };
dependencyImages: { postgresClient: string };
targets: N8nTarget[];
@@ -96,7 +97,7 @@ interface N8nTarget extends PublicServiceTarget {
}
interface CommonOptions {
targetId: string;
targetId: string | null;
full: boolean;
raw: boolean;
}
@@ -158,7 +159,7 @@ export async function runN8nCommand(config: UniDeskConfig, args: string[]): Prom
}
function parseCommonOptions(args: string[]): CommonOptions {
let targetId = "G14";
let targetId: string | null = null;
let full = false;
let raw = false;
for (let index = 0; index < args.length; index += 1) {
@@ -177,7 +178,7 @@ function parseCommonOptions(args: string[]): CommonOptions {
throw new Error(`unsupported n8n option: ${arg}`);
}
}
if (!/^[A-Za-z0-9._-]+$/u.test(targetId)) throw new Error("--target must be a simple target id");
if (targetId !== null && !/^[A-Za-z0-9._-]+$/u.test(targetId)) throw new Error("--target must be a simple target id");
return { targetId, full, raw };
}
@@ -876,6 +877,7 @@ function readN8nConfig(): N8nConfig {
const kind = stringField(root, "kind", "");
if (kind !== "platform-infra-n8n") throw new Error(`${configLabel}.kind must be platform-infra-n8n`);
const metadata = objectField(root, "metadata", "");
const defaults = objectField(root, "defaults", "");
const image = objectField(root, "image", "");
const dependencyImages = objectField(root, "dependencyImages", "");
const runtime = objectField(root, "runtime", "");
@@ -893,6 +895,9 @@ function readN8nConfig(): N8nConfig {
owner: stringField(metadata, "owner", "metadata"),
relatedIssues: numberArrayField(metadata, "relatedIssues", "metadata"),
},
defaults: {
targetId: stringField(defaults, "targetId", "defaults"),
},
image: {
repository: stringField(image, "repository", "image"),
tag: stringField(image, "tag", "image"),
@@ -944,6 +949,7 @@ function readN8nConfig(): N8nConfig {
if (!isImageReference(`${config.image.repository}:${config.image.tag}`)) throw new Error(`${configLabel}.image must render a valid image reference`);
if (!isImageReference(config.dependencyImages.postgresClient)) throw new Error(`${configLabel}.dependencyImages.postgresClient must be an image reference`);
if (config.targets.length === 0) throw new Error(`${configLabel}.targets must not be empty`);
assertKnownEnabledTarget(config.targets, config.defaults.targetId, "defaults.targetId");
return config;
}
@@ -994,9 +1000,16 @@ function parseTarget(record: Record<string, unknown>, index: number): N8nTarget
};
}
function resolveTarget(n8n: N8nConfig, targetId: string): N8nTarget {
const target = n8n.targets.find((item) => item.id.toLowerCase() === targetId.toLowerCase());
if (target === undefined) throw new Error(`unknown n8n target ${targetId}; known targets: ${n8n.targets.map((item) => item.id).join(", ")}`);
function assertKnownEnabledTarget(targets: N8nTarget[], targetId: string, path: string): void {
const target = targets.find((item) => item.id.toLowerCase() === targetId.toLowerCase());
if (target === undefined) throw new Error(`${configLabel}.${path} references unknown target ${targetId}; known targets: ${targets.map((item) => item.id).join(", ")}`);
if (!target.enabled) throw new Error(`${configLabel}.${path} references disabled target ${target.id}`);
}
function resolveTarget(n8n: N8nConfig, targetId: string | null): N8nTarget {
const resolvedTargetId = targetId ?? n8n.defaults.targetId;
const target = n8n.targets.find((item) => item.id.toLowerCase() === resolvedTargetId.toLowerCase());
if (target === undefined) throw new Error(`unknown n8n target ${resolvedTargetId}; known targets: ${n8n.targets.map((item) => item.id).join(", ")}`);
if (!target.enabled) throw new Error(`n8n target ${target.id} is disabled in ${configLabel}`);
return target;
}