feat(checkout): merge PR action with real-GitHub e2e test (#814)
* feat(checkout): merge PR action with real-GitHub e2e test Adds a `checkoutPrMerge` server RPC backed by `gh pr merge` (squash, merge, or rebase) and surfaces three new actions in the git-actions menu — "Squash and merge", "Create a merge commit", "Rebase and merge" — with squash taking the primary slot when a PR is open and mergeable. Also renames the existing local merge action to "Merge locally" to disambiguate it from the new GitHub-side merge. Adds an end-to-end test that creates a real temporary GitHub repo, opens a PR via the daemon, polls until mergeable, calls `checkoutPrMerge`, and verifies the merge landed on `main` — no mocks. The test pre-flights the `delete_repo` scope so it skips cleanly on tokens that can't tear down, and fails loud if cleanup ever errors so we don't leak repos. PR status gains an optional `mergeable` field (`MERGEABLE | CONFLICTING | UNKNOWN`) populated from `gh pr view --json mergeable`. The schema is backward compatible — old payloads without the field still parse and default to `UNKNOWN` via `z.catch`. * Update PR status snapshot expectations * refactor: collect git/checkout/PR feature into packages/app/src/git/ Move 21 git/checkout/PR files out of components/, hooks/, stores/, screens/, utils/ flat-peer slop into a single packages/app/src/git/ module with shrunk filenames (git-diff-pane.tsx -> diff-pane.tsx, use-git-actions.ts -> use-actions.ts, etc). Dedupe: drop the duplicate useGitActionHandlers from diff-pane.tsx — the shared useGitActions hook is the single source. Drop the buildGitActionsForPane wrapper. Collapse the merge-PR triple fan-out (mergePrSquash/Merge/RebaseStatus) into one record keyed by CheckoutPrMergeMethod. Streamline server-side single-use helpers (dispatchStash/PullRequestMessage adapters, GitHubPullRequestMergeError wrapper, legacy worktree test helpers). Schema-additive only: messages.ts exports CheckoutPrMergeMethod and PullRequestMergeable types; daemon-client.ts uses the typed alias. Backward-compatible. Net delta: 43 files, +219/-1212. * fix(app): use GitHub icon for all merge-PR menu actions * test: namespace temp GitHub repos under `paseotmp-` and centralize naming Old prefixes (`paseo-checkout-ship-`, `paseo-e2e-`, `paseo-checkout-pr-merge-`) collided with the `paseo-*` namespace of real repos, making bulk cleanup unsafe. Switch every test that creates real GitHub repos to a single unmistakable `paseotmp-` prefix, owned by one shared helper per test boundary so no caller can name a repo outside the namespace. - New `packages/server/src/server/test-utils/temp-github-repo.ts` exports `TEMP_GITHUB_REPO_PREFIX` + `createTempGithubRepoName(category)`; both server e2e tests (checkout-ship, checkout-pr-merge) consume it. - `packages/app/e2e/helpers/github-fixtures.ts` locks the prefix internally and now requires callers to pass a `category` instead of an arbitrary `prefix`. Updated pr-pane and composer-attachments specs accordingly.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { withUnistyles } from "react-native-unistyles";
|
||||
import {
|
||||
Archive,
|
||||
ArrowDownUp,
|
||||
Download,
|
||||
GitCommitHorizontal,
|
||||
GitMerge,
|
||||
RefreshCcw,
|
||||
Upload,
|
||||
} from "lucide-react-native";
|
||||
import { GitHubIcon } from "@/components/icons/github-icon";
|
||||
import { GitActionsSplitButton } from "@/git/actions-split-button";
|
||||
import { useGitActions } from "@/git/use-actions";
|
||||
import type { Theme } from "@/styles/theme";
|
||||
|
||||
interface WorkspaceGitActionsProps {
|
||||
serverId: string;
|
||||
cwd: string;
|
||||
hideLabels?: boolean;
|
||||
}
|
||||
|
||||
const ThemedGitCommitHorizontal = withUnistyles(GitCommitHorizontal);
|
||||
const ThemedDownload = withUnistyles(Download);
|
||||
const ThemedUpload = withUnistyles(Upload);
|
||||
const ThemedArrowDownUp = withUnistyles(ArrowDownUp);
|
||||
const ThemedGitHubIcon = withUnistyles(GitHubIcon);
|
||||
const ThemedGitMerge = withUnistyles(GitMerge);
|
||||
const ThemedRefreshCcw = withUnistyles(RefreshCcw);
|
||||
const ThemedArchive = withUnistyles(Archive);
|
||||
|
||||
const mutedColorMapping = (theme: Theme) => ({
|
||||
color: theme.colors.foregroundMuted,
|
||||
});
|
||||
|
||||
const ICONS = {
|
||||
commit: <ThemedGitCommitHorizontal size={16} uniProps={mutedColorMapping} />,
|
||||
pull: <ThemedDownload size={16} uniProps={mutedColorMapping} />,
|
||||
push: <ThemedUpload size={16} uniProps={mutedColorMapping} />,
|
||||
pullAndPush: <ThemedArrowDownUp size={16} uniProps={mutedColorMapping} />,
|
||||
viewPr: <ThemedGitHubIcon size={16} uniProps={mutedColorMapping} />,
|
||||
createPr: <ThemedGitHubIcon size={16} uniProps={mutedColorMapping} />,
|
||||
mergePrSquash: <ThemedGitHubIcon size={16} uniProps={mutedColorMapping} />,
|
||||
mergePrMerge: <ThemedGitHubIcon size={16} uniProps={mutedColorMapping} />,
|
||||
mergePrRebase: <ThemedGitHubIcon size={16} uniProps={mutedColorMapping} />,
|
||||
merge: <ThemedGitMerge size={16} uniProps={mutedColorMapping} />,
|
||||
mergeFromBase: <ThemedRefreshCcw size={16} uniProps={mutedColorMapping} />,
|
||||
archive: <ThemedArchive size={16} uniProps={mutedColorMapping} />,
|
||||
};
|
||||
|
||||
export function WorkspaceGitActions({ serverId, cwd, hideLabels }: WorkspaceGitActionsProps) {
|
||||
const { gitActions, isGit } = useGitActions({ serverId, cwd, icons: ICONS });
|
||||
|
||||
if (!isGit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <GitActionsSplitButton gitActions={gitActions} hideLabels={hideLabels} />;
|
||||
}
|
||||
Reference in New Issue
Block a user