Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions apps/desktop/src/clientPersistence.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function makeSecretStorage(available: boolean): DesktopSecretStorage {
}

const clientSettings: ClientSettings = {
autoCreatePrOnPush: true,
autoOpenPlanSidebar: false,
confirmThreadArchive: true,
confirmThreadDelete: false,
Expand Down
70 changes: 70 additions & 0 deletions apps/web/src/components/GitActionsControl.logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1131,3 +1131,73 @@ describe("resolveAutoFeatureBranchName", () => {
assert.equal(ref, "feature/update");
});
});

describe("when: autoCreatePr is disabled", () => {
it("downgrades feature-branch commit+push from PR to plain commit & push", () => {
const quick = resolveQuickAction(
status({ hasWorkingTreeChanges: true }),
false,
false,
true,
false,
);
assert.deepInclude(quick, {
kind: "run_action",
action: "commit_push",
label: "Commit & push",
disabled: false,
});
});

it("downgrades feature-branch ahead-with-upstream from create PR to plain push", () => {
const quick = resolveQuickAction(status({ aheadCount: 2 }), false, false, true, false);
assert.deepInclude(quick, {
kind: "run_action",
action: "push",
label: "Push",
disabled: false,
});
});

it("downgrades feature-branch ahead-without-upstream from create PR to plain push", () => {
const quick = resolveQuickAction(
status({ aheadCount: 1, hasUpstream: false }),
false,
false,
true,
false,
);
assert.deepInclude(quick, {
kind: "run_action",
action: "push",
label: "Push",
disabled: false,
});
});

it("preserves Commit, push & PR when autoCreatePr is true (default)", () => {
const quick = resolveQuickAction(
status({ hasWorkingTreeChanges: true }),
false,
false,
true,
true,
);
assert.deepInclude(quick, {
kind: "run_action",
action: "commit_push_pr",
label: "Commit, push & PR",
disabled: false,
});
});

it("preserves Push & create PR when autoCreatePr is true (default)", () => {
const quick = resolveQuickAction(status({ aheadCount: 2 }), false, false, true, true);
assert.deepInclude(quick, {
kind: "run_action",
action: "create_pr",
label: "Push & create PR",
disabled: false,
});
});
});
7 changes: 4 additions & 3 deletions apps/web/src/components/GitActionsControl.logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export function resolveQuickAction(
isBusy: boolean,
isDefaultRef = false,
hasPrimaryRemote = true,
autoCreatePr = true,
): GitQuickAction {
if (isBusy) {
return { label: "Commit", disabled: true, kind: "show_hint", hint: "Git action in progress." };
Expand Down Expand Up @@ -205,7 +206,7 @@ export function resolveQuickAction(
if (!gitStatus.hasUpstream && !hasPrimaryRemote) {
return { label: "Commit", disabled: false, kind: "run_action", action: "commit" };
}
if (hasOpenPr || isDefaultRef) {
if (hasOpenPr || isDefaultRef || !autoCreatePr) {
return { label: "Commit & push", disabled: false, kind: "run_action", action: "commit_push" };
}
return {
Expand Down Expand Up @@ -238,7 +239,7 @@ export function resolveQuickAction(
hint: "No local commits to push.",
};
}
if (hasOpenPr || isDefaultRef) {
if (hasOpenPr || isDefaultRef || !autoCreatePr) {
return {
label: "Push",
disabled: false,
Expand Down Expand Up @@ -272,7 +273,7 @@ export function resolveQuickAction(
}

if (isAhead) {
if (hasOpenPr || isDefaultRef) {
if (hasOpenPr || isDefaultRef || !autoCreatePr) {
return {
label: "Push",
disabled: false,
Expand Down
12 changes: 10 additions & 2 deletions apps/web/src/components/GitActionsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
resolveThreadBranchUpdate,
} from "./GitActionsControl.logic";
import { AnimatedHeight } from "./AnimatedHeight";
import { useSettings } from "../hooks/useSettings";
import { Button } from "~/components/ui/button";
import { Checkbox } from "~/components/ui/checkbox";
import {
Expand Down Expand Up @@ -1136,10 +1137,17 @@ export default function GitActionsControl({
() => buildMenuItems(gitStatusForActions, isGitActionRunning, hasPrimaryRemote),
[gitStatusForActions, hasPrimaryRemote, isGitActionRunning],
);
const autoCreatePrOnPush = useSettings((s) => s.autoCreatePrOnPush);
const quickAction = useMemo(
() =>
resolveQuickAction(gitStatusForActions, isGitActionRunning, isDefaultRef, hasPrimaryRemote),
[gitStatusForActions, hasPrimaryRemote, isDefaultRef, isGitActionRunning],
resolveQuickAction(
gitStatusForActions,
isGitActionRunning,
isDefaultRef,
hasPrimaryRemote,
autoCreatePrOnPush,
),
[autoCreatePrOnPush, gitStatusForActions, hasPrimaryRemote, isDefaultRef, isGitActionRunning],
);
const quickActionDisabledReason = quickAction.disabled
? (quickAction.hint ?? "This action is currently unavailable.")
Expand Down
26 changes: 26 additions & 0 deletions apps/web/src/components/settings/SettingsPanels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,32 @@ export function GeneralSettingsPanel() {
}
/>

<SettingsRow
title="Auto-create PR on push"
description="When pushing a feature branch with no open PR, also create a pull request automatically."
resetAction={
settings.autoCreatePrOnPush !== DEFAULT_UNIFIED_SETTINGS.autoCreatePrOnPush ? (
<SettingResetButton
label="auto-create PR on push"
onClick={() =>
updateSettings({
autoCreatePrOnPush: DEFAULT_UNIFIED_SETTINGS.autoCreatePrOnPush,
})
}
/>
) : null
}
control={
<Switch
checked={settings.autoCreatePrOnPush}
onCheckedChange={(checked) =>
updateSettings({ autoCreatePrOnPush: Boolean(checked) })
}
aria-label="Auto-create PR on push"
/>
}
/>

<SettingsRow
title="New threads"
description="Pick the default workspace mode for newly created draft threads."
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type SidebarProjectGroupingMode = typeof SidebarProjectGroupingMode.Type;
export const DEFAULT_SIDEBAR_PROJECT_GROUPING_MODE: SidebarProjectGroupingMode = "repository";

export const ClientSettingsSchema = Schema.Struct({
autoCreatePrOnPush: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))),
autoOpenPlanSidebar: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))),
confirmThreadArchive: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),
confirmThreadDelete: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))),
Expand Down
Loading