mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix: avoid early Slack credential leases in Mantis
This commit is contained in:
12
.github/workflows/mantis-slack-desktop-smoke.yml
vendored
12
.github/workflows/mantis-slack-desktop-smoke.yml
vendored
@@ -229,6 +229,7 @@ jobs:
|
||||
keep_args=(--no-keep-lease)
|
||||
fi
|
||||
|
||||
set +e
|
||||
pnpm openclaw qa mantis slack-desktop-smoke \
|
||||
--repo-root "$candidate_repo" \
|
||||
--output-dir "$output_rel" \
|
||||
@@ -245,6 +246,13 @@ jobs:
|
||||
--fast \
|
||||
--scenario "$SCENARIO_ID" \
|
||||
"${keep_args[@]}"
|
||||
mantis_exit=$?
|
||||
set -e
|
||||
|
||||
if [[ ! -f "$root/mantis-slack-desktop-smoke-summary.json" ]]; then
|
||||
echo "Mantis Slack desktop smoke did not produce a summary." >&2
|
||||
exit "$mantis_exit"
|
||||
fi
|
||||
|
||||
if [[ -f "$root/slack-desktop-smoke.mp4" ]]; then
|
||||
if ! command -v ffmpeg >/dev/null 2>&1 || ! command -v ffprobe >/dev/null 2>&1; then
|
||||
@@ -296,6 +304,10 @@ jobs:
|
||||
echo "Slack desktop smoke failed." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$mantis_exit" -ne 0 ]]; then
|
||||
echo "Slack desktop smoke exited with $mantis_exit after reporting status $status." >&2
|
||||
exit "$mantis_exit"
|
||||
fi
|
||||
|
||||
- name: Upload Mantis Slack desktop artifacts
|
||||
id: upload_artifact
|
||||
|
||||
@@ -157,9 +157,11 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
|
||||
it("leases Convex Slack credentials for gateway setup and maps them into the VM env", async () => {
|
||||
const commands: { args: readonly string[]; command: string; env?: NodeJS.ProcessEnv }[] = [];
|
||||
const events: string[] = [];
|
||||
const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
const url = describeFetchInput(input);
|
||||
if (url.endsWith("/acquire")) {
|
||||
events.push("acquire");
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
credentialId: "cred-slack",
|
||||
@@ -177,6 +179,7 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
);
|
||||
}
|
||||
if (url.endsWith("/release") || url.endsWith("/heartbeat")) {
|
||||
events.push(url.endsWith("/release") ? "release" : "heartbeat");
|
||||
return new Response(JSON.stringify({ status: "ok" }), { status: 200 });
|
||||
}
|
||||
throw new Error(`unexpected fetch: ${url} ${describeFetchBody(init?.body)}`);
|
||||
@@ -186,6 +189,7 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
const runner = vi.fn(
|
||||
async (command: string, args: readonly string[], options: { env?: NodeJS.ProcessEnv }) => {
|
||||
commands.push({ command, args, env: options.env });
|
||||
events.push(`${command}:${args[0]}`);
|
||||
if (command === "/tmp/crabbox" && args[0] === "warmup") {
|
||||
return { stdout: "ready lease cbx_c0ffee\n", stderr: "" };
|
||||
}
|
||||
@@ -244,6 +248,17 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
});
|
||||
|
||||
expect(result.status).toBe("pass");
|
||||
expect(events).toEqual(
|
||||
expect.arrayContaining([
|
||||
"/tmp/crabbox:warmup",
|
||||
"/tmp/crabbox:inspect",
|
||||
"acquire",
|
||||
"/tmp/crabbox:run",
|
||||
"release",
|
||||
]),
|
||||
);
|
||||
expect(events.indexOf("acquire")).toBeGreaterThan(events.indexOf("/tmp/crabbox:inspect"));
|
||||
expect(events.indexOf("acquire")).toBeLessThan(events.indexOf("/tmp/crabbox:run"));
|
||||
const runCommand = commands.find(
|
||||
(entry) => entry.command === "/tmp/crabbox" && entry.args[0] === "run",
|
||||
);
|
||||
@@ -274,6 +289,59 @@ describe("mantis Slack desktop smoke runtime", () => {
|
||||
expect(summary.slackUrl).toBe("https://app.slack.com/client/TLEASED/CLEASED");
|
||||
});
|
||||
|
||||
it("stops a created no-keep lease when the remote Slack QA run fails", async () => {
|
||||
const commands: { args: readonly string[]; command: string }[] = [];
|
||||
const runner = vi.fn(async (command: string, args: readonly string[]) => {
|
||||
commands.push({ command, args });
|
||||
if (command === "/tmp/crabbox" && args[0] === "warmup") {
|
||||
return { stdout: "ready lease cbx_fade123\n", stderr: "" };
|
||||
}
|
||||
if (command === "/tmp/crabbox" && args[0] === "inspect") {
|
||||
return {
|
||||
stdout: `${JSON.stringify({
|
||||
host: "203.0.113.10",
|
||||
id: "cbx_fade123",
|
||||
provider: "hetzner",
|
||||
sshKey: "/tmp/key",
|
||||
sshPort: "2222",
|
||||
sshUser: "crabbox",
|
||||
})}\n`,
|
||||
stderr: "",
|
||||
};
|
||||
}
|
||||
if (command === "/tmp/crabbox" && args[0] === "run") {
|
||||
throw new Error("remote Slack QA failed");
|
||||
}
|
||||
if (command === "rsync") {
|
||||
const outputDir = args.at(-1);
|
||||
await fs.mkdir(outputDir as string, { recursive: true });
|
||||
if (!String(outputDir).endsWith("slack-qa/")) {
|
||||
await fs.writeFile(path.join(outputDir as string, "slack-desktop-smoke.png"), "png");
|
||||
await fs.writeFile(path.join(outputDir as string, "remote-metadata.json"), "{}\n");
|
||||
}
|
||||
}
|
||||
return { stdout: "", stderr: "" };
|
||||
});
|
||||
|
||||
const result = await runMantisSlackDesktopSmoke({
|
||||
commandRunner: runner,
|
||||
crabboxBin: "/tmp/crabbox",
|
||||
keepLease: false,
|
||||
outputDir: ".artifacts/qa-e2e/mantis/slack-desktop-created-fail",
|
||||
repoRoot,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("fail");
|
||||
expect(commands).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
args: ["stop", "--provider", "hetzner", "cbx_fade123"],
|
||||
command: "/tmp/crabbox",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("passes gateway setup when Crabbox returns non-zero after remote metadata proves success", async () => {
|
||||
const runner = vi.fn(async (command: string, args: readonly string[]) => {
|
||||
if (command === "/tmp/crabbox" && args[0] === "warmup") {
|
||||
|
||||
@@ -822,14 +822,6 @@ export async function runMantisSlackDesktopSmoke(
|
||||
let remoteMetadata: SlackDesktopRemoteMetadata | undefined;
|
||||
|
||||
try {
|
||||
const preparedCredentialEnv = await prepareGatewayCredentialEnv({
|
||||
credentialRole,
|
||||
credentialSource,
|
||||
env,
|
||||
gatewaySetup,
|
||||
});
|
||||
credentialLease = preparedCredentialEnv.credentialLease;
|
||||
leaseHeartbeat = preparedCredentialEnv.leaseHeartbeat;
|
||||
leaseId =
|
||||
leaseId ??
|
||||
(await warmupCrabbox({
|
||||
@@ -850,6 +842,14 @@ export async function runMantisSlackDesktopSmoke(
|
||||
provider,
|
||||
runner,
|
||||
});
|
||||
const preparedCredentialEnv = await prepareGatewayCredentialEnv({
|
||||
credentialRole,
|
||||
credentialSource,
|
||||
env,
|
||||
gatewaySetup,
|
||||
});
|
||||
credentialLease = preparedCredentialEnv.credentialLease;
|
||||
leaseHeartbeat = preparedCredentialEnv.leaseHeartbeat;
|
||||
let remoteRunError: unknown;
|
||||
await runCommand({
|
||||
command: crabboxBin,
|
||||
@@ -989,7 +989,7 @@ export async function runMantisSlackDesktopSmoke(
|
||||
await fs.writeFile(summaryPath, `${JSON.stringify(summary, null, 2)}\n`, "utf8");
|
||||
await fs.writeFile(reportPath, renderReport(summary), "utf8");
|
||||
}
|
||||
if (summary?.status === "pass" && createdLease && leaseId && !keepLease) {
|
||||
if (createdLease && leaseId && !keepLease) {
|
||||
await stopCrabbox({ crabboxBin, cwd: repoRoot, env, leaseId, provider, runner });
|
||||
}
|
||||
if (leaseHeartbeat) {
|
||||
|
||||
Reference in New Issue
Block a user