1
0
forked from boos/BoosAPI

feat: enhance desktop build process with artifact upload and download, and update server working directory resolution

This commit is contained in:
cita
2026-03-06 20:25:48 +08:00
parent 6c51801e50
commit 02bf0393e6
6 changed files with 54 additions and 5 deletions
+16 -3
View File
@@ -38,6 +38,13 @@ jobs:
- name: Build
run: npm run build
- name: Upload built dist
uses: actions/upload-artifact@v4
with:
name: metapi-dist-${{ github.sha }}
path: dist
if-no-files-found: error
build-packages:
name: Build Desktop Package (${{ matrix.os }})
needs: verify
@@ -101,6 +108,12 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Download built dist
uses: actions/download-artifact@v4
with:
name: metapi-dist-${{ github.sha }}
path: .
- name: Prefetch AppImage tools
if: runner.os == 'Linux'
shell: bash
@@ -132,7 +145,7 @@ jobs:
if ($env:WIN_CSC_KEY_PASSWORD_INPUT) { $env:WIN_CSC_KEY_PASSWORD = $env:WIN_CSC_KEY_PASSWORD_INPUT }
for ($attempt = 1; $attempt -le 2; $attempt++) {
Write-Host "Desktop build attempt $attempt/2"
npm run dist:desktop
npm run package:desktop
if ($LASTEXITCODE -eq 0) {
break
}
@@ -157,7 +170,7 @@ jobs:
set -euo pipefail
for attempt in 1 2; do
echo "Desktop build attempt ${attempt}/2"
if npm run dist:desktop; then
if npm run package:desktop; then
break
fi
if [ "$attempt" -eq 2 ]; then
@@ -186,7 +199,7 @@ jobs:
if [ -n "${APPLE_TEAM_ID_INPUT:-}" ]; then export APPLE_TEAM_ID="$APPLE_TEAM_ID_INPUT"; fi
for attempt in 1 2; do
echo "Desktop build attempt ${attempt}/2"
if npm run dist:desktop; then
if npm run package:desktop; then
break
fi
if [ "$attempt" -eq 2 ]; then
+1
View File
@@ -27,6 +27,7 @@ linux:
target:
- AppImage
- deb
maintainer: cita-777 <cita-777@users.noreply.github.com>
publish:
provider: github
owner: cita-777
+6 -1
View File
@@ -31,6 +31,7 @@
"build:desktop": "tsc -p tsconfig.desktop.json",
"build": "npm run build:web && npm run build:server && npm run build:desktop",
"dist:desktop": "npm run build && electron-builder --config electron-builder.yml --publish never",
"package:desktop": "electron-builder --config electron-builder.yml --publish never",
"docs:dev": "vitepress dev docs --host 0.0.0.0 --port 4173",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs --host 0.0.0.0 --port 4173",
@@ -101,5 +102,9 @@
"overrides": {
"minimist": "^1.2.8"
},
"author": "cita-777"
"author": {
"name": "cita-777",
"email": "cita-777@users.noreply.github.com",
"url": "https://github.com/cita-777"
}
}
+6 -1
View File
@@ -18,6 +18,7 @@ import {
createDesktopHealthUrl,
createDesktopServerUrl,
isFatalServerExit,
resolveDesktopServerWorkingDir,
waitForServerReady,
} from './runtime.js';
@@ -195,7 +196,11 @@ async function startManagedBackend() {
});
const child = spawn(process.execPath, [serverEntryPath], {
cwd: app.getAppPath(),
cwd: resolveDesktopServerWorkingDir({
appPath: app.getAppPath(),
resourcesPath: process.resourcesPath,
isPackaged: app.isPackaged,
}),
env: {
...env,
ELECTRON_RUN_AS_NODE: '1',
+15
View File
@@ -3,6 +3,7 @@ import {
buildDesktopServerEnv,
createDesktopServerUrl,
isFatalServerExit,
resolveDesktopServerWorkingDir,
waitForServerReady,
} from './runtime.js';
@@ -30,6 +31,20 @@ describe('desktop runtime helpers', () => {
expect(createDesktopServerUrl(4312)).toBe('http://127.0.0.1:4312');
});
it('uses resources path as backend cwd for packaged desktop builds', () => {
expect(resolveDesktopServerWorkingDir({
appPath: 'C:/Users/test/AppData/Local/Programs/Metapi/resources/app.asar',
resourcesPath: 'C:/Users/test/AppData/Local/Programs/Metapi/resources',
isPackaged: true,
})).toBe('C:/Users/test/AppData/Local/Programs/Metapi/resources');
expect(resolveDesktopServerWorkingDir({
appPath: '/workspace/metapi',
resourcesPath: '/tmp/electron/resources',
isPackaged: false,
})).toBe('/workspace/metapi');
});
it('waits until the health probe returns ok', async () => {
const fetcher = vi.fn()
.mockRejectedValueOnce(new Error('offline'))
+10
View File
@@ -17,6 +17,12 @@ type ServerExitState = {
signal: NodeJS.Signals | null;
};
type DesktopServerWorkingDirInput = {
appPath: string;
resourcesPath: string;
isPackaged: boolean;
};
const DEFAULT_READY_TIMEOUT_MS = 30_000;
const DEFAULT_READY_INTERVAL_MS = 250;
@@ -43,6 +49,10 @@ export function createDesktopHealthUrl(port: number): string {
return `${createDesktopServerUrl(port)}/api/desktop/health`;
}
export function resolveDesktopServerWorkingDir(input: DesktopServerWorkingDirInput): string {
return input.isPackaged ? input.resourcesPath : input.appPath;
}
export async function waitForServerReady(input: WaitForServerReadyInput): Promise<void> {
const fetcher = input.fetcher || ((url: string, init?: RequestInit) => fetch(url, init));
const timeoutMs = input.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;