Untangle Spike architecture with bridge pattern #9
|
|
@ -228,10 +228,30 @@ export async function commentOnPR(repo: string, prNumber: number, body: string,
|
|||
}
|
||||
|
||||
export async function mergePR(repo: string, prNumber: number, user: User) {
|
||||
return giteaFetch(`/repos/${repo}/pulls/${prNumber}/merge`, user, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ Do: "merge", merge_message_field: "Test merge" }),
|
||||
})
|
||||
// Gitea returns 404/405 while computing mergeability after PR creation
|
||||
const path = `/repos/${repo}/pulls/${prNumber}/merge`
|
||||
|
||||
for (let attempt = 0; attempt < 10; attempt++) {
|
||||
const response = await fetch(`${giteaUrl}/api/v1${path}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `token ${user.token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ Do: "merge" }),
|
||||
})
|
||||
|
||||
if (response.ok) return
|
||||
if (response.status === 404 || response.status === 405) {
|
||||
await Bun.sleep(1000)
|
||||
continue
|
||||
}
|
||||
|
||||
const body = await response.text().catch(() => "")
|
||||
throw new Error(`Gitea ${response.status}: POST ${path}\n${body}`)
|
||||
}
|
||||
|
||||
throw new Error(`Gitea merge failed after 10 retries for ${path}`)
|
||||
}
|
||||
|
||||
export async function createReview(repo: string, prNumber: number, user: User, filePath: string) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ setDefaultTimeout(30_000)
|
|||
import { ensure } from "@workshop/shared/utils"
|
||||
import {
|
||||
type User,
|
||||
type TestPR,
|
||||
setupWebhooks,
|
||||
expectPullRequestWebhook,
|
||||
expectIssueCommentWebhook,
|
||||
|
|
@ -15,6 +14,10 @@ import {
|
|||
mergePR,
|
||||
} from "./helpers"
|
||||
|
||||
function testBranch(label: string) {
|
||||
return `test-${crypto.randomUUID().slice(0, 8)}-${label}`
|
||||
}
|
||||
|
||||
function getEnv(name: string): string {
|
||||
const value = process.env[name]
|
||||
ensure(value, `Missing env var: ${name}. See .env.example`)
|
||||
|
|
@ -37,20 +40,19 @@ afterAll(() => teardown())
|
|||
// --- Tests for Corey's repo (Spike opens PR, Corey comments/reviews/merges) ---
|
||||
|
||||
describe(`${coreyRepo}`, () => {
|
||||
let pr: TestPR
|
||||
const branch = `test-${Date.now()}-corey`
|
||||
|
||||
test("opening a PR sends pull_request webhook with correct author and repo", async () => {
|
||||
pr = await expectPullRequestWebhook({ action: "opened", branch }, async (webhook) => {
|
||||
const result = await openTestPR(coreyRepo, spike, branch)
|
||||
const branch = testBranch("open")
|
||||
await expectPullRequestWebhook({ action: "opened", branch }, async (webhook) => {
|
||||
await openTestPR(coreyRepo, spike, branch)
|
||||
const payload = await webhook
|
||||
expect(payload.pull_request.user.login).toBe(spike.username)
|
||||
expect(payload.repository.full_name).toBe(coreyRepo)
|
||||
return result
|
||||
})
|
||||
})
|
||||
|
||||
test("commenting sends issue_comment webhook with correct user", async () => {
|
||||
const branch = testBranch("comment")
|
||||
const pr = await openTestPR(coreyRepo, spike, branch)
|
||||
await expectIssueCommentWebhook({ action: "created", username: corey.username, prNumber: pr.number }, async (webhook) => {
|
||||
await commentOnPR(coreyRepo, pr.number, "Looks good!", corey)
|
||||
const payload = await webhook
|
||||
|
|
@ -59,6 +61,8 @@ describe(`${coreyRepo}`, () => {
|
|||
})
|
||||
|
||||
test("review with line comment sends pull_request_comment webhook", async () => {
|
||||
const branch = testBranch("review")
|
||||
const pr = await openTestPR(coreyRepo, spike, branch)
|
||||
await expectPullRequestCommentWebhook({ action: "reviewed", branch }, async (webhook) => {
|
||||
await createReview(coreyRepo, pr.number, corey, pr.filename)
|
||||
const payload = await webhook
|
||||
|
|
@ -68,6 +72,8 @@ describe(`${coreyRepo}`, () => {
|
|||
})
|
||||
|
||||
test("merging sends pull_request closed webhook", async () => {
|
||||
const branch = testBranch("merge")
|
||||
const pr = await openTestPR(coreyRepo, spike, branch)
|
||||
await expectPullRequestWebhook({ action: "closed", branch }, async (webhook) => {
|
||||
await mergePR(coreyRepo, pr.number, corey)
|
||||
const payload = await webhook
|
||||
|
|
@ -79,20 +85,19 @@ describe(`${coreyRepo}`, () => {
|
|||
// --- Tests for Spike's repo (Corey opens PR, Spike comments/reviews/merges) ---
|
||||
|
||||
describe(`${spikeRepo}`, () => {
|
||||
let pr: TestPR
|
||||
const branch = `test-${Date.now()}-spike`
|
||||
|
||||
test("opening a PR sends pull_request webhook with correct author and repo", async () => {
|
||||
pr = await expectPullRequestWebhook({ action: "opened", branch }, async (webhook) => {
|
||||
const result = await openTestPR(spikeRepo, corey, branch)
|
||||
const branch = testBranch("open")
|
||||
await expectPullRequestWebhook({ action: "opened", branch }, async (webhook) => {
|
||||
await openTestPR(spikeRepo, corey, branch)
|
||||
const payload = await webhook
|
||||
expect(payload.pull_request.user.login).toBe(corey.username)
|
||||
expect(payload.repository.full_name).toBe(spikeRepo)
|
||||
return result
|
||||
})
|
||||
})
|
||||
|
||||
test("commenting sends issue_comment webhook with correct user", async () => {
|
||||
const branch = testBranch("comment")
|
||||
const pr = await openTestPR(spikeRepo, corey, branch)
|
||||
await expectIssueCommentWebhook({ action: "created", username: spike.username, prNumber: pr.number }, async (webhook) => {
|
||||
await commentOnPR(spikeRepo, pr.number, "On it!", spike)
|
||||
const payload = await webhook
|
||||
|
|
@ -101,6 +106,8 @@ describe(`${spikeRepo}`, () => {
|
|||
})
|
||||
|
||||
test("review with line comment sends pull_request_comment webhook", async () => {
|
||||
const branch = testBranch("review")
|
||||
const pr = await openTestPR(spikeRepo, corey, branch)
|
||||
await expectPullRequestCommentWebhook({ action: "reviewed", branch }, async (webhook) => {
|
||||
await createReview(spikeRepo, pr.number, spike, pr.filename)
|
||||
const payload = await webhook
|
||||
|
|
@ -110,6 +117,8 @@ describe(`${spikeRepo}`, () => {
|
|||
})
|
||||
|
||||
test("merging sends pull_request closed webhook", async () => {
|
||||
const branch = testBranch("merge")
|
||||
const pr = await openTestPR(spikeRepo, corey, branch)
|
||||
await expectPullRequestWebhook({ action: "closed", branch }, async (webhook) => {
|
||||
await mergePR(spikeRepo, pr.number, spike)
|
||||
const payload = await webhook
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user