Skip to content

Commit 05828cd

Browse files
committed
Merge ownership foundation corrections into Project files backend
2 parents 88e5ad2 + 4b7ed91 commit 05828cd

27 files changed

Lines changed: 31312 additions & 88 deletions

‎.github/scripts/resolve-audit-base.sh‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ elif [ "$GITHUB_EVENT_NAME" = workflow_dispatch ]; then
2424
exit 1
2525
fi
2626

27-
base_sha=$(jq -r '.[0].base.sha' <<< "$matching_prs")
28-
if [[ ! "$base_sha" =~ ^[0-9a-f]{40}$ ]]; then
29-
echo 'The pull request did not provide a valid base commit SHA.' >&2
27+
base_ref=$(jq -er '.[0].base.ref | select(type == "string" and length > 0)' <<< "$matching_prs")
28+
if ! git check-ref-format "refs/heads/$base_ref"; then
29+
echo 'The pull request did not provide a valid base branch.' >&2
3030
exit 1
3131
fi
32-
git fetch --depth=1 origin "$base_sha"
32+
git fetch --depth=1 origin "refs/heads/$base_ref"
33+
base_sha=$(git rev-parse --verify 'FETCH_HEAD^{commit}')
3334
echo "ref=$base_sha" >> "$GITHUB_OUTPUT"
3435
elif [ -n "${GITHUB_BEFORE:-}" ] &&
3536
[ "$GITHUB_BEFORE" != 0000000000000000000000000000000000000000 ]; then

‎apps/desktop/e2e/fixtures/live-sim.ts‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,9 +651,16 @@ export class SimDatabase {
651651
}
652652

653653
async close(): Promise<void> {
654-
if (this.userIds.length > 0)
655-
await this.sql`delete from "user" where id in ${this.sql(this.userIds)}`.catch(() => {})
656-
await this.sql.end({ timeout: 5 })
654+
try {
655+
if (this.userIds.length > 0)
656+
await this.sql.begin(async (tx) => {
657+
await tx`delete from workspace where owner_id in ${tx(this.userIds)}`
658+
await tx`delete from project where owner_id in ${tx(this.userIds)}`
659+
await tx`delete from "user" where id in ${tx(this.userIds)}`
660+
})
661+
} finally {
662+
await this.sql.end({ timeout: 5 })
663+
}
657664
}
658665

