fix updater download acceleration

This commit is contained in:
Cooper-X-Oak committed 2026-05-01 23:47:58 +08:00
1 parent 110332580a
commit e34b3feee7
5 files changed
+82 -3

No files matched your search

+4
View File
@@ -222,6 +222,7 @@ jobs:
OPENLESS_UPDATE_TARGET: ${{ matrix.updater-target }}
OPENLESS_UPDATE_ARCH: ${{ matrix.updater-arch }}
OPENLESS_UPDATE_REPO: appergb/openless
OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com
run: node scripts/write-updater-manifest.mjs
# ── 收集产物 ──
@@ -266,6 +267,7 @@ jobs:
openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz
openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz.sig
openless-all/app/src-tauri/target/release/bundle/latest-darwin-aarch64.json
openless-all/app/src-tauri/target/release/bundle/latest-darwin-aarch64-mirror.json
if-no-files-found: error
- name: Upload Windows artifacts
@@ -287,6 +289,7 @@ jobs:
openless-all/app/src-tauri/target/release/bundle/nsis/*.exe.sig
openless-all/app/src-tauri/target/release/bundle/msi/*.msi.sig
openless-all/app/src-tauri/target/release/bundle/latest-windows-x86_64.json
openless-all/app/src-tauri/target/release/bundle/latest-windows-x86_64-mirror.json
if-no-files-found: error
- name: Upload Linux artifacts
@@ -308,6 +311,7 @@ jobs:
path: |
openless-all/app/src-tauri/target/release/bundle/appimage/*.AppImage.sig
openless-all/app/src-tauri/target/release/bundle/latest-linux-x86_64.json
openless-all/app/src-tauri/target/release/bundle/latest-linux-x86_64-mirror.json
if-no-files-found: error
# ── tag 推送时,同步上传到 GitHub Release ──
+63
View File
@@ -0,0 +1,63 @@
# Auto Update Download Acceleration
## Problem
OpenLess used a single Tauri updater endpoint on GitHub Releases:
```text
https://github.com/appergb/openless/releases/latest/download/latest-{{target}}-{{arch}}.json
```
The manifest also pointed installer downloads back to GitHub Releases. On networks where GitHub release assets are slow, a small updater package can take minutes to download.
Desktop apps do not reliably inherit a user's shell proxy environment. Instead of making updater correctness depend on whether a proxy is visible to the app process, the updater should use a GitHub release acceleration URL directly.
## Runtime Behavior
The app does not manually probe local proxy ports. It lets the OS/process network stack do whatever it normally does, while the updater endpoint itself points at `fastgit.cc` first. This keeps the rule simple: proxy or no proxy, updater traffic should prefer the fastgit transport.
## Fastgit Acceleration
Release builds now publish two updater manifests per target:
```text
latest-<target>-<arch>.json
latest-<target>-<arch>-mirror.json
```
The client checks the mirror manifest first, then GitHub. The mirror manifest points its installer URL at:
```text
https://fastgit.cc/https://github.com/<repo>/releases/latest/download/<asset>
```
The updater signature still protects the downloaded package. The mirror only changes transport; it cannot replace the signed payload without verification failing.
## Maintainer Notes
Set `OPENLESS_UPDATE_MIRROR_BASE_URL` in CI to change the mirror host. Keep it formatted as a prefix for GitHub URLs, for example:
```text
https://fastgit.cc/https://github.com
```
If a mirror becomes unreliable, replace that environment value and the mirror endpoint in `openless-all/app/src-tauri/tauri.conf.json`.
## Evidence
Measured from Windows on 2026-05-01. Direct GitHub release downloads were tested with local proxy disabled to reproduce the slow path. `fastgit.cc` was tested both through the normal local proxy environment and with local proxy disabled; results vary by route, so do not treat one machine's no-proxy number as a CDN SLA.
```text
Direct GitHub installer asset, 4.78 MB, proxy disabled:
run 1: timed out after 90.75s, 1.73 MB received
run 2: timed out after 90.06s, 2.44 MB received
fastgit.cc installer asset, 4.78 MB, normal local proxy environment:
with protocol prefix: 3.12s / 3.63s / 3.39s
without protocol prefix: 2.92s / 2.45s / 2.87s
fastgit.cc target-user signal:
manual browser/download usage reported completing in under 1s without enabling a proxy.
```
This is enough to justify a `fastgit.cc` mirror path, but not enough to treat a public mirror as permanently trusted infrastructure. `fastgit.cc` explicitly documents support for GitHub release/archive acceleration and accepts GitHub links with or without the protocol prefix. Keep the mirror configurable and re-test before each release if download performance is a release blocker.
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'node:url';
const target = process.env.OPENLESS_UPDATE_TARGET;
const arch = process.env.OPENLESS_UPDATE_ARCH;
const repo = process.env.OPENLESS_UPDATE_REPO || 'appergb/openless';
const mirrorBaseUrl = process.env.OPENLESS_UPDATE_MIRROR_BASE_URL || 'https://fastgit.cc/https://github.com';
if (!target || !arch) {
throw new Error('OPENLESS_UPDATE_TARGET and OPENLESS_UPDATE_ARCH are required');
@@ -52,12 +53,20 @@ if (!existsSync(signaturePath)) {
const assetName = basename(artifact);
const manifestName = `latest-${target}-${arch}.json`;
const mirrorManifestName = `latest-${target}-${arch}-mirror.json`;
const githubAssetUrl = `https://github.com/${repo}/releases/latest/download/${assetName}`;
const mirrorAssetUrl = `${mirrorBaseUrl.replace(/\/$/, '')}/${repo}/releases/latest/download/${assetName}`;
const manifest = {
version: packageJson.version,
pub_date: new Date().toISOString(),
url: `https://github.com/${repo}/releases/latest/download/${assetName}`,
url: githubAssetUrl,
signature: readFileSync(signaturePath, 'utf8').trim(),
};
const mirrorManifest = {
...manifest,
url: mirrorAssetUrl,
};
writeFileSync(join(bundleDir, manifestName), `${JSON.stringify(manifest, null, 2)}\n`);
console.log(`Wrote ${manifestName} for ${assetName}`);
writeFileSync(join(bundleDir, mirrorManifestName), `${JSON.stringify(mirrorManifest, null, 2)}\n`);
console.log(`Wrote ${manifestName} and ${mirrorManifestName} for ${assetName}`);
@@ -88,6 +88,7 @@
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDFERUFBODAzNTY0QzMyM0YKUldRL01reFdBNmpxSGE1K0JadlpONXNWTzhJcGZCRGxjUVdIWExNNFJpeUNsSGZwazdlQThhemkK",
"endpoints": [
"https://fastgit.cc/https://github.com/appergb/openless/releases/latest/download/latest-{{target}}-{{arch}}-mirror.json",
"https://github.com/appergb/openless/releases/latest/download/latest-{{target}}-{{arch}}.json"
]
}
@@ -7,6 +7,8 @@ import { useTranslation } from 'react-i18next';
import { isTauri, restartApp } from '../lib/ipc';
import { Btn } from '../pages/_atoms';
const UPDATE_CHECK_TIMEOUT_MS = 15_000;
export type UpdateStatus =
| 'idle'
| 'checking'
@@ -78,7 +80,7 @@ export function useAutoUpdate(): UseAutoUpdate {
return;
}
const { check } = await import('@tauri-apps/plugin-updater');
const next = await check();
const next = await check({ timeout: UPDATE_CHECK_TIMEOUT_MS });
updateRef.current = next;
setVersion(next?.version ?? '');
setStatus(next ? 'available' : 'none');