Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion apps/server/src/git/Layers/GitManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2739,7 +2739,17 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => {
expect.objectContaining({
kind: "phase_started",
phase: "pr",
label: "Creating PR...",
label: "Preparing PR...",
}),
expect.objectContaining({
kind: "phase_started",
phase: "pr",
label: "Generating PR content...",
}),
expect.objectContaining({
kind: "phase_started",
phase: "pr",
label: "Creating GitHub pull request...",
}),
]);
}),
Expand Down
18 changes: 16 additions & 2 deletions apps/server/src/git/Layers/GitManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const STATUS_RESULT_CACHE_TTL = Duration.seconds(1);
const STATUS_RESULT_CACHE_CAPACITY = 2_048;
type StripProgressContext<T> = T extends any ? Omit<T, "actionId" | "cwd" | "action"> : never;
type GitActionProgressPayload = StripProgressContext<GitActionProgressEvent>;
type GitActionProgressEmitter = (event: GitActionProgressPayload) => Effect.Effect<void, never>;

interface OpenPrInfo {
number: number;
Expand Down Expand Up @@ -1200,6 +1201,7 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () {
modelSelection: ModelSelection,
cwd: string,
fallbackBranch: string | null,
emit: GitActionProgressEmitter,
) {
const details = yield* gitCore.statusDetails(cwd);
const branch = details.branch ?? fallbackBranch;
Expand Down Expand Up @@ -1234,6 +1236,11 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () {
}

const baseBranch = yield* resolveBaseBranch(cwd, branch, details.upstreamRef, headContext);
yield* emit({
kind: "phase_started",
phase: "pr",
label: "Generating PR content...",
});
const rangeContext = yield* gitCore.readRangeContext(cwd, baseBranch);

const generated = yield* textGeneration.generatePrContent({
Expand All @@ -1254,6 +1261,11 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () {
gitManagerError("runPrStep", "Failed to write pull request body temp file.", cause),
),
);
yield* emit({
kind: "phase_started",
phase: "pr",
label: "Creating GitHub pull request...",
});
yield* gitHubCli
.createPullRequest({
cwd,
Expand Down Expand Up @@ -1612,11 +1624,13 @@ export const makeGitManager = Effect.fn("makeGitManager")(function* () {
.emit({
kind: "phase_started",
phase: "pr",
label: "Creating PR...",
label: "Preparing PR...",
})
.pipe(
Effect.tap(() => Ref.set(currentPhase, Option.some("pr"))),
Effect.flatMap(() => runPrStep(modelSelection, input.cwd, currentBranch)),
Effect.flatMap(() =>
runPrStep(modelSelection, input.cwd, currentBranch, progress.emit),
),
)
: { status: "skipped_not_requested" as const };

Expand Down
29 changes: 27 additions & 2 deletions apps/web/src/components/GitActionsControl.logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,12 @@ describe("buildGitActionProgressStages", () => {
pushTarget: "origin/feature/test",
shouldPushBeforePr: true,
});
assert.deepEqual(stages, ["Pushing to origin/feature/test...", "Creating PR..."]);
assert.deepEqual(stages, [
"Pushing to origin/feature/test...",
"Preparing PR...",
"Generating PR content...",
"Creating GitHub pull request...",
]);
});

it("shows only PR progress when create-pr can skip the push", () => {
Expand All @@ -887,7 +892,11 @@ describe("buildGitActionProgressStages", () => {
hasWorkingTreeChanges: false,
shouldPushBeforePr: false,
});
assert.deepEqual(stages, ["Creating PR..."]);
assert.deepEqual(stages, [
"Preparing PR...",
"Generating PR content...",
"Creating GitHub pull request...",
]);
});

it("includes commit stages for commit+push when working tree is dirty", () => {
Expand All @@ -903,6 +912,22 @@ describe("buildGitActionProgressStages", () => {
"Pushing to origin/feature/test...",
]);
});

it("includes granular PR stages for commit+push+PR actions", () => {
const stages = buildGitActionProgressStages({
action: "commit_push_pr",
hasCustomCommitMessage: true,
hasWorkingTreeChanges: true,
pushTarget: "origin/feature/test",
});
assert.deepEqual(stages, [
"Committing...",
"Pushing to origin/feature/test...",
"Preparing PR...",
"Generating PR content...",
"Creating GitHub pull request...",
]);
});
});

describe("resolveThreadBranchUpdate", () => {
Expand Down
9 changes: 7 additions & 2 deletions apps/web/src/components/GitActionsControl.logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ export function buildGitActionProgressStages(input: {
}): string[] {
const branchStages = input.featureBranch ? ["Preparing feature branch..."] : [];
const pushStage = input.pushTarget ? `Pushing to ${input.pushTarget}...` : "Pushing...";
const prStages = [
"Preparing PR...",
"Generating PR content...",
"Creating GitHub pull request...",
];

if (input.action === "push") {
return [pushStage];
}
if (input.action === "create_pr") {
return input.shouldPushBeforePr ? [pushStage, "Creating PR..."] : ["Creating PR..."];
return input.shouldPushBeforePr ? [pushStage, ...prStages] : prStages;
}

const shouldIncludeCommitStages = input.action === "commit" || input.hasWorkingTreeChanges;
Expand All @@ -67,7 +72,7 @@ export function buildGitActionProgressStages(input: {
if (input.action === "commit_push") {
return [...branchStages, ...commitStages, pushStage];
}
return [...branchStages, ...commitStages, pushStage, "Creating PR..."];
return [...branchStages, ...commitStages, pushStage, ...prStages];
}

export function buildMenuItems(
Expand Down
Loading