Auto-sync GitHub after connecting to project (#756)

This commit is contained in:
Will Chen
2025-07-31 15:35:18 -07:00
committed by GitHub
parent 03c200b932
commit 867ea28f73

View File

@@ -49,6 +49,8 @@ interface ConnectedGitHubConnectorProps {
appId: number; appId: number;
app: any; app: any;
refreshApp: () => void; refreshApp: () => void;
triggerAutoSync?: boolean;
onAutoSyncComplete?: () => void;
} }
interface UnconnectedGitHubConnectorProps { interface UnconnectedGitHubConnectorProps {
@@ -56,7 +58,7 @@ interface UnconnectedGitHubConnectorProps {
folderName: string; folderName: string;
settings: any; settings: any;
refreshSettings: () => void; refreshSettings: () => void;
refreshApp: () => void; handleRepoSetupComplete: () => void;
expanded?: boolean; expanded?: boolean;
} }
@@ -64,6 +66,8 @@ function ConnectedGitHubConnector({
appId, appId,
app, app,
refreshApp, refreshApp,
triggerAutoSync,
onAutoSyncComplete,
}: ConnectedGitHubConnectorProps) { }: ConnectedGitHubConnectorProps) {
const [isSyncing, setIsSyncing] = useState(false); const [isSyncing, setIsSyncing] = useState(false);
const [syncError, setSyncError] = useState<string | null>(null); const [syncError, setSyncError] = useState<string | null>(null);
@@ -71,6 +75,7 @@ function ConnectedGitHubConnector({
const [showForceDialog, setShowForceDialog] = useState(false); const [showForceDialog, setShowForceDialog] = useState(false);
const [isDisconnecting, setIsDisconnecting] = useState(false); const [isDisconnecting, setIsDisconnecting] = useState(false);
const [disconnectError, setDisconnectError] = useState<string | null>(null); const [disconnectError, setDisconnectError] = useState<string | null>(null);
const autoSyncTriggeredRef = useRef(false);
const handleDisconnectRepo = async () => { const handleDisconnectRepo = async () => {
setIsDisconnecting(true); setIsDisconnecting(true);
@@ -85,32 +90,51 @@ function ConnectedGitHubConnector({
} }
}; };
const handleSyncToGithub = async (force: boolean = false) => { const handleSyncToGithub = useCallback(
setIsSyncing(true); async (force: boolean = false) => {
setSyncError(null); setIsSyncing(true);
setSyncSuccess(false); setSyncError(null);
setShowForceDialog(false); setSyncSuccess(false);
setShowForceDialog(false);
try { try {
const result = await IpcClient.getInstance().syncGithubRepo(appId, force); const result = await IpcClient.getInstance().syncGithubRepo(
if (result.success) { appId,
setSyncSuccess(true); force,
} else { );
setSyncError(result.error || "Failed to sync to GitHub."); if (result.success) {
// If it's a push rejection error, show the force dialog setSyncSuccess(true);
if ( } else {
result.error?.includes("rejected") || setSyncError(result.error || "Failed to sync to GitHub.");
result.error?.includes("non-fast-forward") // If it's a push rejection error, show the force dialog
) { if (
// Don't show force dialog immediately, let user see the error first result.error?.includes("rejected") ||
result.error?.includes("non-fast-forward")
) {
// Don't show force dialog immediately, let user see the error first
}
} }
} catch (err: any) {
setSyncError(err.message || "Failed to sync to GitHub.");
} finally {
setIsSyncing(false);
} }
} catch (err: any) { },
setSyncError(err.message || "Failed to sync to GitHub."); [appId],
} finally { );
setIsSyncing(false);
// Auto-sync when triggerAutoSync prop is true
useEffect(() => {
if (triggerAutoSync && !autoSyncTriggeredRef.current) {
autoSyncTriggeredRef.current = true;
handleSyncToGithub(false).finally(() => {
onAutoSyncComplete?.();
});
} else if (!triggerAutoSync) {
// Reset the ref when triggerAutoSync becomes false
autoSyncTriggeredRef.current = false;
} }
}; }, [triggerAutoSync]); // Only depend on triggerAutoSync to avoid unnecessary re-runs
return ( return (
<div className="w-full" data-testid="github-connected-repo"> <div className="w-full" data-testid="github-connected-repo">
@@ -268,7 +292,7 @@ function UnconnectedGitHubConnector({
folderName, folderName,
settings, settings,
refreshSettings, refreshSettings,
refreshApp, handleRepoSetupComplete,
expanded, expanded,
}: UnconnectedGitHubConnectorProps) { }: UnconnectedGitHubConnectorProps) {
// --- Collapsible State --- // --- Collapsible State ---
@@ -516,9 +540,10 @@ function UnconnectedGitHubConnector({
appId, appId,
); );
} }
setCreateRepoSuccess(true); setCreateRepoSuccess(true);
setRepoCheckError(null); setRepoCheckError(null);
refreshApp(); handleRepoSetupComplete();
} catch (err: any) { } catch (err: any) {
setCreateRepoError( setCreateRepoError(
err.message || err.message ||
@@ -882,6 +907,16 @@ export function GitHubConnector({
}: GitHubConnectorProps) { }: GitHubConnectorProps) {
const { app, refreshApp } = useLoadApp(appId); const { app, refreshApp } = useLoadApp(appId);
const { settings, refreshSettings } = useSettings(); const { settings, refreshSettings } = useSettings();
const [pendingAutoSync, setPendingAutoSync] = useState(false);
const handleRepoSetupComplete = useCallback(() => {
setPendingAutoSync(true);
refreshApp();
}, [refreshApp]);
const handleAutoSyncComplete = useCallback(() => {
setPendingAutoSync(false);
}, []);
if (app?.githubOrg && app?.githubRepo && appId) { if (app?.githubOrg && app?.githubRepo && appId) {
return ( return (
@@ -889,6 +924,8 @@ export function GitHubConnector({
appId={appId} appId={appId}
app={app} app={app}
refreshApp={refreshApp} refreshApp={refreshApp}
triggerAutoSync={pendingAutoSync}
onAutoSyncComplete={handleAutoSyncComplete}
/> />
); );
} else { } else {
@@ -898,7 +935,7 @@ export function GitHubConnector({
folderName={folderName} folderName={folderName}
settings={settings} settings={settings}
refreshSettings={refreshSettings} refreshSettings={refreshSettings}
refreshApp={refreshApp} handleRepoSetupComplete={handleRepoSetupComplete}
expanded={expanded} expanded={expanded}
/> />
); );