import fs from 'fs'; import path from 'path'; async function main() { const serverUrl = process.env.GITHUB_SERVER_URL || process.env.GITEA_SERVER_URL || 'https://git.zzzjy.cloud'; const token = process.env.GITHUB_TOKEN || process.env.GITEA_TOKEN; const repo = process.env.GITHUB_REPOSITORY || 'zzzjy/hatty'; const tag = process.env.GITHUB_REF_NAME || 'v1.0.0'; if (!token) { console.error('Error: GITHUB_TOKEN or GITEA_TOKEN is required.'); process.exit(1); } const [owner, repoName] = repo.split('/'); const apiBase = `${serverUrl.replace(/\/+$/, '')}/api/v1/repos/${owner}/${repoName}`; console.log(`Connecting to Gitea at ${serverUrl} for repository ${repo}...`); // 1. 检查或创建 Release let releaseId = null; const tagCheckRes = await fetch(`${apiBase}/releases/tags/${tag}`, { headers: { Authorization: `token ${token}`, Accept: 'application/json', }, }); if (tagCheckRes.ok) { const existing = await tagCheckRes.json(); releaseId = existing.id; console.log(`Found existing release for tag ${tag} (id: ${releaseId})`); } else { console.log(`Creating new release for tag ${tag}...`); const createRes = await fetch(`${apiBase}/releases`, { method: 'POST', headers: { Authorization: `token ${token}`, 'Content-Type': 'application/json', Accept: 'application/json', }, body: JSON.stringify({ tag_name: tag, name: `hatty ${tag}`, body: `### ⚡ hatty ${tag} 现代化 Linux 终端新版本发布\n\n- **架构**:Electron + xterm.js (WebGL 硬件加速) + Linux PTY\n- **特性**:无边框磨砂毛玻璃、5 套现代暗黑主题、多标签页、灵活多窗格分屏\n- **安装说明**:下载下方附件 \`.deb\` 文件,在终端运行 \`sudo dpkg -i hatty_*.deb\` 即可完成安装。`, draft: false, prerelease: false, }), }); if (!createRes.ok) { const errText = await createRes.text(); console.error(`Failed to create release: ${createRes.status} ${errText}`); process.exit(1); } const created = await createRes.json(); releaseId = created.id; console.log(`Release created successfully with id ${releaseId}`); } // 2. 查找 dist/ 下的 .deb 安装包 const distDir = path.resolve('dist'); if (!fs.existsSync(distDir)) { console.error('dist directory does not exist.'); process.exit(1); } const files = fs.readdirSync(distDir).filter((f) => f.endsWith('.deb') || f.endsWith('.AppImage')); if (files.length === 0) { console.error('No .deb or .AppImage files found in dist directory.'); process.exit(1); } // 3. 上传安装包到 Release 附件 for (const fileName of files) { const filePath = path.join(distDir, fileName); const fileStat = fs.statSync(filePath); console.log(`Uploading ${fileName} (${(fileStat.size / (1024 * 1024)).toFixed(2)} MB)...`); const fileBuffer = fs.readFileSync(filePath); const formData = new FormData(); const blob = new Blob([fileBuffer], { type: 'application/octet-stream' }); formData.append('attachment', blob, fileName); const uploadRes = await fetch(`${apiBase}/releases/${releaseId}/assets?name=${encodeURIComponent(fileName)}`, { method: 'POST', headers: { Authorization: `token ${token}`, }, body: formData, }); if (uploadRes.ok) { console.log(`✔ Successfully uploaded ${fileName}`); } else { const err = await uploadRes.text(); console.warn(`Warning: Upload ${fileName} returned status ${uploadRes.status}: ${err}`); } } console.log('All release operations completed successfully!'); } main().catch((err) => { console.error('Unexpected error:', err); process.exit(1); });