#!/usr/bin/env bun /** * End-to-end check that the merge queue hands a conflicting pull to an AI fix and re-enqueues it after * CI passes on the fix commit. Needs a dev server with MERGEFIX_PROVIDER=mock; takes several minutes * because the Workflow polls CI every two minutes. Queues the pull through `PUT /pulls/:n/merge_queue`. * * D1_CWD=$PWD bun scripts/e2e-mergefix-queue.ts */ import { api, assert, d1, fixStatus, poll, prepareConflict } from "./mergefix-harness"; const REQUEUE_TIMEOUT_MS = 15 * 60 * 1000; const FIX_TIMEOUT_MS = 5 * 60 * 1000; const user = await api<{ login: string }>("GET", "/user"); const name = `mergefix-queue-${Date.now().toString(36)}`; const line = (middle: string) => `header\none\n${middle}\nthree\nfooter\n`; const prepared = await prepareConflict(user.login, name, [ { path: "app.txt", base: line("two"), head: line("two (head wording)"), main: line("two (main wording)") }, ]); try { const repoId = String(d1(`SELECT id FROM repos WHERE name = '${name}'`)[0]?.id); d1( `INSERT INTO repo_mergefix_settings (repo_id, queue_enabled, allow_private, min_confidence, min_margin, updated_at) VALUES ('${repoId}', 1, 0, 0.8, 0.3, ${Date.now()})`, ); await api( "PUT", `/repos/${user.login}/${name}/pulls/${prepared.pull.number}/merge_queue`, { method: "merge", expected_head: prepared.before }, [200, 202, 204], ); const applied = await poll("the queue-triggered fix to land", FIX_TIMEOUT_MS, async () => { const fix = await fixStatus(user.login, name, prepared.pull.number); return fix && !["queued", "running", "applying"].includes(fix.status) ? fix : null; }); assert(applied.status === "applied", `expected applied, got ${applied.status}: ${applied.error}`); assert(prepared.remoteHead() === applied.commit_sha, "head branch moved to the fix commit"); console.log(`fix ${applied.commit_sha?.slice(0, 7)} applied; waiting for CI and re-enqueue`); const requeued = await poll("the pull to rejoin the queue", REQUEUE_TIMEOUT_MS, async () => { const fix = await fixStatus(user.login, name, prepared.pull.number); return fix?.requeue && fix.requeue.status !== "waiting" ? fix.requeue : null; }); assert(requeued.status === "enqueued", `expected enqueued, got ${requeued.status}: ${requeued.error}`); const entry = d1( `SELECT e.state FROM merge_queue_entries e JOIN issues i ON i.id = e.issue_id WHERE i.repo_id = '${repoId}' ORDER BY e.created_at DESC LIMIT 1`, )[0]; assert(["queued", "testing", "merged"].includes(String(entry?.state)), `queue entry state ${String(entry?.state)}`); console.log(`ok: pull re-enqueued after green CI (latest queue entry state: ${String(entry?.state)})`); } finally { prepared.cleanup(); }