This commit is contained in:
AmintaCCCP
2025-07-28 23:10:11 +08:00
parent e8c4b2ee66
commit 9acbdc93f1
3 changed files with 233 additions and 46 deletions

View File

@@ -33,8 +33,10 @@ jobs:
- name: Build web app
run: npm run build
env:
VITE_BASE_PATH: './'
- name: Verify web build
- name: Verify and fix web build
shell: bash
run: |
echo "Checking if dist directory exists and contains files:"
@@ -42,6 +44,19 @@ jobs:
echo "✓ dist directory and index.html found"
echo "Contents of dist directory:"
ls -la dist/ | head -10
# 检查 index.html 中的路径并修复
echo "Checking and fixing asset paths in index.html..."
if [ -f "dist/index.html" ]; then
# 确保所有资源路径都是相对路径
sed -i.bak 's|href="/|href="./|g' dist/index.html
sed -i.bak 's|src="/|src="./|g' dist/index.html
sed -i.bak 's|href="\([^"]*\)"|href="./\1"|g' dist/index.html
sed -i.bak 's|src="\([^"]*\)"|src="./\1"|g' dist/index.html
# 移除备份文件
rm -f dist/index.html.bak
echo "✓ Asset paths fixed in index.html"
fi
else
echo "Creating fallback dist directory and index.html"
mkdir -p dist
@@ -49,6 +64,10 @@ jobs:
echo "✓ Fallback index.html created from template"
fi
# 显示最终的 index.html 内容(前几行)
echo "Final index.html content (first 10 lines):"
head -10 dist/index.html || echo "Could not read index.html"
- name: Install sharp for icon generation
run: npm install sharp --save-dev
@@ -63,7 +82,7 @@ jobs:
console.log('Build directory created');
"
- name: Generate icons
- name: Generate icons and app resources
shell: bash
run: |
node -e "
@@ -97,10 +116,21 @@ jobs:
fs.copyFileSync(sourceIcon, 'build/icon.png');
fs.copyFileSync(sourceIcon, 'build/icon-512x512.png');
} else {
console.log('No source icon found, will use electron-builder default');
// Create a simple placeholder
const placeholderSvg = '<svg width=\"512\" height=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"512\" height=\"512\" fill=\"#3b82f6\"/><text x=\"256\" y=\"256\" text-anchor=\"middle\" dy=\".3em\" fill=\"white\" font-size=\"48\" font-family=\"Arial\">APP</text></svg>';
fs.writeFileSync('build/icon.svg', placeholderSvg);
console.log('Creating default application icon');
// Create a better default icon
const iconSvg = \`<svg width=\"512\" height=\"512\" xmlns=\"http://www.w3.org/2000/svg\">
<defs>
<linearGradient id=\"grad1\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">
<stop offset=\"0%\" style=\"stop-color:#667eea;stop-opacity:1\" />
<stop offset=\"100%\" style=\"stop-color:#764ba2;stop-opacity:1\" />
</linearGradient>
</defs>
<rect width=\"512\" height=\"512\" fill=\"url(#grad1)\" rx=\"64\"/>
<text x=\"256\" y=\"280\" text-anchor=\"middle\" fill=\"white\" font-size=\"120\" font-family=\"Arial, sans-serif\" font-weight=\"bold\">⭐</text>
<text x=\"256\" y=\"380\" text-anchor=\"middle\" fill=\"white\" font-size=\"32\" font-family=\"Arial, sans-serif\">GitHub</text>
<text x=\"256\" y=\"420\" text-anchor=\"middle\" fill=\"white\" font-size=\"32\" font-family=\"Arial, sans-serif\">Stars</text>
</svg>\`;
fs.writeFileSync('build/icon.svg', iconSvg);
}
console.log('Icon files prepared successfully');
@@ -166,48 +196,79 @@ jobs:
' nodeIntegration: false,\\n' +
' contextIsolation: true,\\n' +
' enableRemoteModule: false,\\n' +
' webSecurity: false\\n' +
' webSecurity: false,\\n' +
' allowRunningInsecureContent: true,\\n' +
' devTools: isDev // 只在开发模式下启用 DevTools\\n' +
' },\\n' +
' icon: path.join(__dirname, \\'../build/icon.png\\'),\\n' +
' titleBarStyle: process.platform === \\'darwin\\' ? \\'hiddenInset\\' : \\'default\\',\\n' +
' show: false\\n' +
' show: false,\\n' +
' autoHideMenuBar: true, // 隐藏菜单栏\\n' +
' frame: true, // 保持窗口框架\\n' +
' backgroundColor: \\'#ffffff\\' // 设置背景色,避免白屏闪烁\\n' +
' });\\n\\n' +
' // Add error handling\\n' +
' mainWindow.webContents.on(\\'did-fail-load\\', (event, errorCode, errorDescription) => {\\n' +
' console.error(\\'Failed to load:\\', errorCode, errorDescription);\\n' +
' // 添加错误处理和加载事件\\n' +
' mainWindow.webContents.on(\\'did-fail-load\\', (event, errorCode, errorDescription, validatedURL) => {\\n' +
' console.error(\\'Failed to load:\\', errorCode, errorDescription, validatedURL);\\n' +
' // 如果主页面加载失败,尝试加载 fallback 页面\\n' +
' const fallbackPath = path.join(__dirname, \\'../dist/index.html\\');\\n' +
' if (fs.existsSync(fallbackPath)) {\\n' +
' console.log(\\'Loading fallback page:\\', fallbackPath);\\n' +
' mainWindow.loadFile(fallbackPath);\\n' +
' }\\n' +
' });\\n\\n' +
' mainWindow.webContents.on(\\'dom-ready\\', () => {\\n' +
' console.log(\\'DOM ready\\');\\n' +
' if (isDev) console.log(\\'DOM ready\\');\\n' +
' // 注入一些基础样式,防止白屏\\n' +
' mainWindow.webContents.insertCSS(\\'body { background-color: #ffffff; }\\');\\n' +
' });\\n\\n' +
' mainWindow.webContents.on(\\'did-finish-load\\', () => {\\n' +
' if (isDev) console.log(\\'Page finished loading\\');\\n' +
' // 页面加载完成后显示窗口\\n' +
' if (!mainWindow.isVisible()) {\\n' +
' mainWindow.show();\\n' +
' }\\n' +
' });\\n\\n' +
' if (isDev) {\\n' +
' mainWindow.loadURL(\\'http://localhost:5173\\');\\n' +
' mainWindow.webContents.openDevTools();\\n' +
' } else {\\n' +
' // Try multiple possible paths for the built app\\n' +
' // 生产环境:尝试多个可能的路径\\n' +
' const possiblePaths = [\\n' +
' path.join(__dirname, \\'../dist/index.html\\'),\\n' +
' path.join(__dirname, \\'../build/index.html\\'),\\n' +
' path.join(process.resourcesPath, \\'app.asar/dist/index.html\\'),\\n' +
' path.join(process.resourcesPath, \\'app/dist/index.html\\'),\\n' +
' path.join(process.resourcesPath, \\'dist/index.html\\')\\n' +
' path.join(process.resourcesPath, \\'dist/index.html\\'),\\n' +
' path.join(__dirname, \\'../build/index.html\\')\\n' +
' ];\\n\\n' +
' let indexPath = null;\\n' +
' for (const testPath of possiblePaths) {\\n' +
' if (fs.existsSync(testPath)) {\\n' +
' indexPath = testPath;\\n' +
' break;\\n' +
' try {\\n' +
' if (fs.existsSync(testPath)) {\\n' +
' indexPath = testPath;\\n' +
' break;\\n' +
' }\\n' +
' } catch (error) {\\n' +
' // 忽略文件系统错误,继续尝试下一个路径\\n' +
' continue;\\n' +
' }\\n' +
' }\\n\\n' +
' if (indexPath) {\\n' +
' console.log(\\'Loading from:\\', indexPath);\\n' +
' mainWindow.loadFile(indexPath);\\n' +
' console.log(\\'Loading application from:\\', indexPath);\\n' +
' mainWindow.loadFile(indexPath).catch(error => {\\n' +
' console.error(\\'Failed to load file:\\', error);\\n' +
' // 加载失败时显示错误页面\\n' +
' mainWindow.loadURL(\\'data:text/html,<h1>Application Load Error</h1><p>Could not load the main application. Please restart the app.</p>\\');\\n' +
' });\\n' +
' } else {\\n' +
' console.error(\\'Could not find index.html in any expected location\\');\\n' +
' console.log(\\'Checked paths:\\', possiblePaths);\\n' +
' // Load a simple error page\\n' +
' mainWindow.loadURL(\\'data:text/html,<h1>Error: Could not load application</h1><p>Please check the console for details.</p>\\');\\n' +
' console.log(\\'Current directory:\\', __dirname);\\n' +
' console.log(\\'Process resources path:\\', process.resourcesPath);\\n' +
' // 显示详细的错误信息\\n' +
' const errorHtml = \\'<h1>Application Not Found</h1><p>Could not locate the application files.</p><p>Please reinstall the application.</p>\\';\\n' +
' mainWindow.loadURL(\\'data:text/html,\\' + encodeURIComponent(errorHtml));\\n' +
' }\\n' +
' // Open DevTools in production for debugging\\n' +
' mainWindow.webContents.openDevTools();\\n' +
' }\\n\\n' +
' mainWindow.once(\\'ready-to-show\\', () => {\\n' +
' mainWindow.show();\\n' +
@@ -258,6 +319,10 @@ jobs:
packageJson.homepage = './';
packageJson.scripts = packageJson.scripts || {};
// 确保构建脚本使用正确的基础路径
packageJson.scripts.build = 'vite build --base=./';
packageJson.scripts['build:electron'] = 'vite build --base=./ && electron-builder';
// Ensure proper base path for Electron
if (!packageJson.build) packageJson.build = {};
packageJson.build.extraMetadata = {
@@ -279,7 +344,9 @@ jobs:
'build/**/*',
'electron/**/*',
'node_modules/**/*',
'package.json'
'package.json',
'!node_modules/.cache/**/*',
'!**/*.map'
],
extraResources: [
{
@@ -287,6 +354,11 @@ jobs:
to: 'dist',
filter: ['**/*']
}
],
compression: 'normal',
asar: true,
asarUnpack: [
'dist/**/*'
]
};
@@ -303,24 +375,54 @@ jobs:
if ('${{ matrix.os }}' === 'windows-latest') {
packageJson.build.win = {
target: 'nsis',
icon: 'build/icon.png'
target: [
{
target: 'nsis',
arch: ['x64']
}
],
icon: 'build/icon.png',
requestedExecutionLevel: 'asInvoker'
};
packageJson.build.nsis = {
oneClick: false,
allowToChangeInstallationDirectory: true
allowToChangeInstallationDirectory: true,
createDesktopShortcut: true,
createStartMenuShortcut: true,
shortcutName: 'GitHub Stars Manager'
};
} else if ('${{ matrix.os }}' === 'macos-latest') {
packageJson.build.mac = {
target: 'dmg',
target: [
{
target: 'dmg',
arch: ['x64', 'arm64']
}
],
icon: 'build/icon.png',
category: 'public.app-category.productivity'
category: 'public.app-category.productivity',
hardenedRuntime: true,
gatekeeperAssess: false
};
packageJson.build.dmg = {
title: 'GitHub Stars Manager',
icon: 'build/icon.png'
};
} else {
packageJson.build.linux = {
target: 'AppImage',
target: [
{
target: 'AppImage',
arch: ['x64']
}
],
icon: 'build/icon-512x512.png',
category: 'Office'
category: 'Office',
desktop: {
Name: 'GitHub Stars Manager',
Comment: 'Manage your GitHub starred repositories',
Categories: 'Office;Development;'
}
};
}
@@ -331,15 +433,29 @@ jobs:
- name: Debug before build
shell: bash
run: |
echo "=== Debug Information ==="
echo "=== Pre-Build Debug Information ==="
echo "Current directory contents:"
ls -la
echo ""
echo "Dist directory contents:"
ls -la dist/ || echo "No dist directory"
echo ""
echo "Electron directory contents:"
ls -la electron/ || echo "No electron directory"
echo ""
echo "Build directory contents:"
ls -la build/ || echo "No build directory"
echo ""
echo "Package.json build config:"
node -e "console.log(JSON.stringify(require('./package.json').build, null, 2))"
echo ""
echo "Checking dist/index.html content:"
if [ -f "dist/index.html" ]; then
echo "First 20 lines of dist/index.html:"
head -20 dist/index.html
else
echo "dist/index.html not found"
fi
- name: Build Electron app
run: npm run dist

View File

@@ -4,38 +4,95 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Stars Manager</title>
<base href="./">
<style>
body {
font-family: Arial, sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
max-width: 800px;
margin: 0 auto;
max-width: 600px;
background: white;
padding: 40px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
text-align: center;
}
h1 {
color: #333;
margin-bottom: 20px;
font-size: 2.5em;
font-weight: 300;
}
.logo {
font-size: 4em;
margin-bottom: 20px;
}
p {
color: #666;
line-height: 1.6;
margin-bottom: 15px;
}
.status {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin-top: 30px;
border-left: 4px solid #007bff;
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-top: 3px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-right: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
h1 { color: #333; }
.status { color: #666; margin-top: 20px; }
</style>
</head>
<body>
<div class="container">
<div class="logo"></div>
<h1>GitHub Stars Manager</h1>
<p>Welcome to GitHub Stars Manager Desktop Application!</p>
<div class="status">
<p>This is a fallback page. The main application should load here.</p>
<p>Application built successfully with GitHub Actions.</p>
<div class="loading"></div>
<p><strong>Application Status:</strong> Ready</p>
<p>This is a fallback page displayed when the main application bundle is not available.</p>
<p>The desktop application has been built successfully with GitHub Actions.</p>
</div>
</div>
<script>
console.log('GitHub Stars Manager loaded successfully');
console.log('GitHub Stars Manager fallback page loaded successfully');
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM ready');
console.log('DOM ready - Fallback page');
// 尝试检测是否在 Electron 环境中
if (window.process && window.process.type === 'renderer') {
console.log('Running in Electron renderer process');
}
// 添加一些基本的错误处理
window.addEventListener('error', function(e) {
console.error('Page error:', e.error);
});
// 检查资源加载
setTimeout(function() {
console.log('Fallback page fully loaded');
}, 1000);
});
</script>
</body>

View File

@@ -4,7 +4,21 @@ import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: './', // 使用相对路径,解决 Electron 白屏问题
optimizeDeps: {
exclude: ['lucide-react'],
},
build: {
outDir: 'dist',
assetsDir: 'assets',
// 确保资源文件使用相对路径
rollupOptions: {
output: {
// 简化文件名,避免复杂的哈希
entryFileNames: 'assets/[name].js',
chunkFileNames: 'assets/[name].js',
assetFileNames: 'assets/[name].[ext]'
}
}
}
});