@markjaquith/agency 2.74.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -121
- package/cli-main.ts +0 -26
- package/cli.ts +1 -17
- package/package.json +1 -2
- package/schemas/agency-graph-v1.schema.json +1 -1
- package/src/cli-parser.test.ts +0 -19
- package/src/cli-parser.ts +0 -23
- package/src/cli.test.ts +3 -3
- package/src/commands/context.test.ts +0 -67
- package/src/commands/init.test.ts +1 -2
- package/src/commands/pr.test.ts +2 -87
- package/src/commands/pr.ts +2 -79
- package/src/commands/push.test.ts +1 -2
- package/src/graph-schema.ts +1 -1
- package/src/services/ArchiveBulkService.test.ts +1 -142
- package/src/services/ArchiveService.test.ts +1 -172
- package/src/services/ArchiveService.ts +0 -26
- package/src/services/ContextService.ts +3 -47
- package/src/services/DoctorService.ts +8 -24
- package/src/services/GraphService.test.ts +1 -0
- package/src/services/GraphService.ts +2 -5
- package/src/services/PhaseService.ts +70 -191
- package/src/services/PullRequestService.test.ts +1 -45
- package/src/services/PullRequestService.ts +1 -22
- package/src/services/PushService.test.ts +29 -295
- package/src/services/PushService.ts +10 -239
- package/src/services/RepositoryService.test.ts +1 -61
- package/src/services/RepositoryService.ts +2 -13
- package/src/services/ReviewService.test.ts +1 -84
- package/src/services/ReviewService.ts +9 -48
- package/src/services/SyncService.test.ts +0 -81
- package/src/services/SyncService.ts +12 -39
- package/src/services/TaskPhaseService.test.ts +0 -80
- package/src/services/TaskService.ts +1 -9
- package/src/services/VersionControlService.test.ts +4 -117
- package/src/services/VersionControlService.ts +3 -426
- package/src/services/WorkbaseService.test.ts +0 -20
- package/src/services/WorkbaseService.ts +1 -18
- package/src/services/WorktreeService.test.ts +1 -705
- package/src/services/WorktreeService.ts +395 -1604
- package/src/services/push-validation.ts +0 -7
- package/src/test-utils.ts +0 -4
- package/src/workbase/AGENTS.md +4 -5
- package/src/workbase/checkout-command.test.ts +1 -1
- package/src/workbase/checkout-command.ts +1 -1
- package/src/workbase/delivery-command.test.ts +4 -35
- package/src/workbase/delivery-command.ts +2 -15
- package/src/workbase/schemas.test.ts +0 -19
- package/src/workbase/schemas.ts +1 -2
- package/src/commands/vcs.test.ts +0 -75
- package/src/commands/vcs.ts +0 -72
- package/src/services/VcsMigrationService.test.ts +0 -348
- package/src/services/VcsMigrationService.ts +0 -857
- package/src/vcs-status-fast.ts +0 -310
- package/src/workbase/version-control.ts +0 -5
- package/src/workbase/workspace-command.test.ts +0 -70
- package/src/workbase/workspace-command.ts +0 -63
|
@@ -125,20 +125,12 @@ export class DoctorService extends Effect.Service<DoctorService>()(
|
|
|
125
125
|
return available
|
|
126
126
|
})
|
|
127
127
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"jj",
|
|
134
|
-
config.vcs === "jj" ? "error" : "optional",
|
|
135
|
-
"Jujutsu",
|
|
136
|
-
),
|
|
137
|
-
],
|
|
138
|
-
{ concurrency: "unbounded", batching: true },
|
|
128
|
+
const versionControlAvailable = yield* tool(
|
|
129
|
+
"tool.git",
|
|
130
|
+
"git",
|
|
131
|
+
"error",
|
|
132
|
+
"Git",
|
|
139
133
|
)
|
|
140
|
-
const versionControlAvailable =
|
|
141
|
-
gitAvailable && (config.vcs !== "jj" || jjAvailable)
|
|
142
134
|
yield* Effect.all(
|
|
143
135
|
[
|
|
144
136
|
tool(
|
|
@@ -180,15 +172,6 @@ export class DoctorService extends Effect.Service<DoctorService>()(
|
|
|
180
172
|
] as const,
|
|
181
173
|
]
|
|
182
174
|
: []),
|
|
183
|
-
...(config.workspaceCreateCommand
|
|
184
|
-
? [
|
|
185
|
-
[
|
|
186
|
-
"integration.workspace-create",
|
|
187
|
-
config.workspaceCreateCommand,
|
|
188
|
-
"Workspace creator",
|
|
189
|
-
] as const,
|
|
190
|
-
]
|
|
191
|
-
: []),
|
|
192
175
|
...Object.entries(config.repositories ?? {}).flatMap(
|
|
193
176
|
([alias, repository]) =>
|
|
194
177
|
repository.postCheckoutCommand
|
|
@@ -384,8 +367,9 @@ export class DoctorService extends Effect.Service<DoctorService>()(
|
|
|
384
367
|
category: "repository",
|
|
385
368
|
level: "warning",
|
|
386
369
|
status: "fail",
|
|
387
|
-
message:
|
|
388
|
-
|
|
370
|
+
message:
|
|
371
|
+
"Repository, ref, remote, and workspace checks were skipped because Git is unavailable",
|
|
372
|
+
remediation: "Install 'git' and rerun 'agency doctor'.",
|
|
389
373
|
})
|
|
390
374
|
}
|
|
391
375
|
for (const repository of repositoryList) {
|
|
@@ -121,6 +121,7 @@ describe("GraphService", () => {
|
|
|
121
121
|
const graph = await getGraph(root)
|
|
122
122
|
|
|
123
123
|
expect(Schema.decodeUnknownSync(AgencyGraph)(graph)).toEqual(graph)
|
|
124
|
+
expect(graph.workbase.vcs).toBe("git")
|
|
124
125
|
expect(graph.nodes.map((node) => node.id)).toEqual([
|
|
125
126
|
"epic:delivery",
|
|
126
127
|
"execution-unit:phase/ship/implement",
|
|
@@ -821,10 +821,7 @@ export class GraphService extends Effect.Service<GraphService>()(
|
|
|
821
821
|
checkoutCommit: materialized
|
|
822
822
|
? yield* backend.workspaceHead(checkoutPath)
|
|
823
823
|
: null,
|
|
824
|
-
checkoutBranch:
|
|
825
|
-
backend.kind === "jj" && materialized
|
|
826
|
-
? data.branch
|
|
827
|
-
: actualBranch,
|
|
824
|
+
checkoutBranch: actualBranch,
|
|
828
825
|
dirty: materialized
|
|
829
826
|
? yield* backend.workspaceDirty(checkoutPath)
|
|
830
827
|
: null,
|
|
@@ -1022,7 +1019,7 @@ export class GraphService extends Effect.Service<GraphService>()(
|
|
|
1022
1019
|
version: GRAPH_VERSION,
|
|
1023
1020
|
workbase: {
|
|
1024
1021
|
version: config.version,
|
|
1025
|
-
vcs:
|
|
1022
|
+
vcs: "git",
|
|
1026
1023
|
...(include.has("workspace") ? { root } : {}),
|
|
1027
1024
|
},
|
|
1028
1025
|
filters,
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
buildNonPrCompletion,
|
|
31
31
|
type NonPrCompletionInput,
|
|
32
32
|
} from "../workbase/completion"
|
|
33
|
-
import { VersionControlService } from "./VersionControlService"
|
|
34
33
|
|
|
35
34
|
class PhaseError extends Data.TaggedError("PhaseError")<{
|
|
36
35
|
readonly message: string
|
|
@@ -93,10 +92,8 @@ export class PhaseService extends Effect.Service<PhaseService>()(
|
|
|
93
92
|
Effect.gen(function* () {
|
|
94
93
|
const fs = yield* FileSystemService
|
|
95
94
|
const workbase = yield* WorkbaseService
|
|
96
|
-
const versionControl = yield* VersionControlService
|
|
97
95
|
const tasks = yield* TaskService
|
|
98
96
|
const root = yield* workbase.discover(startPath)
|
|
99
|
-
const backend = yield* versionControl.forWorkbase(root)
|
|
100
97
|
const taskId = yield* decodeId(input.taskId, "task")
|
|
101
98
|
const id = yield* decodeId(input.id, "phase")
|
|
102
99
|
const task = yield* tasks.show(taskId, root)
|
|
@@ -274,213 +271,95 @@ export class PhaseService extends Effect.Service<PhaseService>()(
|
|
|
274
271
|
firstData.repo,
|
|
275
272
|
...(firstData.repos ?? []).map((reference) => reference.repo),
|
|
276
273
|
]
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
alias
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
continue
|
|
308
|
-
}
|
|
309
|
-
const expected = await realpath(oldPath)
|
|
310
|
-
const registered = (
|
|
311
|
-
await runBackend(
|
|
312
|
-
backend.listWorkspaces(join(root, "repos", alias)),
|
|
313
|
-
)
|
|
314
|
-
).find((workspace) => workspace.path === expected)
|
|
315
|
-
if (!registered?.name)
|
|
316
|
-
throw new Error(
|
|
317
|
-
`Cannot convert task '${taskId}'; checkout '${alias}' is not registered as a jj workspace`,
|
|
318
|
-
)
|
|
319
|
-
if (await runBackend(backend.workspaceDirty(oldPath)))
|
|
320
|
-
throw new Error(
|
|
321
|
-
`Cannot convert task '${taskId}'; jj workspace '${alias}' has uncommitted changes`,
|
|
322
|
-
)
|
|
323
|
-
const head = await runBackend(
|
|
324
|
-
backend.workspaceHead(oldPath),
|
|
325
|
-
)
|
|
326
|
-
if (!head)
|
|
327
|
-
throw new Error(
|
|
328
|
-
`Cannot resolve jj workspace '${alias}' before conversion`,
|
|
329
|
-
)
|
|
330
|
-
workspaces.push({
|
|
331
|
-
alias,
|
|
332
|
-
name: registered.name,
|
|
333
|
-
head,
|
|
334
|
-
oldPath,
|
|
335
|
-
newPath: join(firstCodePath, alias),
|
|
336
|
-
})
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
apply: async () => {
|
|
340
|
-
await mkdir(firstCodePath, { recursive: true })
|
|
341
|
-
for (const workspace of workspaces) {
|
|
342
|
-
const repositoryPath = join(
|
|
343
|
-
root,
|
|
344
|
-
"repos",
|
|
345
|
-
workspace.alias,
|
|
346
|
-
)
|
|
347
|
-
await runBackend(
|
|
348
|
-
backend.removeWorkspace({
|
|
349
|
-
repositoryPath,
|
|
350
|
-
workspacePath: workspace.oldPath,
|
|
351
|
-
workspaceName: workspace.name,
|
|
352
|
-
}),
|
|
353
|
-
)
|
|
354
|
-
await runBackend(
|
|
355
|
-
backend.createWorkspace({
|
|
356
|
-
repositoryPath,
|
|
357
|
-
workspacePath: workspace.newPath,
|
|
358
|
-
workspaceName: workspace.name,
|
|
359
|
-
revision: workspace.head,
|
|
360
|
-
}),
|
|
361
|
-
)
|
|
362
|
-
}
|
|
363
|
-
await rm(oldCodePath, { recursive: true, force: true })
|
|
364
|
-
},
|
|
365
|
-
rollback: async () => {
|
|
366
|
-
await mkdir(oldCodePath, { recursive: true })
|
|
367
|
-
for (const workspace of [...workspaces].reverse()) {
|
|
368
|
-
const repositoryPath = join(
|
|
369
|
-
root,
|
|
370
|
-
"repos",
|
|
371
|
-
workspace.alias,
|
|
372
|
-
)
|
|
373
|
-
await runBackend(
|
|
374
|
-
backend.removeWorkspace({
|
|
375
|
-
repositoryPath,
|
|
376
|
-
workspacePath: workspace.newPath,
|
|
377
|
-
workspaceName: workspace.name,
|
|
378
|
-
}),
|
|
379
|
-
)
|
|
380
|
-
await runBackend(
|
|
381
|
-
backend.createWorkspace({
|
|
382
|
-
repositoryPath,
|
|
383
|
-
workspacePath: workspace.oldPath,
|
|
384
|
-
workspaceName: workspace.name,
|
|
385
|
-
revision: workspace.head,
|
|
386
|
-
}),
|
|
274
|
+
const repair = async (basePath: string) => {
|
|
275
|
+
for (const alias of checkoutAliases) {
|
|
276
|
+
const checkoutPath = join(basePath, alias)
|
|
277
|
+
try {
|
|
278
|
+
await lstat(checkoutPath)
|
|
279
|
+
} catch {
|
|
280
|
+
continue
|
|
281
|
+
}
|
|
282
|
+
const result = Bun.spawnSync([
|
|
283
|
+
"git",
|
|
284
|
+
"-C",
|
|
285
|
+
join(root, "repos", alias),
|
|
286
|
+
"worktree",
|
|
287
|
+
"repair",
|
|
288
|
+
checkoutPath,
|
|
289
|
+
])
|
|
290
|
+
if (result.exitCode !== 0) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Failed to repair moved worktree for '${alias}': ${new TextDecoder().decode(result.stderr)}`,
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
steps.push({
|
|
298
|
+
label: `move and repair code for ${taskId}/${firstPhaseId}`,
|
|
299
|
+
preflight: async () => {
|
|
300
|
+
for (const entry of await readdir(oldCodePath)) {
|
|
301
|
+
if (!checkoutAliases.includes(entry))
|
|
302
|
+
throw new Error(
|
|
303
|
+
`Cannot convert task '${taskId}'; code contains unmanaged entry '${entry}'`,
|
|
387
304
|
)
|
|
388
|
-
|
|
389
|
-
await rm(firstDirectory, { recursive: true, force: true })
|
|
390
|
-
},
|
|
391
|
-
manualRecovery: `Restore jj workspaces from ${firstCodePath} to ${oldCodePath}`,
|
|
392
|
-
})
|
|
393
|
-
} else {
|
|
394
|
-
const repair = async (basePath: string) => {
|
|
305
|
+
}
|
|
395
306
|
for (const alias of checkoutAliases) {
|
|
396
|
-
const checkoutPath = join(
|
|
307
|
+
const checkoutPath = join(oldCodePath, alias)
|
|
397
308
|
try {
|
|
398
309
|
await lstat(checkoutPath)
|
|
399
310
|
} catch {
|
|
400
311
|
continue
|
|
401
312
|
}
|
|
402
|
-
const
|
|
313
|
+
const listed = Bun.spawnSync([
|
|
403
314
|
"git",
|
|
404
315
|
"-C",
|
|
405
316
|
join(root, "repos", alias),
|
|
406
317
|
"worktree",
|
|
407
|
-
"
|
|
408
|
-
|
|
318
|
+
"list",
|
|
319
|
+
"--porcelain",
|
|
409
320
|
])
|
|
410
|
-
if (
|
|
321
|
+
if (listed.exitCode !== 0)
|
|
411
322
|
throw new Error(
|
|
412
|
-
`Failed to
|
|
323
|
+
`Failed to inspect worktrees for '${alias}'`,
|
|
413
324
|
)
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
for (const entry of await readdir(oldCodePath)) {
|
|
421
|
-
if (!checkoutAliases.includes(entry))
|
|
422
|
-
throw new Error(
|
|
423
|
-
`Cannot convert task '${taskId}'; code contains unmanaged entry '${entry}'`,
|
|
424
|
-
)
|
|
425
|
-
}
|
|
426
|
-
for (const alias of checkoutAliases) {
|
|
427
|
-
const checkoutPath = join(oldCodePath, alias)
|
|
325
|
+
const expected = await realpath(checkoutPath)
|
|
326
|
+
let registered = false
|
|
327
|
+
for (const line of new TextDecoder()
|
|
328
|
+
.decode(listed.stdout)
|
|
329
|
+
.split("\n")) {
|
|
330
|
+
if (!line.startsWith("worktree ")) continue
|
|
428
331
|
try {
|
|
429
|
-
await
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
"git",
|
|
435
|
-
"-C",
|
|
436
|
-
join(root, "repos", alias),
|
|
437
|
-
"worktree",
|
|
438
|
-
"list",
|
|
439
|
-
"--porcelain",
|
|
440
|
-
])
|
|
441
|
-
if (listed.exitCode !== 0)
|
|
442
|
-
throw new Error(
|
|
443
|
-
`Failed to inspect worktrees for '${alias}'`,
|
|
444
|
-
)
|
|
445
|
-
const expected = await realpath(checkoutPath)
|
|
446
|
-
let registered = false
|
|
447
|
-
for (const line of new TextDecoder()
|
|
448
|
-
.decode(listed.stdout)
|
|
449
|
-
.split("\n")) {
|
|
450
|
-
if (!line.startsWith("worktree ")) continue
|
|
451
|
-
try {
|
|
452
|
-
if ((await realpath(line.slice(9))) === expected) {
|
|
453
|
-
registered = true
|
|
454
|
-
break
|
|
455
|
-
}
|
|
456
|
-
} catch {}
|
|
457
|
-
}
|
|
458
|
-
if (!registered)
|
|
459
|
-
throw new Error(
|
|
460
|
-
`Cannot convert task '${taskId}'; checkout '${alias}' is not registered as a Git worktree`,
|
|
461
|
-
)
|
|
462
|
-
}
|
|
463
|
-
},
|
|
464
|
-
apply: async () => {
|
|
465
|
-
await mkdir(firstDirectory, { recursive: true })
|
|
466
|
-
await rename(oldCodePath, firstCodePath)
|
|
467
|
-
try {
|
|
468
|
-
await repair(firstCodePath)
|
|
469
|
-
} catch (cause) {
|
|
470
|
-
await rename(firstCodePath, oldCodePath)
|
|
471
|
-
await repair(oldCodePath)
|
|
472
|
-
await rm(firstDirectory, { recursive: true, force: true })
|
|
473
|
-
throw cause
|
|
332
|
+
if ((await realpath(line.slice(9))) === expected) {
|
|
333
|
+
registered = true
|
|
334
|
+
break
|
|
335
|
+
}
|
|
336
|
+
} catch {}
|
|
474
337
|
}
|
|
475
|
-
|
|
476
|
-
|
|
338
|
+
if (!registered)
|
|
339
|
+
throw new Error(
|
|
340
|
+
`Cannot convert task '${taskId}'; checkout '${alias}' is not registered as a Git worktree`,
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
apply: async () => {
|
|
345
|
+
await mkdir(firstDirectory, { recursive: true })
|
|
346
|
+
await rename(oldCodePath, firstCodePath)
|
|
347
|
+
try {
|
|
348
|
+
await repair(firstCodePath)
|
|
349
|
+
} catch (cause) {
|
|
477
350
|
await rename(firstCodePath, oldCodePath)
|
|
478
351
|
await repair(oldCodePath)
|
|
479
352
|
await rm(firstDirectory, { recursive: true, force: true })
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
|
|
353
|
+
throw cause
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
rollback: async () => {
|
|
357
|
+
await rename(firstCodePath, oldCodePath)
|
|
358
|
+
await repair(oldCodePath)
|
|
359
|
+
await rm(firstDirectory, { recursive: true, force: true })
|
|
360
|
+
},
|
|
361
|
+
manualRecovery: `Move ${firstCodePath} back to ${oldCodePath} and run git worktree repair`,
|
|
362
|
+
})
|
|
484
363
|
}
|
|
485
364
|
steps.push(
|
|
486
365
|
documentWriteStep(root, [
|
|
@@ -98,7 +98,7 @@ describe("PullRequestService", () => {
|
|
|
98
98
|
await Bun.write(
|
|
99
99
|
path,
|
|
100
100
|
`#!/usr/bin/env bun
|
|
101
|
-
await Bun.write(${JSON.stringify(ghCallPath)}, JSON.stringify({ args: Bun.argv.slice(2), cwd: process.cwd()
|
|
101
|
+
await Bun.write(${JSON.stringify(ghCallPath)}, JSON.stringify({ args: Bun.argv.slice(2), cwd: process.cwd() }))
|
|
102
102
|
process.stdout.write(${JSON.stringify(stdout)})
|
|
103
103
|
process.stderr.write(${JSON.stringify(stderr)})
|
|
104
104
|
process.exit(${exitCode})
|
|
@@ -111,7 +111,6 @@ process.exit(${exitCode})
|
|
|
111
111
|
(await Bun.file(ghCallPath).json()) as {
|
|
112
112
|
args: string[]
|
|
113
113
|
cwd: string
|
|
114
|
-
gitDir?: string
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
const expectRemoteBranch = async (branch: string, exists = true) => {
|
|
@@ -243,49 +242,6 @@ process.exit(${exitCode})
|
|
|
243
242
|
expect(updated.endsWith(`${body}\n`)).toBe(true)
|
|
244
243
|
})
|
|
245
244
|
|
|
246
|
-
test("creates a PR from a non-colocated jj workspace with backing Git context", async () => {
|
|
247
|
-
if (!Bun.which("jj")) return
|
|
248
|
-
await rm(join(root, "repos/agency"), { recursive: true, force: true })
|
|
249
|
-
await requireCommand([
|
|
250
|
-
"jj",
|
|
251
|
-
"git",
|
|
252
|
-
"clone",
|
|
253
|
-
"--no-colocate",
|
|
254
|
-
remotePath,
|
|
255
|
-
join(root, "repos/agency"),
|
|
256
|
-
])
|
|
257
|
-
await requireCommand(
|
|
258
|
-
["jj", "config", "set", "--repo", "user.name", "Agency Test"],
|
|
259
|
-
join(root, "repos/agency"),
|
|
260
|
-
)
|
|
261
|
-
await requireCommand(
|
|
262
|
-
["jj", "config", "set", "--repo", "user.email", "agency@example.com"],
|
|
263
|
-
join(root, "repos/agency"),
|
|
264
|
-
)
|
|
265
|
-
await Bun.write(
|
|
266
|
-
join(root, "agency.json"),
|
|
267
|
-
JSON.stringify({ version: 2, vcs: "jj" }),
|
|
268
|
-
)
|
|
269
|
-
await createTask("jj-example", "task/jj-example")
|
|
270
|
-
const workspace = await materialize("jj-example")
|
|
271
|
-
await Bun.write(join(workspace.writablePath!, "CHANGE.md"), "jj change\n")
|
|
272
|
-
await requireCommand(
|
|
273
|
-
["jj", "describe", "-m", "feat: add jj example"],
|
|
274
|
-
workspace.writablePath!,
|
|
275
|
-
)
|
|
276
|
-
await requireCommand(["jj", "new"], workspace.writablePath!)
|
|
277
|
-
const url = "https://github.com/example/agency/pull/44"
|
|
278
|
-
await writeFakeGh({ stdout: `${url}\n` })
|
|
279
|
-
|
|
280
|
-
expect(await createPullRequest("jj-example")).toBe(url)
|
|
281
|
-
await expectRemoteBranch("task/jj-example")
|
|
282
|
-
const ghCall = await readGhCall()
|
|
283
|
-
expect(ghCall.args).toContain("--head")
|
|
284
|
-
expect(ghCall.args).toContain("--repo")
|
|
285
|
-
expect(ghCall.gitDir).toContain(".jj")
|
|
286
|
-
expect(await Bun.file(join(root, "repos/agency/.git")).exists()).toBe(false)
|
|
287
|
-
})
|
|
288
|
-
|
|
289
245
|
test("passes --draft to gh", async () => {
|
|
290
246
|
await createTask()
|
|
291
247
|
await writeFakeGh({
|
|
@@ -195,20 +195,6 @@ export class PullRequestService extends Effect.Service<PullRequestService>()(
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
yield* backend.push(workspace.writablePath, remote, execution.branch)
|
|
198
|
-
const defaults =
|
|
199
|
-
backend.kind === "jj"
|
|
200
|
-
? yield* backend.pullRequestDefaults(
|
|
201
|
-
workspace.writablePath,
|
|
202
|
-
execution.base,
|
|
203
|
-
)
|
|
204
|
-
: null
|
|
205
|
-
if (backend.kind === "jj" && !defaults) {
|
|
206
|
-
return yield* new PullRequestError({
|
|
207
|
-
message:
|
|
208
|
-
"Failed to derive pull request title and body from jj commits",
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
|
|
212
198
|
const remoteUrl = yield* backend.remoteUrl(
|
|
213
199
|
workspace.writablePath,
|
|
214
200
|
remote,
|
|
@@ -230,22 +216,15 @@ export class PullRequestService extends Effect.Service<PullRequestService>()(
|
|
|
230
216
|
})
|
|
231
217
|
: resolveGitHubCreateCommand({
|
|
232
218
|
base: execution.base,
|
|
233
|
-
branch: execution.branch,
|
|
234
|
-
repository,
|
|
235
219
|
draft,
|
|
236
|
-
vcs: config.vcs ?? "git",
|
|
237
220
|
title: options.title,
|
|
238
221
|
head: options.head,
|
|
239
222
|
labels: options.labels,
|
|
240
|
-
...(defaults ? { defaults } : {}),
|
|
241
223
|
})
|
|
242
|
-
const gitEnvironment = config.delivery
|
|
243
|
-
? {}
|
|
244
|
-
: yield* backend.gitEnvironment(workspace.writablePath)
|
|
245
224
|
const created = yield* fs.runCommand(resolved.argv, {
|
|
246
225
|
cwd: workspace.writablePath,
|
|
247
226
|
captureOutput: true,
|
|
248
|
-
env:
|
|
227
|
+
env: resolved.environment,
|
|
249
228
|
})
|
|
250
229
|
if (created.exitCode !== 0) {
|
|
251
230
|
return yield* new PullRequestError({
|