feat: add deb packaging and Gitea Actions automated release workflow
Build and Release / Build & Release DEB Package (push) Failing after 1m16s

This commit is contained in:
2026-09-23 01:42:52 +08:00
parent bde1a6b250
commit 30b7993d24
13 changed files with 3349 additions and 11 deletions
+108
View File
@@ -0,0 +1,108 @@
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);
});