mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-21 00:21:49 +00:00
Everything this stack adds now carries issue in its file name, workflow name and job id, so one search finds all of it: ls .github/workflows/issue_* grep -ril issue scripts .github/prompts .github/*.json Renames: label_sync.yml -> issue_label_sync.yml, label_claude_code.yml -> issue_label_claude_code.yml, .github/labels.json -> .github/issue-labels.json, scripts/sync-labels(.test).ts -> scripts/sync-issue-labels(.test).ts. Job ids now match the script they run: classify-issue-tests, classify-issue, label-issue, sync-issue-labels-tests, sync-issue-labels, label-claude-code
86 lines
3.6 KiB
TypeScript
86 lines
3.6 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
|
|
import type { GitHubApi } from "./auto-close-duplicates";
|
|
import { MANIFEST, manifestLabels, type Manifest } from "./issue-labels";
|
|
import { readConfig, syncLabels, syncPlan, type GitHubLabel } from "./sync-issue-labels";
|
|
|
|
const small: Manifest = {
|
|
domain: { caching: { color: "1C6E5B", description: "Response cache" } },
|
|
provider: {},
|
|
kind: {},
|
|
priority: { p0: { color: "B60205", description: "Bleeding" } },
|
|
lift: {},
|
|
needs: { template: { color: "E99695", description: "Template sections missing" } },
|
|
};
|
|
|
|
describe("syncPlan", () => {
|
|
test("creates what is missing, updates what drifted, leaves the rest", () => {
|
|
const existing: readonly GitHubLabel[] = [
|
|
{ name: "Domain:Caching", color: "1c6e5b", description: "Response cache" },
|
|
{ name: "priority:p0", color: "000000", description: "Bleeding" },
|
|
{ name: "bug", color: "d73a4a", description: "Something isn't working" },
|
|
];
|
|
expect(syncPlan(existing, small).map((action) => `${action.kind} ${action.name}`)).toEqual([
|
|
"unchanged domain:caching",
|
|
"update priority:p0",
|
|
"create needs:template",
|
|
]);
|
|
});
|
|
|
|
test("a missing description counts as drift", () => {
|
|
const existing: readonly GitHubLabel[] = [{ name: "domain:caching", color: "1C6E5B", description: null }];
|
|
expect(syncPlan(existing, small)[0]?.kind).toBe("update");
|
|
});
|
|
|
|
test("the real manifest is 44 labels across six namespaces", () => {
|
|
expect(manifestLabels(MANIFEST)).toHaveLength(44);
|
|
expect(syncPlan([], MANIFEST).every((action) => action.kind === "create")).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("syncLabels", () => {
|
|
function fakeApi(existing: readonly GitHubLabel[]): { readonly api: GitHubApi; readonly writes: string[] } {
|
|
const writes: string[] = [];
|
|
const api: GitHubApi = {
|
|
request: async <T>(method: string, path: string, body?: object): Promise<T> => {
|
|
if (method === "GET" && path.startsWith("/repos/BerriAI/litellm/labels")) {
|
|
return existing as T;
|
|
}
|
|
if (method === "GET") {
|
|
throw new Error(`unexpected GET ${path}`);
|
|
}
|
|
writes.push(`${method} ${path} ${JSON.stringify(body)}`);
|
|
return {} as T;
|
|
},
|
|
};
|
|
return { api, writes };
|
|
}
|
|
|
|
test("a real run creates and patches, and never deletes", async () => {
|
|
const { api, writes } = fakeApi([{ name: "priority:p0", color: "000000", description: "Bleeding" }, { name: "stale", color: "ededed", description: null }]);
|
|
await syncLabels(api, { repo: "BerriAI/litellm", dryRun: false }, small);
|
|
expect(writes).toEqual([
|
|
'POST /repos/BerriAI/litellm/labels {"name":"domain:caching","color":"1C6E5B","description":"Response cache"}',
|
|
'PATCH /repos/BerriAI/litellm/labels/priority%3Ap0 {"color":"B60205","description":"Bleeding"}',
|
|
'POST /repos/BerriAI/litellm/labels {"name":"needs:template","color":"E99695","description":"Template sections missing"}',
|
|
]);
|
|
});
|
|
|
|
test("a dry run returns the plan and writes nothing", async () => {
|
|
const { api, writes } = fakeApi([]);
|
|
const plan = await syncLabels(api, { repo: "BerriAI/litellm", dryRun: true }, small);
|
|
expect(plan.map((action) => action.kind)).toEqual(["create", "create", "create"]);
|
|
expect(writes).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("readConfig", () => {
|
|
test("reads the repo and the dry-run flag", () => {
|
|
expect(readConfig({ GITHUB_TOKEN: "t", GITHUB_REPOSITORY: "BerriAI/litellm", DRY_RUN: "true" })).toEqual({
|
|
token: "t",
|
|
repo: "BerriAI/litellm",
|
|
dryRun: true,
|
|
});
|
|
expect(() => readConfig({ GITHUB_TOKEN: "t", GITHUB_REPOSITORY: "nope" })).toThrow("GITHUB_REPOSITORY");
|
|
});
|
|
});
|