feat: add post-run Gitea lifecycle (#5)
This commit is contained in:
155
packages/agents/src/git/gitea.test.ts
Normal file
155
packages/agents/src/git/gitea.test.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { createGiteaHttpTransport, runPostRunGiteaLifecycle } from "./gitea";
|
||||
import type { GitCommandRunner, GiteaTransport } from "./gitea";
|
||||
|
||||
const repository = {
|
||||
cloneUrl: "https://git.openputer.com/puter/zopu-code.git",
|
||||
defaultBranch: "main",
|
||||
htmlUrl: "https://git.openputer.com/puter/zopu-code",
|
||||
name: "zopu-code",
|
||||
sshUrl: "ssh://git@git.openputer.com:2222/puter/zopu-code.git",
|
||||
};
|
||||
|
||||
const makeRunner = (): GitCommandRunner & { readonly commands: string[] } => {
|
||||
const commands: string[] = [];
|
||||
let statusCalls = 0;
|
||||
return {
|
||||
commands,
|
||||
run(command) {
|
||||
commands.push(command);
|
||||
if (command === "git branch --show-current") {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stderr: "",
|
||||
stdout: "work/issue-5\n",
|
||||
});
|
||||
}
|
||||
if (command === "git status --porcelain=v1") {
|
||||
statusCalls += 1;
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stderr: "",
|
||||
stdout: statusCalls === 1 ? " M src/gitea.ts\n" : "",
|
||||
});
|
||||
}
|
||||
if (command === "git diff --no-ext-diff --binary") {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stderr: "",
|
||||
stdout: "diff --git ...",
|
||||
});
|
||||
}
|
||||
if (command === "git rev-parse HEAD") {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stderr: "",
|
||||
stdout: "abc123\n",
|
||||
});
|
||||
}
|
||||
if (command.includes("git status --porcelain=v1")) {
|
||||
return Promise.resolve({ exitCode: 0, stderr: "", stdout: "" });
|
||||
}
|
||||
return Promise.resolve({ exitCode: 0, stderr: "", stdout: "" });
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
describe("Gitea lifecycle adapter", () => {
|
||||
test("inspects, commits, pushes, and creates an open PR through mocked boundaries", async () => {
|
||||
const runner = makeRunner();
|
||||
const pullRequests: unknown[] = [];
|
||||
const transport: GiteaTransport = {
|
||||
createPullRequest(input) {
|
||||
pullRequests.push(input);
|
||||
return Promise.resolve({
|
||||
base: { ref: input.base },
|
||||
head: { ref: input.head },
|
||||
htmlUrl: "https://git.openputer.com/puter/zopu-code/pulls/5",
|
||||
number: 5,
|
||||
state: "open",
|
||||
});
|
||||
},
|
||||
getRepository() {
|
||||
return Promise.resolve(repository);
|
||||
},
|
||||
};
|
||||
|
||||
const result = await runPostRunGiteaLifecycle({
|
||||
baseBranch: "main",
|
||||
body: "Generated by the verified project run.",
|
||||
issueNumber: 5,
|
||||
issueTitle: "Publish verified changes",
|
||||
repositoryPath: "puter/zopu-code",
|
||||
runner,
|
||||
transport,
|
||||
verification: "passed",
|
||||
workspace: "/workspace",
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
branch: "work/issue-5",
|
||||
commitSha: "abc123",
|
||||
pullRequest: {
|
||||
baseBranch: "main",
|
||||
branch: "work/issue-5",
|
||||
number: 5,
|
||||
status: "open",
|
||||
},
|
||||
status: "pull_request_open",
|
||||
});
|
||||
expect(runner.commands).toEqual([
|
||||
"git branch --show-current",
|
||||
"git status --porcelain=v1",
|
||||
"git diff --no-ext-diff --binary",
|
||||
"git add --all && git commit -m 'feat(issue-5): Publish verified changes'",
|
||||
"git rev-parse HEAD",
|
||||
"git status --porcelain=v1",
|
||||
"git push 'ssh://git@git.openputer.com:2222/puter/zopu-code.git' HEAD:'work/issue-5'",
|
||||
]);
|
||||
expect(pullRequests).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("mocks the HTTP Gitea boundary without calling the network", async () => {
|
||||
const requests: Request[] = [];
|
||||
const transport = createGiteaHttpTransport({
|
||||
baseUrl: "https://git.openputer.com",
|
||||
fetch: (input, init) => {
|
||||
const request = new Request(String(input), init);
|
||||
requests.push(request);
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
request.method === "GET"
|
||||
? JSON.stringify(repository)
|
||||
: JSON.stringify({
|
||||
base: { ref: "main" },
|
||||
head: { ref: "work/issue-5" },
|
||||
html_url: "https://git.openputer.com/puter/zopu-code/pulls/5",
|
||||
number: 5,
|
||||
state: "open",
|
||||
}),
|
||||
{ headers: { "content-type": "application/json" } }
|
||||
)
|
||||
);
|
||||
},
|
||||
token: "scoped-test-token",
|
||||
});
|
||||
|
||||
await transport.getRepository("puter/zopu-code");
|
||||
await transport.createPullRequest({
|
||||
base: "main",
|
||||
body: "body",
|
||||
head: "work/issue-5",
|
||||
repositoryPath: "puter/zopu-code",
|
||||
title: "title",
|
||||
});
|
||||
|
||||
expect(requests).toHaveLength(2);
|
||||
expect(requests[0]?.url).toBe(
|
||||
"https://git.openputer.com/api/v1/repos/puter/zopu-code"
|
||||
);
|
||||
expect(requests[1]?.headers.get("authorization")).toBe(
|
||||
"token scoped-test-token"
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user