mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(release): reject duplicate candidate checklist options
This commit is contained in:
@@ -87,64 +87,72 @@ export function parseArgs(argv) {
|
||||
windowsNodeInstallerDigests: "",
|
||||
outputDir: "",
|
||||
};
|
||||
const seen = new Set();
|
||||
const setOnce = (flag, key, value) => {
|
||||
if (seen.has(flag)) {
|
||||
throw new Error(`${flag} was provided more than once`);
|
||||
}
|
||||
seen.add(flag);
|
||||
options[key] = value;
|
||||
};
|
||||
parseArgv: for (let index = 0; index < args.length; index += 1) {
|
||||
const arg = args[index];
|
||||
switch (arg) {
|
||||
case "--":
|
||||
break parseArgv;
|
||||
case "--tag":
|
||||
options.tag = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "tag", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--workflow-ref":
|
||||
options.workflowRef = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "workflowRef", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--repo":
|
||||
options.repo = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "repo", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--full-release-run":
|
||||
options.fullReleaseRunId = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "fullReleaseRunId", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--npm-preflight-run":
|
||||
options.npmPreflightRunId = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "npmPreflightRunId", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--windows-node-tag":
|
||||
options.windowsNodeTag = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "windowsNodeTag", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--skip-dispatch":
|
||||
options.skipDispatch = true;
|
||||
setOnce(arg, "skipDispatch", true);
|
||||
break;
|
||||
case "--skip-local-generated-check":
|
||||
options.skipLocalGeneratedCheck = true;
|
||||
setOnce(arg, "skipLocalGeneratedCheck", true);
|
||||
break;
|
||||
case "--skip-parallels":
|
||||
options.skipParallels = true;
|
||||
setOnce(arg, "skipParallels", true);
|
||||
break;
|
||||
case "--skip-telegram":
|
||||
options.skipTelegram = true;
|
||||
setOnce(arg, "skipTelegram", true);
|
||||
break;
|
||||
case "--telegram-provider-mode":
|
||||
options.telegramProviderMode = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "telegramProviderMode", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--provider":
|
||||
options.provider = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "provider", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--mode":
|
||||
options.mode = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "mode", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--release-profile":
|
||||
options.releaseProfile = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "releaseProfile", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--npm-dist-tag":
|
||||
options.npmDistTag = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "npmDistTag", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--plugin-publish-scope":
|
||||
options.pluginPublishScope = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "pluginPublishScope", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--plugins":
|
||||
options.plugins = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "plugins", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "--output-dir":
|
||||
options.outputDir = requireValue(args, ++index, arg);
|
||||
setOnce(arg, "outputDir", requireValue(args, ++index, arg));
|
||||
break;
|
||||
case "-h":
|
||||
case "--help":
|
||||
|
||||
@@ -79,6 +79,41 @@ describe("release candidate checklist", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects duplicate release candidate CLI options", () => {
|
||||
const requiredArgs = ["--tag", "v2026.5.14-beta.3"];
|
||||
const duplicateOption = (
|
||||
flag: string,
|
||||
firstValue: string,
|
||||
secondValue: string,
|
||||
prefix = requiredArgs,
|
||||
): [string, string[]] => [flag, [...prefix, flag, firstValue, flag, secondValue]];
|
||||
const duplicateFlag = (flag: string): [string, string[]] => [flag, [...requiredArgs, flag, flag]];
|
||||
const duplicateCases = [
|
||||
duplicateOption("--tag", "v2026.5.14-beta.3", "v2026.5.14-beta.4", []),
|
||||
duplicateOption("--workflow-ref", "release/a", "release/b"),
|
||||
duplicateOption("--repo", "openclaw/openclaw", "fork/openclaw"),
|
||||
duplicateOption("--full-release-run", "111", "222"),
|
||||
duplicateOption("--npm-preflight-run", "111", "222"),
|
||||
duplicateOption("--windows-node-tag", "v0.6.3", "v0.6.4"),
|
||||
duplicateFlag("--skip-dispatch"),
|
||||
duplicateFlag("--skip-local-generated-check"),
|
||||
duplicateFlag("--skip-parallels"),
|
||||
duplicateFlag("--skip-telegram"),
|
||||
duplicateOption("--telegram-provider-mode", "mock-openai", "live-frontier"),
|
||||
duplicateOption("--provider", "blacksmith-testbox", "crabbox"),
|
||||
duplicateOption("--mode", "fresh", "upgrade"),
|
||||
duplicateOption("--release-profile", "beta", "stable"),
|
||||
duplicateOption("--npm-dist-tag", "beta", "latest"),
|
||||
duplicateOption("--plugin-publish-scope", "all-publishable", "selected"),
|
||||
duplicateOption("--plugins", "telegram", "discord"),
|
||||
duplicateOption("--output-dir", ".artifacts/a", ".artifacts/b"),
|
||||
] satisfies Array<[string, string[]]>;
|
||||
|
||||
for (const [flag, args] of duplicateCases) {
|
||||
expect(() => parseArgs(args), flag).toThrow(`${flag} was provided more than once`);
|
||||
}
|
||||
});
|
||||
|
||||
it("requires stable validation evidence to include soak and blocking performance", () => {
|
||||
const stableManifest = {
|
||||
workflowName: "Full Release Validation",
|
||||
|
||||
Reference in New Issue
Block a user