fix(server): preserve heartbeat workspace environment

Preserve environmentId when heartbeat refreshes issue workspace settings so accepted-plan children keep the same pre-realization environment intent.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Nicky LeachandPaperclip committed 2026-07-08 16:43:46 +00:00
1 parent 294f4c8332
commit e5edf34b6b
3 files changed
+18 -4

No files matched your search

@@ -290,6 +290,7 @@ describeEmbeddedPostgres("accepted plan workspace refresh", () => {
const projectWorkspaceId = randomUUID();
const sharedExecutionWorkspaceId = randomUUID();
const issueId = randomUUID();
const issueEnvironmentId = randomUUID();
const agentId = randomUUID();
const repoRoot = await createGitRepo();
tempRoots.push(repoRoot);
@@ -367,6 +368,7 @@ describeEmbeddedPostgres("accepted plan workspace refresh", () => {
executionWorkspaceId: sharedExecutionWorkspaceId,
executionWorkspaceSettings: {
mode: "isolated_workspace",
environmentId: issueEnvironmentId,
},
createdAt: new Date(),
updatedAt: new Date(),
@@ -444,6 +446,7 @@ describeEmbeddedPostgres("accepted plan workspace refresh", () => {
expect(refreshedIssue?.executionWorkspaceId).not.toBe(sharedExecutionWorkspaceId);
expect(refreshedIssue?.executionWorkspaceSettings).toMatchObject({
mode: "isolated_workspace",
environmentId: issueEnvironmentId,
});
const isolatedRows = await db
+5 -2
View File
@@ -10265,7 +10265,7 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
: null;
const isolatedWorkspacesEnabled = (await instanceSettings.getExperimental()).enableIsolatedWorkspaces;
const issueExecutionWorkspaceSettings = isolatedWorkspacesEnabled
? parseIssueExecutionWorkspaceSettings(issueContext?.executionWorkspaceSettings)
? parseIssueExecutionWorkspaceSettings(issueContext?.executionWorkspaceSettings, { includeEnvironmentId: true })
: null;
const contextProjectId = readNonEmptyString(context.projectId);
const executionProjectId = issueContext?.projectId ?? contextProjectId;
@@ -11108,7 +11108,10 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
};
}
if (Object.keys(nextIssuePatch).length > 0) {
await issuesSvc.update(issueId, nextIssuePatch);
await issuesSvc.update(issueId, {
...nextIssuePatch,
preserveExecutionWorkspaceEnvironmentId: true,
});
}
}
if (persistedExecutionWorkspace) {
+10 -2
View File
@@ -6167,6 +6167,7 @@ export function issueService(db: Db) {
blockedByIssueIds?: string[];
actorAgentId?: string | null;
actorUserId?: string | null;
preserveExecutionWorkspaceEnvironmentId?: boolean;
},
dbOrTx: any = db,
) => {
@@ -6182,6 +6183,7 @@ export function issueService(db: Db) {
blockedByIssueIds,
actorAgentId,
actorUserId,
preserveExecutionWorkspaceEnvironmentId,
...issueData
} = data;
const isolatedWorkspacesEnabled = (await instanceSettings.getExperimental()).enableIsolatedWorkspaces;
@@ -6244,8 +6246,14 @@ export function issueService(db: Db) {
: existing.executionWorkspacePreference;
const nextExecutionWorkspaceSettings =
issueData.executionWorkspaceSettings !== undefined
? parseIssueExecutionWorkspaceSettings(issueData.executionWorkspaceSettings)
: parseIssueExecutionWorkspaceSettings(existing.executionWorkspaceSettings);
? parseIssueExecutionWorkspaceSettings(
issueData.executionWorkspaceSettings,
{ includeEnvironmentId: preserveExecutionWorkspaceEnvironmentId === true },
)
: parseIssueExecutionWorkspaceSettings(
existing.executionWorkspaceSettings,
{ includeEnvironmentId: preserveExecutionWorkspaceEnvironmentId === true },
);
if (issueData.executionWorkspaceSettings !== undefined) {
patch.executionWorkspaceSettings = nextExecutionWorkspaceSettings
? { ...nextExecutionWorkspaceSettings }