mirror of
https://github.com/github/awesome-copilot.git
synced 2026-10-12 14:54:16 +00:00
fix(canvas): handle board startup requests
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 545df520-6557-4211-a110-53c60f4b9f3a
This commit is contained in:
co-authored by
Copilot App
parent
758f4382db
commit
01678e9489
@@ -213,6 +213,7 @@ function routesFor(instanceId) {
|
|||||||
function wrap(fn) {
|
function wrap(fn) {
|
||||||
return async (ctx) => {
|
return async (ctx) => {
|
||||||
try {
|
try {
|
||||||
|
if (!store) throw new CanvasError("not_ready", "The extension is still starting. Retry the action.");
|
||||||
return await fn(ctx);
|
return await fn(ctx);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof CanvasError) throw error;
|
if (error instanceof CanvasError) throw error;
|
||||||
@@ -316,6 +317,7 @@ session = await joinSession({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
open: async (ctx) => {
|
open: async (ctx) => {
|
||||||
|
if (!store) throw new CanvasError("not_ready", "The extension is still starting. Retry opening it.");
|
||||||
let entry = servers.get(ctx.instanceId);
|
let entry = servers.get(ctx.instanceId);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
entry = await startBoardServer({
|
entry = await startBoardServer({
|
||||||
|
|||||||
@@ -39,13 +39,29 @@ async function fingerprint(dir) {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadCanvas({ id, extensionDir, workspacePath }) {
|
async function loadCanvas({ id, extensionDir, workspacePath, triggerDuringJoin = false }) {
|
||||||
let canvas;
|
let canvas;
|
||||||
|
let startupResults;
|
||||||
const context = vm.createContext({ setTimeout });
|
const context = vm.createContext({ setTimeout });
|
||||||
const sdk = {
|
const sdk = {
|
||||||
createCanvas: (definition) => definition,
|
createCanvas: (definition) => definition,
|
||||||
joinSession: async (options) => {
|
joinSession: async (options) => {
|
||||||
[canvas] = options.canvases;
|
[canvas] = options.canvases;
|
||||||
|
if (triggerDuringJoin) {
|
||||||
|
const ctx = { instanceId: "startup-test", input: {} };
|
||||||
|
const requests = [
|
||||||
|
canvas.actions.find((entry) => entry.name === "get_board").handler(ctx),
|
||||||
|
canvas.open(ctx),
|
||||||
|
];
|
||||||
|
startupResults = Promise.all(requests.map(async (request) => {
|
||||||
|
try {
|
||||||
|
await request;
|
||||||
|
return { ok: true };
|
||||||
|
} catch (error) {
|
||||||
|
return { ok: false, code: error.code, message: error.message };
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
return { workspacePath, log() {}, send: async () => {} };
|
return { workspacePath, log() {}, send: async () => {} };
|
||||||
},
|
},
|
||||||
CanvasError: class CanvasError extends Error {
|
CanvasError: class CanvasError extends Error {
|
||||||
@@ -76,11 +92,13 @@ async function loadCanvas({ id, extensionDir, workspacePath }) {
|
|||||||
}, { context });
|
}, { context });
|
||||||
});
|
});
|
||||||
await module.evaluate();
|
await module.evaluate();
|
||||||
return (name, input = {}) => {
|
const act = (name, input = {}) => {
|
||||||
const action = canvas.actions.find((entry) => entry.name === name);
|
const action = canvas.actions.find((entry) => entry.name === name);
|
||||||
assert.ok(action, `Missing canvas action ${name}`);
|
assert.ok(action, `Missing canvas action ${name}`);
|
||||||
return action.handler({ instanceId: "test-board", input });
|
return action.handler({ instanceId: "test-board", input });
|
||||||
};
|
};
|
||||||
|
act.startupResults = startupResults;
|
||||||
|
return act;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeJSON(file, value) {
|
async function writeJSON(file, value) {
|
||||||
@@ -148,6 +166,19 @@ for (const id of ["open-pr-board", "external-plugin-review-board"]) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("external-plugin-review-board returns retryable not_ready errors during startup", async (t) => {
|
||||||
|
const f = await fixture(t, "external-plugin-review-board");
|
||||||
|
const act = await loadCanvas({ ...f, triggerDuringJoin: true });
|
||||||
|
const results = await act.startupResults;
|
||||||
|
assert.equal(results.length, 2);
|
||||||
|
for (const result of results) {
|
||||||
|
assert.equal(result.ok, false);
|
||||||
|
assert.equal(result.code, "not_ready");
|
||||||
|
assert.match(result.message, /still starting/i);
|
||||||
|
}
|
||||||
|
assert.equal((await act("get_board")).items.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test("both canvases keep independent boards in the same session workspace", async (t) => {
|
test("both canvases keep independent boards in the same session workspace", async (t) => {
|
||||||
const pr = await fixture(t, "open-pr-board");
|
const pr = await fixture(t, "open-pr-board");
|
||||||
const plugin = { ...await fixture(t, "external-plugin-review-board"), workspacePath: pr.workspacePath };
|
const plugin = { ...await fixture(t, "external-plugin-review-board"), workspacePath: pr.workspacePath };
|
||||||
|
|||||||
Reference in New Issue
Block a user