mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 02:06:43 +00:00
fix(scripts): bound sync-labels GitHub CLI operations (#110463)
* fix(scripts): bound sync-labels GitHub CLI operations * fix(scripts): bound sync-labels GitHub CLI operations * fix(scripts): bound sync-labels GitHub CLI operations * fix(scripts): bound label discovery requests Co-authored-by: wanyongstar <wan.yong@xydigit.com> --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
co-authored by
Peter Steinberger
parent
ff54749b1b
commit
c20ece85f4
@@ -5,6 +5,8 @@ import { resolve } from "node:path";
|
||||
import { parse } from "yaml";
|
||||
import { resolveGitHubRepoFromOrigin } from "./lib/github-repo.ts";
|
||||
|
||||
const SYNC_LABELS_TIMEOUT_MS = 120_000;
|
||||
|
||||
type RepoLabel = {
|
||||
name: string;
|
||||
color?: string;
|
||||
@@ -77,7 +79,11 @@ for (const label of missing) {
|
||||
if (metadata.description) {
|
||||
args.push("-f", `description=${metadata.description}`);
|
||||
}
|
||||
execFileSync("gh", args, { stdio: "inherit" });
|
||||
execFileSync("gh", args, {
|
||||
stdio: "inherit",
|
||||
timeout: SYNC_LABELS_TIMEOUT_MS,
|
||||
killSignal: "SIGKILL",
|
||||
});
|
||||
console.log(`Created label: ${label}`);
|
||||
}
|
||||
|
||||
@@ -93,6 +99,8 @@ function resolveLabelMetadata(label: string): { color: string; description?: str
|
||||
function fetchExistingLabels(repoLocal: string): Map<string, RepoLabel> {
|
||||
const raw = execFileSync("gh", ["api", `repos/${repoLocal}/labels?per_page=100`, "--paginate"], {
|
||||
encoding: "utf8",
|
||||
timeout: SYNC_LABELS_TIMEOUT_MS,
|
||||
killSignal: "SIGKILL",
|
||||
});
|
||||
const labels = JSON.parse(raw) as RepoLabel[];
|
||||
return new Map(labels.map((label) => [label.name, label]));
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { execFileSyncMock } = vi.hoisted(() => ({
|
||||
execFileSyncMock: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("node:child_process", async () => {
|
||||
const actual = await vi.importActual<typeof import("node:child_process")>("node:child_process");
|
||||
return {
|
||||
...actual,
|
||||
execFileSync: execFileSyncMock,
|
||||
};
|
||||
});
|
||||
|
||||
describe("sync-labels", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
execFileSyncMock.mockReset();
|
||||
execFileSyncMock.mockImplementation((command: string, args?: readonly string[]) => {
|
||||
if (command === "git") {
|
||||
return "https://github.com/openclaw/openclaw.git\n";
|
||||
}
|
||||
if (command === "gh" && args?.some((arg) => arg.includes("/labels?"))) {
|
||||
return "[]";
|
||||
}
|
||||
return "";
|
||||
});
|
||||
vi.spyOn(console, "log").mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("bounds every GitHub CLI operation", async () => {
|
||||
await import("../../scripts/sync-labels.ts");
|
||||
|
||||
const ghCalls = execFileSyncMock.mock.calls.filter(([command]) => command === "gh");
|
||||
expect(ghCalls.length).toBeGreaterThan(1);
|
||||
for (const [, , options] of ghCalls) {
|
||||
expect(options).toMatchObject({
|
||||
timeout: 120_000,
|
||||
killSignal: "SIGKILL",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user