Update fix

more enhanced  UI and more details what is fixed,  ect
This commit is contained in:
Stijnus
2025-02-03 01:40:54 +01:00
parent f091409f7e
commit b5096735ef
2 changed files with 383 additions and 51 deletions

View File

@@ -24,6 +24,8 @@ interface UpdateProgress {
currentCommit?: string;
remoteCommit?: string;
updateReady?: boolean;
changelog?: string;
compareUrl?: string;
};
}
@@ -231,9 +233,103 @@ export const action: ActionFunction = async ({ request }) => {
// Get commit messages between current and remote
try {
const { stdout: logOutput } = await execAsync(
`git log --oneline ${currentCommit.trim()}..${remoteCommit.trim()}`,
`git log --pretty=format:"%h|%s|%aI" ${currentCommit.trim()}..${remoteCommit.trim()}`,
);
commitMessages = logOutput.split('\n').filter(Boolean);
// Parse and group commits by type
const commits = logOutput
.split('\n')
.filter(Boolean)
.map((line) => {
const [hash, subject, timestamp] = line.split('|');
let type = 'other';
let message = subject;
if (subject.startsWith('feat:') || subject.startsWith('feature:')) {
type = 'feature';
message = subject.replace(/^feat(?:ure)?:/, '').trim();
} else if (subject.startsWith('fix:')) {
type = 'fix';
message = subject.replace(/^fix:/, '').trim();
} else if (subject.startsWith('docs:')) {
type = 'docs';
message = subject.replace(/^docs:/, '').trim();
} else if (subject.startsWith('style:')) {
type = 'style';
message = subject.replace(/^style:/, '').trim();
} else if (subject.startsWith('refactor:')) {
type = 'refactor';
message = subject.replace(/^refactor:/, '').trim();
} else if (subject.startsWith('perf:')) {
type = 'perf';
message = subject.replace(/^perf:/, '').trim();
} else if (subject.startsWith('test:')) {
type = 'test';
message = subject.replace(/^test:/, '').trim();
} else if (subject.startsWith('build:')) {
type = 'build';
message = subject.replace(/^build:/, '').trim();
} else if (subject.startsWith('ci:')) {
type = 'ci';
message = subject.replace(/^ci:/, '').trim();
}
return {
hash,
type,
message,
timestamp: new Date(timestamp),
};
});
// Group commits by type
const groupedCommits = commits.reduce(
(acc, commit) => {
if (!acc[commit.type]) {
acc[commit.type] = [];
}
acc[commit.type].push(commit);
return acc;
},
{} as Record<string, typeof commits>,
);
// Format commit messages with emojis and timestamps
const formattedMessages = Object.entries(groupedCommits).map(([type, commits]) => {
const emoji = {
feature: '✨',
fix: '🐛',
docs: '📚',
style: '💎',
refactor: '♻️',
perf: '⚡',
test: '🧪',
build: '🛠️',
ci: '⚙️',
other: '🔍',
}[type];
const title = {
feature: 'Features',
fix: 'Bug Fixes',
docs: 'Documentation',
style: 'Styles',
refactor: 'Code Refactoring',
perf: 'Performance',
test: 'Tests',
build: 'Build',
ci: 'CI',
other: 'Other Changes',
}[type];
return `### ${emoji} ${title}\n\n${commits
.map((c) => `* ${c.message} (${c.hash.substring(0, 7)}) - ${c.timestamp.toLocaleString()}`)
.join('\n')}`;
});
commitMessages = formattedMessages;
} catch {
// Handle silently - empty commitMessages array will be used
}
@@ -260,6 +356,15 @@ export const action: ActionFunction = async ({ request }) => {
return;
}
// Fetch changelog
sendProgress({
stage: 'fetch',
message: 'Fetching changelog...',
progress: 95,
});
const changelog = await fetchChangelog(currentCommit.trim(), remoteCommit.trim());
// We have changes, send the details
sendProgress({
stage: 'fetch',
@@ -274,6 +379,8 @@ export const action: ActionFunction = async ({ request }) => {
currentCommit: currentCommit.trim().substring(0, 7),
remoteCommit: remoteCommit.trim().substring(0, 7),
updateReady: true,
changelog,
compareUrl: `https://github.com/stackblitz-labs/bolt.diy/compare/${currentCommit.trim().substring(0, 7)}...${remoteCommit.trim().substring(0, 7)}`,
},
});
@@ -292,6 +399,8 @@ export const action: ActionFunction = async ({ request }) => {
currentCommit: currentCommit.trim().substring(0, 7),
remoteCommit: remoteCommit.trim().substring(0, 7),
updateReady: true,
changelog,
compareUrl: `https://github.com/stackblitz-labs/bolt.diy/compare/${currentCommit.trim().substring(0, 7)}...${remoteCommit.trim().substring(0, 7)}`,
},
});
return;
@@ -378,3 +487,87 @@ export const action: ActionFunction = async ({ request }) => {
);
}
};
// Add this function to fetch the changelog
async function fetchChangelog(currentCommit: string, remoteCommit: string): Promise<string> {
try {
// First try to get the changelog.md content
const { stdout: changelogContent } = await execAsync('git show upstream/main:changelog.md');
// If we have a changelog, return it
if (changelogContent) {
return changelogContent;
}
// If no changelog.md, generate one in a similar format
let changelog = '# Changes in this Update\n\n';
// Get commit messages grouped by type
const { stdout: commitLog } = await execAsync(
`git log --pretty=format:"%h|%s|%b" ${currentCommit.trim()}..${remoteCommit.trim()}`,
);
const commits = commitLog.split('\n').filter(Boolean);
const categorizedCommits: Record<string, string[]> = {
'✨ Features': [],
'🐛 Bug Fixes': [],
'📚 Documentation': [],
'💎 Styles': [],
'♻️ Code Refactoring': [],
'⚡ Performance': [],
'🧪 Tests': [],
'🛠️ Build': [],
'⚙️ CI': [],
'🔍 Other Changes': [],
};
// Categorize commits
for (const commit of commits) {
const [hash, subject] = commit.split('|');
let category = '🔍 Other Changes';
if (subject.startsWith('feat:') || subject.startsWith('feature:')) {
category = '✨ Features';
} else if (subject.startsWith('fix:')) {
category = '🐛 Bug Fixes';
} else if (subject.startsWith('docs:')) {
category = '📚 Documentation';
} else if (subject.startsWith('style:')) {
category = '💎 Styles';
} else if (subject.startsWith('refactor:')) {
category = '♻️ Code Refactoring';
} else if (subject.startsWith('perf:')) {
category = '⚡ Performance';
} else if (subject.startsWith('test:')) {
category = '🧪 Tests';
} else if (subject.startsWith('build:')) {
category = '🛠️ Build';
} else if (subject.startsWith('ci:')) {
category = '⚙️ CI';
}
const message = subject.includes(':') ? subject.split(':')[1].trim() : subject.trim();
categorizedCommits[category].push(`* ${message} (${hash.substring(0, 7)})`);
}
// Build changelog content
for (const [category, commits] of Object.entries(categorizedCommits)) {
if (commits.length > 0) {
changelog += `\n## ${category}\n\n${commits.join('\n')}\n`;
}
}
// Add stats
const { stdout: stats } = await execAsync(`git diff --shortstat ${currentCommit.trim()}..${remoteCommit.trim()}`);
if (stats) {
changelog += '\n## 📊 Stats\n\n';
changelog += `${stats.trim()}\n`;
}
return changelog;
} catch (error) {
console.error('Error fetching changelog:', error);
return 'Unable to fetch changelog';
}
}