Update api.update.ts

This commit is contained in:
Stijnus 2025-02-02 16:25:22 +01:00
parent 9171cf48aa
commit 3dd3fafb77

View File

@ -45,6 +45,27 @@ export const action: ActionFunction = async ({ request }) => {
}; };
try { try {
// Check if remote exists
let defaultBranch = branch || 'main'; // Make branch mutable
try {
await execAsync('git remote get-url origin');
} catch {
throw new Error(
'No remote repository found. Please set up the remote repository first by running:\ngit remote add origin https://github.com/stackblitz-labs/bolt.diy.git',
);
}
// Get default branch if not specified
if (!branch) {
try {
const { stdout } = await execAsync('git remote show origin | grep "HEAD branch" | cut -d" " -f5');
defaultBranch = stdout.trim() || 'main';
} catch {
defaultBranch = 'main'; // Fallback to main if we can't detect
}
}
// Fetch stage // Fetch stage
sendProgress({ sendProgress({
stage: 'fetch', stage: 'fetch',
@ -52,31 +73,67 @@ export const action: ActionFunction = async ({ request }) => {
progress: 0, progress: 0,
}); });
// Fetch all remotes
await execAsync('git fetch --all');
// Check if remote branch exists
try {
await execAsync(`git rev-parse --verify origin/${defaultBranch}`);
} catch {
throw new Error(`Remote branch 'origin/${defaultBranch}' not found. Please push your changes first.`);
}
// Get current commit hash // Get current commit hash
const { stdout: currentCommit } = await execAsync('git rev-parse HEAD'); const { stdout: currentCommit } = await execAsync('git rev-parse HEAD');
// Fetch changes // Initialize variables
await execAsync('git fetch origin'); let changedFiles: string[] = [];
let commitMessages: string[] = [];
let stats: RegExpMatchArray | null = null;
// Get list of changed files // Get list of changed files
const { stdout: diffOutput } = await execAsync(`git diff --name-status origin/${branch}`); try {
const changedFiles = diffOutput const { stdout: diffOutput } = await execAsync(`git diff --name-status origin/${defaultBranch}`);
.split('\n') changedFiles = diffOutput
.filter(Boolean) .split('\n')
.map((line) => { .filter(Boolean)
const [status, file] = line.split('\t'); .map((line) => {
return `${status === 'M' ? 'Modified' : status === 'A' ? 'Added' : 'Deleted'}: ${file}`; const [status, file] = line.split('\t');
}); return `${status === 'M' ? 'Modified' : status === 'A' ? 'Added' : 'Deleted'}: ${file}`;
});
} catch {
// Handle silently - empty changedFiles array will be used
}
// Get commit messages // Get commit messages
const { stdout: logOutput } = await execAsync(`git log --oneline ${currentCommit.trim()}..origin/${branch}`); try {
const commitMessages = logOutput.split('\n').filter(Boolean); const { stdout: logOutput } = await execAsync(
`git log --oneline ${currentCommit.trim()}..origin/${defaultBranch}`,
);
commitMessages = logOutput.split('\n').filter(Boolean);
} catch {
// Handle silently - empty commitMessages array will be used
}
// Get diff stats // Get diff stats
const { stdout: diffStats } = await execAsync(`git diff --shortstat origin/${branch}`); try {
const stats = diffStats.match( const { stdout: diffStats } = await execAsync(`git diff --shortstat origin/${defaultBranch}`);
/(\d+) files? changed(?:, (\d+) insertions?\\(\\+\\))?(?:, (\d+) deletions?\\(-\\))?/, stats = diffStats.match(
); /(\d+) files? changed(?:, (\d+) insertions?\\(\\+\\))?(?:, (\d+) deletions?\\(-\\))?/,
);
} catch {
// Handle silently - null stats will be used
}
// If no changes detected
if (!stats && changedFiles.length === 0) {
sendProgress({
stage: 'complete',
message: 'No updates available. You are on the latest version.',
progress: 100,
});
return;
}
sendProgress({ sendProgress({
stage: 'fetch', stage: 'fetch',
@ -93,11 +150,11 @@ export const action: ActionFunction = async ({ request }) => {
// Pull stage // Pull stage
sendProgress({ sendProgress({
stage: 'pull', stage: 'pull',
message: `Pulling changes from ${branch}...`, message: `Pulling changes from ${defaultBranch}...`,
progress: 0, progress: 0,
}); });
await execAsync(`git pull origin ${branch}`); await execAsync(`git pull origin ${defaultBranch}`);
sendProgress({ sendProgress({
stage: 'pull', stage: 'pull',
@ -141,11 +198,11 @@ export const action: ActionFunction = async ({ request }) => {
message: 'Update completed successfully! Click Restart to apply changes.', message: 'Update completed successfully! Click Restart to apply changes.',
progress: 100, progress: 100,
}); });
} catch (error) { } catch (err) {
sendProgress({ sendProgress({
stage: 'complete', stage: 'complete',
message: 'Update failed', message: 'Update failed',
error: error instanceof Error ? error.message : 'Unknown error occurred', error: err instanceof Error ? err.message : 'Unknown error occurred',
}); });
} finally { } finally {
controller.close(); controller.close();
@ -160,12 +217,12 @@ export const action: ActionFunction = async ({ request }) => {
Connection: 'keep-alive', Connection: 'keep-alive',
}, },
}); });
} catch (error) { } catch (err) {
console.error('Update preparation failed:', error); console.error('Update preparation failed:', err);
return json( return json(
{ {
success: false, success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred while preparing update', error: err instanceof Error ? err.message : 'Unknown error occurred while preparing update',
}, },
{ status: 500 }, { status: 500 },
); );