659666
/** A user with a workspace, a session as the desktop sign-in creates, and one chat per title. */
@@ -671,6 +678,10 @@ export class SimDatabase {
671678
await tx`insert into user_stats (id, user_id) values (${generateId()}, ${userId})`
672679
await tx`insert into workspace (id, name, owner_id, billed_account_user_id)
673680
values (${workspaceId}, 'Desktop tools E2E', ${userId}, ${userId})`
681+
await tx`insert into project (id, name, owner_id)
682+
values (${workspaceId}, 'E2E fixture project', ${userId})`
683+
await tx`insert into project_workspace (project_id, workspace_id)
684+
values (${workspaceId}, ${workspaceId})`
674685
await tx`insert into permissions (id, user_id, entity_type, entity_id, permission_type)
675686
values (${generateId()}, ${userId}, 'workspace', ${workspaceId}, 'admin')`
676687
await tx`insert into session (id, token, user_id, user_agent, expires_at, created_at, updated_at)

‎apps/sim/app/api/copilot/chat/stream/desktop-executor.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Redis through the production reconnect route, for the live tail and the replay batch a view
55
* attaches with after a reload.
66
*/
7+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
78
import { authMock, authMockFns } from '@sim/testing/mocks/auth.mock'
89
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
910

@@ -72,7 +73,7 @@ describe.runIf(Boolean(redisUrl))('desktop executor binding on a chat stream', (
7273
createdAt: now,
7374
updatedAt: now,
7475
})
75-
await db.insert(workspace).values({
76+
await insertWorkspaceFixture(db, {
7677
id: workspaceId,
7778
name: 'Desktop stream fixture',
7879
ownerId: userId,
@@ -105,7 +106,7 @@ describe.runIf(Boolean(redisUrl))('desktop executor binding on a chat stream', (
105106
await db.delete(copilotChats).where(eq(copilotChats.id, chatId))
106107
await db.delete(desktopDevices).where(eq(desktopDevices.id, deviceId))
107108
await db.delete(permissions).where(eq(permissions.userId, userId))
108-
await db.delete(workspace).where(eq(workspace.id, workspaceId))
109+
await deleteWorkspaceFixture(db, eq(workspace.id, workspaceId))
109110
await db.delete(user).where(eq(user.id, userId))
110111
await closeRedisConnection()
111112
})

‎apps/sim/lib/credentials/application/credential-sharing.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
12
import { generateId } from '@sim/utils/id'
23
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
34

@@ -49,7 +50,7 @@ describe('Credential sharing through user-held API credentials in PostgreSQL', (
4950
role: 'admin',
5051
createdAt: new Date(),
5152
})
52-
await db.insert(schema.workspace).values({
53+
await insertWorkspaceFixture(db, {
5354
id: workspaceId,
5455
name: 'Sharing test',
5556
ownerId: actorId,
@@ -85,7 +86,7 @@ describe('Credential sharing through user-held API credentials in PostgreSQL', (
8586
afterAll(async () => {
8687
if (!runtime) return
8788
const { db, schema, eq, inArray } = runtime
88-
await db.delete(schema.workspace).where(eq(schema.workspace.id, workspaceId))
89+
await deleteWorkspaceFixture(db, eq(schema.workspace.id, workspaceId))
8990
await db.delete(schema.organization).where(eq(schema.organization.id, organizationId))
9091
await db
9192
.delete(schema.user)

‎apps/sim/lib/desktop/application/activity.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Background desktop activity against real PostgreSQL and Redis: which of a user's chats a desktop
33
* runs, and whether each is running, waiting on the user's approval, or blocked by an offline desktop.
44
*/
5+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
56
import { afterAll, describe, expect, it, vi } from 'vitest'
67

78
const { redisUrl } = await vi.hoisted(async () => {
@@ -42,7 +43,7 @@ describe.runIf(Boolean(redisUrl))('background desktop activity', () => {
4243
const deviceIds: string[] = []
4344

4445
afterAll(async () => {
45-
if (workspaceIds.length) await db.delete(workspace).where(inArray(workspace.id, workspaceIds))
46+
if (workspaceIds.length) await deleteWorkspaceFixture(db, inArray(workspace.id, workspaceIds))
4647
if (deviceIds.length)
4748
await db.delete(desktopDevices).where(inArray(desktopDevices.id, deviceIds))
4849
if (userIds.length) await db.delete(user).where(inArray(user.id, userIds))
@@ -65,7 +66,7 @@ describe.runIf(Boolean(redisUrl))('background desktop activity', () => {
6566
createdAt: now,
6667
updatedAt: now,
6768
})
68-
await db.insert(workspace).values({
69+
await insertWorkspaceFixture(db, {
6970
id: workspaceId,
7071
name: 'Desktop activity fixture',
7172
ownerId: userId,

‎apps/sim/lib/desktop/application/executor.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* completion. Calls are persisted the way the run loop persists a bound run's desktop calls, and
55
* Stop runs through the real `requestRunStop`.
66
*/
7+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
78
import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'
89

910
const { redisUrl, presence } = await vi.hoisted(async () => {
@@ -87,7 +88,7 @@ describe.runIf(Boolean(redisUrl))('desktop background executor protocol', () =>
8788
})
8889
const workspaceId = generateId()
8990
workspaceIds.set(userId, workspaceId)
90-
await db.insert(workspace).values({
91+
await insertWorkspaceFixture(db, {
9192
id: workspaceId,
9293
name: 'Desktop executor fixture',
9394
ownerId: userId,
@@ -243,7 +244,7 @@ describe.runIf(Boolean(redisUrl))('desktop background executor protocol', () =>
243244
await db.delete(desktopDevices).where(inArray(desktopDevices.id, deviceIds))
244245
}
245246
const workspaces = [...workspaceIds.values()]
246-
if (workspaces.length) await db.delete(workspace).where(inArray(workspace.id, workspaces))
247+
if (workspaces.length) await deleteWorkspaceFixture(db, inArray(workspace.id, workspaces))
247248
if (userIds.length) await db.delete(user).where(inArray(user.id, userIds))
248249
})
249250

‎apps/sim/lib/desktop/application/import.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { mkdtempSync } from 'node:fs'
88
import { rm } from 'node:fs/promises'
99
import { tmpdir } from 'node:os'
1010
import path from 'node:path'
11+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
1112
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
1213

1314
const fixtureStorage = vi.hoisted(() => ({ root: '' }))
@@ -52,7 +53,7 @@ describe('desktop imports', () => {
5253
if (userIds.length) {
5354
// Audit rows outlive their actor (the foreign key sets null), so they go first.
5455
await db.delete(auditLog).where(inArray(auditLog.actorId, userIds))
55-
await db.delete(workspace).where(inArray(workspace.ownerId, userIds))
56+
await deleteWorkspaceFixture(db, inArray(workspace.ownerId, userIds))
5657
await db.delete(user).where(inArray(user.id, userIds))
5758
}
5859
await rm(fixtureStorage.root, { recursive: true, force: true })
@@ -75,7 +76,7 @@ describe('desktop imports', () => {
7576
updatedAt: now,
7677
})
7778
await db.insert(userStats).values({ id: generateId(), userId })
78-
await db.insert(workspace).values({
79+
await insertWorkspaceFixture(db, {
7980
id: workspaceId,
8081
name: 'Desktop import fixture',
8182
ownerId: userId,

‎apps/sim/lib/desktop/executor/bound-turn.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* through the real `requestRunStop`, and a waiter that dies is settled by the stale-execution cron.
66
* Deadlines are moved on the row itself, which is all the server reads.
77
*/
8+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
89
import { authMock, authMockFns } from '@sim/testing/mocks/auth.mock'
910
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
1011

@@ -340,7 +341,7 @@ describe.runIf(Boolean(redisUrl))("a turn bound to a desktop's background execut
340341
createdAt: now,
341342
updatedAt: now,
342343
})
343-
await db.insert(workspace).values({
344+
await insertWorkspaceFixture(db, {
344345
id: workspaceId,
345346
name: 'Bound turn fixture',
346347
ownerId: userId,
@@ -369,7 +370,7 @@ describe.runIf(Boolean(redisUrl))("a turn bound to a desktop's background execut
369370
await db.delete(auditLog).where(inArray(auditLog.resourceId, deviceIds))
370371
await db.delete(desktopDevices).where(inArray(desktopDevices.id, deviceIds))
371372
}
372-
await db.delete(workspace).where(eq(workspace.id, workspaceId))
373+
await deleteWorkspaceFixture(db, eq(workspace.id, workspaceId))
373374
await db.delete(user).where(eq(user.id, userId))
374375
})
375376

‎apps/sim/lib/desktop/executor/desktop-call-classifier.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
user,
1515
workspace,
1616
} from '@sim/db/schema'
17+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
1718
import { generateId } from '@sim/utils/id'
1819
import { eq, sql } from 'drizzle-orm'
1920
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
@@ -105,7 +106,7 @@ describe('desktop call classification in SQL and TypeScript', () => {
105106
createdAt: now,
106107
updatedAt: now,
107108
})
108-
await db.insert(workspace).values({
109+
await insertWorkspaceFixture(db, {
109110
id: workspaceId,
110111
name: 'Classifier parity fixture',
111112
ownerId: userId,
@@ -154,7 +155,7 @@ describe('desktop call classification in SQL and TypeScript', () => {
154155
afterAll(async () => {
155156
await db.delete(copilotChats).where(eq(copilotChats.id, chatId))
156157
await db.delete(desktopDevices).where(eq(desktopDevices.id, deviceId))
157-
await db.delete(workspace).where(eq(workspace.id, workspaceId))
158+
await deleteWorkspaceFixture(db, eq(workspace.id, workspaceId))
158159
await db.delete(user).where(eq(user.id, userId))
159160
})
160161

‎apps/sim/lib/mothership/tools/client/desktop-tool-chat-view-lease.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Runs against real PostgreSQL and Redis through the production pre-persist path, the authorize
66
* route, the lease route and the confirm route.
77
*/
8+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
89
import { authMock, authMockFns } from '@sim/testing/mocks/auth.mock'
910
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
1011

@@ -202,7 +203,7 @@ describe.runIf(Boolean(redisUrl))('a chat-view import kept alive by its lease',
202203
createdAt: now,
203204
updatedAt: now,
204205
})
205-
await db.insert(workspace).values({
206+
await insertWorkspaceFixture(db, {
206207
id: workspaceId,
207208
name: 'Chat-view lease fixture',
208209
ownerId: userId,
@@ -226,7 +227,7 @@ describe.runIf(Boolean(redisUrl))('a chat-view import kept alive by its lease',
226227

227228
afterAll(async () => {
228229
await db.delete(copilotChats).where(eq(copilotChats.id, chatId))
229-
await db.delete(workspace).where(eq(workspace.id, workspaceId))
230+
await deleteWorkspaceFixture(db, eq(workspace.id, workspaceId))
230231
await db.delete(user).where(eq(user.id, userId))
231232
await db.delete(user).where(eq(user.id, otherUserId))
232233
})

0 commit comments

Comments
 (0)