mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 02:20:38 +09:00
Fix issue workspace reuse after isolation
Persist realized isolated/operator workspaces back onto the issue as reusable workspaces so later runs stay on the same workspace, and update the issue workspace picker to present realized isolated workspaces as existing workspaces. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
e0d2c4bddf
commit
5a1e17f27f
4 changed files with 70 additions and 13 deletions
|
|
@ -3,6 +3,7 @@ import {
|
|||
buildExecutionWorkspaceAdapterConfig,
|
||||
defaultIssueExecutionWorkspaceSettingsForProject,
|
||||
gateProjectExecutionWorkspacePolicy,
|
||||
issueExecutionWorkspaceModeForPersistedWorkspace,
|
||||
parseIssueExecutionWorkspaceSettings,
|
||||
parseProjectExecutionWorkspacePolicy,
|
||||
resolveExecutionWorkspaceMode,
|
||||
|
|
@ -142,6 +143,14 @@ describe("execution workspace policy helpers", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("maps persisted execution workspace modes back to issue settings", () => {
|
||||
expect(issueExecutionWorkspaceModeForPersistedWorkspace("isolated_workspace")).toBe("isolated_workspace");
|
||||
expect(issueExecutionWorkspaceModeForPersistedWorkspace("operator_branch")).toBe("operator_branch");
|
||||
expect(issueExecutionWorkspaceModeForPersistedWorkspace("shared_workspace")).toBe("shared_workspace");
|
||||
expect(issueExecutionWorkspaceModeForPersistedWorkspace("adapter_managed")).toBe("agent_default");
|
||||
expect(issueExecutionWorkspaceModeForPersistedWorkspace("cloud_sandbox")).toBe("agent_default");
|
||||
});
|
||||
|
||||
it("disables project execution workspace policy when the instance flag is off", () => {
|
||||
expect(
|
||||
gateProjectExecutionWorkspacePolicy(
|
||||
|
|
|
|||
|
|
@ -132,6 +132,18 @@ export function defaultIssueExecutionWorkspaceSettingsForProject(
|
|||
};
|
||||
}
|
||||
|
||||
export function issueExecutionWorkspaceModeForPersistedWorkspace(
|
||||
mode: string | null | undefined,
|
||||
): IssueExecutionWorkspaceSettings["mode"] {
|
||||
if (mode === "isolated_workspace" || mode === "operator_branch" || mode === "shared_workspace") {
|
||||
return mode;
|
||||
}
|
||||
if (mode === "adapter_managed" || mode === "cloud_sandbox") {
|
||||
return "agent_default";
|
||||
}
|
||||
return "shared_workspace";
|
||||
}
|
||||
|
||||
export function resolveExecutionWorkspaceMode(input: {
|
||||
projectPolicy: ProjectExecutionWorkspacePolicy | null;
|
||||
issueSettings: IssueExecutionWorkspaceSettings | null;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import { workspaceOperationService } from "./workspace-operations.js";
|
|||
import {
|
||||
buildExecutionWorkspaceAdapterConfig,
|
||||
gateProjectExecutionWorkspacePolicy,
|
||||
issueExecutionWorkspaceModeForPersistedWorkspace,
|
||||
parseIssueExecutionWorkspaceSettings,
|
||||
parseProjectExecutionWorkspacePolicy,
|
||||
resolveExecutionWorkspaceMode,
|
||||
|
|
@ -2098,11 +2099,29 @@ export function heartbeatService(db: Db) {
|
|||
cleanupReason: null,
|
||||
});
|
||||
}
|
||||
if (issueId && persistedExecutionWorkspace && issueRef?.executionWorkspaceId !== persistedExecutionWorkspace.id) {
|
||||
await issuesSvc.update(issueId, {
|
||||
executionWorkspaceId: persistedExecutionWorkspace.id,
|
||||
...(resolvedProjectWorkspaceId ? { projectWorkspaceId: resolvedProjectWorkspaceId } : {}),
|
||||
});
|
||||
if (issueId && persistedExecutionWorkspace) {
|
||||
const nextIssueWorkspaceMode = issueExecutionWorkspaceModeForPersistedWorkspace(persistedExecutionWorkspace.mode);
|
||||
const shouldSwitchIssueToExistingWorkspace =
|
||||
issueRef?.executionWorkspacePreference === "reuse_existing" ||
|
||||
executionWorkspaceMode === "isolated_workspace" ||
|
||||
executionWorkspaceMode === "operator_branch";
|
||||
const nextIssuePatch: Record<string, unknown> = {};
|
||||
if (issueRef?.executionWorkspaceId !== persistedExecutionWorkspace.id) {
|
||||
nextIssuePatch.executionWorkspaceId = persistedExecutionWorkspace.id;
|
||||
}
|
||||
if (resolvedProjectWorkspaceId && issueRef?.projectWorkspaceId !== resolvedProjectWorkspaceId) {
|
||||
nextIssuePatch.projectWorkspaceId = resolvedProjectWorkspaceId;
|
||||
}
|
||||
if (shouldSwitchIssueToExistingWorkspace) {
|
||||
nextIssuePatch.executionWorkspacePreference = "reuse_existing";
|
||||
nextIssuePatch.executionWorkspaceSettings = {
|
||||
...(issueExecutionWorkspaceSettings ?? {}),
|
||||
mode: nextIssueWorkspaceMode,
|
||||
};
|
||||
}
|
||||
if (Object.keys(nextIssuePatch).length > 0) {
|
||||
await issuesSvc.update(issueId, nextIssuePatch);
|
||||
}
|
||||
}
|
||||
if (persistedExecutionWorkspace) {
|
||||
context.executionWorkspaceId = persistedExecutionWorkspace.id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue