From 1407f754b176f521494f66f99871f524800c4880 Mon Sep 17 00:00:00 2001 From: Cita Date: Thu, 2 Apr 2026 12:53:28 +0800 Subject: [PATCH] [codex] add Fedora desktop rpm packaging (#390) * add Fedora desktop rpm packaging * harden desktop packaging yaml assertion --- .github/workflows/release.yml | 45 ++++++++++++++---------- docs/deployment.md | 6 ++++ docs/getting-started.md | 7 ++++ electron-builder.yml | 1 + scripts/desktop/release.workflow.test.ts | 33 ++++++++++++----- src/desktop/iconAssets.test.ts | 10 ++++++ 6 files changed, 74 insertions(+), 28 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b95c7b..e7d63bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,14 +121,20 @@ jobs: restore-keys: | electron-cache-${{ runner.os }}- - - name: Install dependencies - run: npm ci - - - name: Download built dist - uses: actions/download-artifact@v8 - with: - name: metapi-dist-${{ github.sha }} - path: dist + - name: Install dependencies + run: npm ci + + - name: Install Linux packaging dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends -y rpm + + - name: Download built dist + uses: actions/download-artifact@v8 + with: + name: metapi-dist-${{ github.sha }} + path: dist - name: Build desktop artifacts (Windows) if: runner.os == 'Windows' @@ -240,17 +246,18 @@ jobs: uses: actions/upload-artifact@v7 with: name: metapi-desktop-${{ github.run_id }}-${{ matrix.artifactLabel }} - path: | - release/*.exe - release/*.dmg - release/*.zip - release/*.AppImage - release/*.deb - release/*.blockmap - release/latest*.yml - release/latest*.json - release/builder-debug.yml - if-no-files-found: error + path: | + release/*.exe + release/*.dmg + release/*.zip + release/*.AppImage + release/*.deb + release/*.rpm + release/*.blockmap + release/latest*.yml + release/latest*.json + release/builder-debug.yml + if-no-files-found: error publish-release: name: Publish GitHub Release diff --git a/docs/deployment.md b/docs/deployment.md index 4e89c1c..163563e 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -232,6 +232,12 @@ docker run -d --name metapi \ 2. 用户数据目录会保留,升级后自动继续使用原有数据 3. 如需排查启动问题,优先查看 `app.getPath('userData')/logs` 下的最新日志 +Linux 安装包选择建议: + +- Fedora / RHEL / CentOS / openSUSE 优先使用 `.rpm` +- Debian / Ubuntu / Linux Mint 优先使用 `.deb` +- 其他发行版可使用 `.AppImage` + ## 本地开发运行(源码调试) 开发、调试或提交 PR 的完整流程见 [快速上手 → 本地开发启动](./getting-started.md#方式三-本地开发启动) 和 [CONTRIBUTING.md](../CONTRIBUTING.md)。 diff --git a/docs/getting-started.md b/docs/getting-started.md index 8a34144..3c1d6a9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -77,6 +77,12 @@ docker compose up -d 2. 安装并启动 Metapi Desktop 3. 桌面壳会自动启动本地服务并保存数据,无需手动准备 Node.js 环境 +Linux 安装包选择建议: + +- Fedora / RHEL / CentOS / openSUSE 优先下载 `.rpm` +- Debian / Ubuntu / Linux Mint 优先下载 `.deb` +- 其他发行版或想免安装直接运行时,可下载 `.AppImage` + | 项目 | 说明 | |------|------| | 管理界面 | 应用启动后会直接打开桌面窗口,不需要假设固定的 `http://localhost:4000` | @@ -91,6 +97,7 @@ docker compose up -d > [!TIP] > - Windows 下常见路径是 `%APPDATA%\Metapi\data` 和 `%APPDATA%\Metapi\logs`。 > - 如果没有额外覆盖端口,本机其他客户端可以直接连接 `http://127.0.0.1:4000`。 +> - Linux 用户建议优先选原生包:Fedora 系列用 `.rpm`,Debian/Ubuntu 系列用 `.deb`。 > [!WARNING] > **端口冲突排障:** 桌面版默认使用 `4000` 端口;如果该端口被其他应用占用: diff --git a/electron-builder.yml b/electron-builder.yml index ae093b1..9787ff5 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -26,6 +26,7 @@ linux: target: - AppImage - deb + - rpm maintainer: cita-777 publish: provider: github diff --git a/scripts/desktop/release.workflow.test.ts b/scripts/desktop/release.workflow.test.ts index e8a4b6f..670fd70 100644 --- a/scripts/desktop/release.workflow.test.ts +++ b/scripts/desktop/release.workflow.test.ts @@ -3,14 +3,29 @@ import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; describe('release workflow', () => { - it('builds macOS arm64 and x64 on dedicated runners and verifies packaged app architecture', () => { - const workflow = readFileSync(resolve(process.cwd(), '.github/workflows/release.yml'), 'utf8'); - - expect(workflow).toContain('runner: macos-15-intel'); - expect(workflow).toContain('runner: macos-15'); + it('builds macOS arm64 and x64 on dedicated runners and verifies packaged app architecture', () => { + const workflow = readFileSync(resolve(process.cwd(), '.github/workflows/release.yml'), 'utf8'); + + expect(workflow).toContain('runner: macos-15-intel'); + expect(workflow).toContain('runner: macos-15'); expect(workflow).toContain('expectedMacArch: x64'); expect(workflow).toContain('expectedMacArch: arm64'); - expect(workflow).toContain('Verify packaged macOS architecture'); - expect(workflow).toContain('node scripts/desktop/verifyMacArchitecture.mjs'); - }); -}); + expect(workflow).toContain('Verify packaged macOS architecture'); + expect(workflow).toContain('node scripts/desktop/verifyMacArchitecture.mjs'); + }); + + it('uploads Linux desktop artifacts for AppImage, deb, and rpm packages', () => { + const workflow = readFileSync(resolve(process.cwd(), '.github/workflows/release.yml'), 'utf8'); + + expect(workflow).toContain('release/*.AppImage'); + expect(workflow).toContain('release/*.deb'); + expect(workflow).toContain('release/*.rpm'); + }); + + it('installs rpm tooling on Linux runners before packaging Fedora desktop artifacts', () => { + const workflow = readFileSync(resolve(process.cwd(), '.github/workflows/release.yml'), 'utf8'); + + expect(workflow).toContain("if: runner.os == 'Linux'"); + expect(workflow).toContain('sudo apt-get install --no-install-recommends -y rpm'); + }); +}); diff --git a/src/desktop/iconAssets.test.ts b/src/desktop/iconAssets.test.ts index caea752..fa753d0 100644 --- a/src/desktop/iconAssets.test.ts +++ b/src/desktop/iconAssets.test.ts @@ -1,4 +1,5 @@ import { readFile } from 'node:fs/promises'; +import { createRequire } from 'node:module'; import { join } from 'node:path'; import { describe, expect, it } from 'vitest'; @@ -26,4 +27,13 @@ describe('desktop icon assets', () => { expect(config).toContain('icon: build/desktop-icon.png'); }); + + it('builds Linux desktop packages for AppImage, deb, and rpm distributions', async () => { + const configPath = join(process.cwd(), 'electron-builder.yml'); + const require = createRequire(import.meta.url); + const { load } = require('js-yaml') as { load: (source: string) => { linux?: { target?: string[] } } }; + const config = load(await readFile(configPath, 'utf8')); + + expect(config.linux?.target).toEqual(expect.arrayContaining(['AppImage', 'deb', 'rpm'])); + }); });