Gateway: add APNs push test pipeline (#20307)
Merged via /review-pr -> /prepare-pr -> /merge-pr. Prepared head SHA: 6a1c4422079b075fb7900890fa09819f41aee8b1 Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com> Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com> Reviewed-by: @mbelinky
This commit is contained in:
88
src/cli/nodes-cli/register.push.ts
Normal file
88
src/cli/nodes-cli/register.push.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { Command } from "commander";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { getNodesTheme, runNodesCommand } from "./cli-utils.js";
|
||||
import { callGatewayCli, nodesCallOpts, resolveNodeId } from "./rpc.js";
|
||||
import type { NodesRpcOpts } from "./types.js";
|
||||
|
||||
type NodesPushOpts = NodesRpcOpts & {
|
||||
node?: string;
|
||||
title?: string;
|
||||
body?: string;
|
||||
environment?: string;
|
||||
};
|
||||
|
||||
function normalizeEnvironment(value: unknown): "sandbox" | "production" | null {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (normalized === "sandbox" || normalized === "production") {
|
||||
return normalized;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function registerNodesPushCommand(nodes: Command) {
|
||||
nodesCallOpts(
|
||||
nodes
|
||||
.command("push")
|
||||
.description("Send an APNs test push to an iOS node")
|
||||
.requiredOption("--node <idOrNameOrIp>", "Node id, name, or IP")
|
||||
.option("--title <text>", "Push title", "OpenClaw")
|
||||
.option("--body <text>", "Push body")
|
||||
.option("--environment <sandbox|production>", "Override APNs environment")
|
||||
.action(async (opts: NodesPushOpts) => {
|
||||
await runNodesCommand("push", async () => {
|
||||
const nodeId = await resolveNodeId(opts, String(opts.node ?? ""));
|
||||
const title = String(opts.title ?? "").trim() || "OpenClaw";
|
||||
const body = String(opts.body ?? "").trim() || `Push test for node ${nodeId}`;
|
||||
const environment = normalizeEnvironment(opts.environment);
|
||||
if (opts.environment && !environment) {
|
||||
throw new Error("invalid --environment (use sandbox|production)");
|
||||
}
|
||||
|
||||
const params: Record<string, unknown> = {
|
||||
nodeId,
|
||||
title,
|
||||
body,
|
||||
};
|
||||
if (environment) {
|
||||
params.environment = environment;
|
||||
}
|
||||
|
||||
const result = await callGatewayCli("push.test", opts, params);
|
||||
if (opts.json) {
|
||||
defaultRuntime.log(JSON.stringify(result, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
const parsed =
|
||||
typeof result === "object" && result !== null
|
||||
? (result as {
|
||||
ok?: unknown;
|
||||
status?: unknown;
|
||||
reason?: unknown;
|
||||
environment?: unknown;
|
||||
})
|
||||
: {};
|
||||
const ok = parsed.ok === true;
|
||||
const status = typeof parsed.status === "number" ? parsed.status : 0;
|
||||
const reason =
|
||||
typeof parsed.reason === "string" && parsed.reason.trim().length > 0
|
||||
? parsed.reason.trim()
|
||||
: undefined;
|
||||
const env =
|
||||
typeof parsed.environment === "string" && parsed.environment.trim().length > 0
|
||||
? parsed.environment.trim()
|
||||
: "unknown";
|
||||
const { ok: okLabel, error: errorLabel } = getNodesTheme();
|
||||
const label = ok ? okLabel : errorLabel;
|
||||
defaultRuntime.log(label(`push.test status=${status} ok=${ok} env=${env}`));
|
||||
if (reason) {
|
||||
defaultRuntime.log(`reason: ${reason}`);
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ timeoutMs: 25_000 },
|
||||
);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { registerNodesInvokeCommands } from "./register.invoke.js";
|
||||
import { registerNodesLocationCommands } from "./register.location.js";
|
||||
import { registerNodesNotifyCommand } from "./register.notify.js";
|
||||
import { registerNodesPairingCommands } from "./register.pairing.js";
|
||||
import { registerNodesPushCommand } from "./register.push.js";
|
||||
import { registerNodesScreenCommands } from "./register.screen.js";
|
||||
import { registerNodesStatusCommands } from "./register.status.js";
|
||||
|
||||
@@ -30,6 +31,7 @@ export function registerNodesCli(program: Command) {
|
||||
registerNodesPairingCommands(nodes);
|
||||
registerNodesInvokeCommands(nodes);
|
||||
registerNodesNotifyCommand(nodes);
|
||||
registerNodesPushCommand(nodes);
|
||||
registerNodesCanvasCommands(nodes);
|
||||
registerNodesCameraCommands(nodes);
|
||||
registerNodesScreenCommands(nodes);
|
||||
|
||||
Reference in New Issue
Block a user