Merge pull request #839 from Open-Less/release/1.3.15

fix(updater): prepare 1.3.15-Beta.2 after repository transfer
This commit is contained in:
TRIP authored and GitHub committed 2026-07-21 18:43:09 +08:00
commit 857ea6dc21
21 files changed
+110 -67

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
blank_issues_enabled: true blank_issues_enabled: true
contact_links: contact_links:
- name: OpenLess issue / PR 规范 - name: OpenLess issue / PR 规范
url: https://github.com/appergb/openless url: https://github.com/Open-Less/openless
about: 提交前请确认中文正文、upstream 兼容标题、issue-first 和单一职责 PR 规则。 about: 提交前请确认中文正文、upstream 兼容标题、issue-first 和单一职责 PR 规则。
+1 -1
View File
@@ -330,7 +330,7 @@ jobs:
working-directory: openless-all/app working-directory: openless-all/app
env: env:
OPENLESS_UPDATE_APK_DIR: ${{ steps.apk.outputs.out_dir }} OPENLESS_UPDATE_APK_DIR: ${{ steps.apk.outputs.out_dir }}
OPENLESS_UPDATE_REPO: appergb/openless OPENLESS_UPDATE_REPO: Open-Less/openless
OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com
OPENLESS_RELEASE_CHANNEL: ${{ env.OPENLESS_RELEASE_CHANNEL }} OPENLESS_RELEASE_CHANNEL: ${{ env.OPENLESS_RELEASE_CHANNEL }}
OPENLESS_RELEASE_TAG: ${{ github.ref_name }} OPENLESS_RELEASE_TAG: ${{ github.ref_name }}
+1 -1
View File
@@ -499,7 +499,7 @@ jobs:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
OPENLESS_UPDATE_TARGET: ${{ matrix.updater-target }} OPENLESS_UPDATE_TARGET: ${{ matrix.updater-target }}
OPENLESS_UPDATE_ARCH: ${{ matrix.updater-arch }} OPENLESS_UPDATE_ARCH: ${{ matrix.updater-arch }}
OPENLESS_UPDATE_REPO: appergb/openless OPENLESS_UPDATE_REPO: Open-Less/openless
OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com OPENLESS_UPDATE_MIRROR_BASE_URL: https://fastgit.cc/https://github.com
# beta 渠道时输出 latest-{tgt}-{arch}-beta.json,stable 沿用旧文件名。 # beta 渠道时输出 latest-{tgt}-{arch}-beta.json,stable 沿用旧文件名。
OPENLESS_RELEASE_CHANNEL: ${{ env.OPENLESS_RELEASE_CHANNEL }} OPENLESS_RELEASE_CHANNEL: ${{ env.OPENLESS_RELEASE_CHANNEL }}
+2 -2
View File
@@ -5,10 +5,10 @@ cask "openless" do
sha256 arm: "4bfa85f48714626ec010b92d22a5ab98c834f60b5c7e5f6281e12a11ad90ad9f", sha256 arm: "4bfa85f48714626ec010b92d22a5ab98c834f60b5c7e5f6281e12a11ad90ad9f",
intel: "929ad6c047fc8942724b7e1edb5dc0d88affbd2ec4184b2dd3d482c0e06d999f" intel: "929ad6c047fc8942724b7e1edb5dc0d88affbd2ec4184b2dd3d482c0e06d999f"
url "https://github.com/appergb/openless/releases/download/v#{version}-tauri/OpenLess_#{version}_#{arch}.dmg" url "https://github.com/Open-Less/openless/releases/download/v#{version}-tauri/OpenLess_#{version}_#{arch}.dmg"
name "OpenLess" name "OpenLess"
desc "Menu-bar voice input layer" desc "Menu-bar voice input layer"
homepage "https://github.com/appergb/openless" homepage "https://github.com/Open-Less/openless"
livecheck do livecheck do
url :url url :url
+5 -5
View File
@@ -16,7 +16,7 @@
<p align="center"> <p align="center">
<a href="https://openless.top"><strong>Website</strong></a> <a href="https://openless.top"><strong>Website</strong></a>
&nbsp;·&nbsp; &nbsp;·&nbsp;
<a href="https://github.com/appergb/openless/releases/latest"><strong>Download</strong></a> <a href="https://github.com/Open-Less/openless/releases/latest"><strong>Download</strong></a>
&nbsp;·&nbsp; &nbsp;·&nbsp;
<a href="README.md">English</a> <a href="README.md">English</a>
&nbsp;/&nbsp; &nbsp;/&nbsp;
@@ -24,9 +24,9 @@
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/appergb/openless/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/appergb/openless?style=flat-square&color=2c5282" /></a> <a href="https://github.com/Open-Less/openless/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/Open-Less/openless?style=flat-square&color=2c5282" /></a>
<a href="https://github.com/appergb/openless/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/appergb/openless?style=flat-square&color=2f855a" /></a> <a href="https://github.com/Open-Less/openless/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/Open-Less/openless?style=flat-square&color=2f855a" /></a>
<a href="https://github.com/appergb/openless/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/appergb/openless?style=flat-square&color=805ad5" /></a> <a href="https://github.com/Open-Less/openless/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/Open-Less/openless?style=flat-square&color=805ad5" /></a>
<a href="https://discord.gg/vTZHTFGFm"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a> <a href="https://discord.gg/vTZHTFGFm"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a>
</p> </p>
@@ -240,7 +240,7 @@ Go to [Releases](../../releases) and download:
- If unsure, run `adb shell getprop ro.product.cpu.abi` and pick the matching APK. - If unsure, run `adb shell getprop ro.product.cpu.abi` and pick the matching APK.
- **macOS (Homebrew)**: - **macOS (Homebrew)**:
```bash ```bash
brew tap appergb/openless https://github.com/appergb/openless brew tap Open-Less/openless https://github.com/Open-Less/openless
brew install --cask openless brew install --cask openless
xattr -cr /Applications/OpenLess.app xattr -cr /Applications/OpenLess.app
+5 -5
View File
@@ -16,7 +16,7 @@
<p align="center"> <p align="center">
<a href="https://openless.top"><strong>官网</strong></a> <a href="https://openless.top"><strong>官网</strong></a>
&nbsp;·&nbsp; &nbsp;·&nbsp;
<a href="https://github.com/appergb/openless/releases/latest"><strong>下载</strong></a> <a href="https://github.com/Open-Less/openless/releases/latest"><strong>下载</strong></a>
&nbsp;·&nbsp; &nbsp;·&nbsp;
<a href="README.md">English</a> <a href="README.md">English</a>
&nbsp;/&nbsp; &nbsp;/&nbsp;
@@ -24,9 +24,9 @@
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/appergb/openless/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/appergb/openless?style=flat-square&color=2c5282" /></a> <a href="https://github.com/Open-Less/openless/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/Open-Less/openless?style=flat-square&color=2c5282" /></a>
<a href="https://github.com/appergb/openless/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/appergb/openless?style=flat-square&color=2f855a" /></a> <a href="https://github.com/Open-Less/openless/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/Open-Less/openless?style=flat-square&color=2f855a" /></a>
<a href="https://github.com/appergb/openless/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/appergb/openless?style=flat-square&color=805ad5" /></a> <a href="https://github.com/Open-Less/openless/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/Open-Less/openless?style=flat-square&color=805ad5" /></a>
<a href="https://discord.gg/vTZHTFGFm"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a> <a href="https://discord.gg/vTZHTFGFm"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a>
</p> </p>
@@ -240,7 +240,7 @@ OpenLess 只做一件事:**把语音变成可用的书面文字(尤其是 AI 提
- 不确定时执行 `adb shell getprop ro.product.cpu.abi`,下载对应 ABI 的包。 - 不确定时执行 `adb shell getprop ro.product.cpu.abi`,下载对应 ABI 的包。
- **macOS(Homebrew)**: - **macOS(Homebrew)**:
```bash ```bash
brew tap appergb/openless https://github.com/appergb/openless brew tap Open-Less/openless https://github.com/Open-Less/openless
brew install --cask openless brew install --cask openless
xattr -cr /Applications/OpenLess.app xattr -cr /Applications/OpenLess.app
+2 -2
View File
@@ -4,13 +4,13 @@
### macOS ### macOS
1. 从 [Releases](https://github.com/appergb/openless/releases/latest) 下载 `OpenLess_<版本>_aarch64.dmg`。 1. 从 [Releases](https://github.com/Open-Less/openless/releases/latest) 下载 `OpenLess_<版本>_aarch64.dmg`。
2. 打开 dmg,将 OpenLess.app 拖入「应用程序」文件夹。 2. 打开 dmg,将 OpenLess.app 拖入「应用程序」文件夹。
3. 双击启动。 3. 双击启动。
### Windows ### Windows
1. 从 [Releases](https://github.com/appergb/openless/releases/latest) 下载 `OpenLess_<版本>_x64-setup.exe`。 1. 从 [Releases](https://github.com/Open-Less/openless/releases/latest) 下载 `OpenLess_<版本>_x64-setup.exe`。
2. 运行安装程序,按提示完成安装。 2. 运行安装程序,按提示完成安装。
3. 从开始菜单启动 OpenLess。 3. 从开始菜单启动 OpenLess。
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "openless-app", "name": "openless-app",
"version": "1.3.15-Beta.1", "version": "1.3.15-Beta.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "openless-app", "name": "openless-app",
"version": "1.3.15-Beta.1", "version": "1.3.15-Beta.2",
"dependencies": { "dependencies": {
"@base-ui/react": "^1.6.0", "@base-ui/react": "^1.6.0",
"@formkit/auto-animate": "^0.9.0", "@formkit/auto-animate": "^0.9.0",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "openless-app", "name": "openless-app",
"private": true, "private": true,
"version": "1.3.15-Beta.1", "version": "1.3.15-Beta.2",
"type": "module", "type": "module",
"scripts": { "scripts": {
"pretest": "npm run build", "pretest": "npm run build",
@@ -10,6 +10,7 @@ for (const expected of [
'scripts/check-hotkey-injection.mjs', 'scripts/check-hotkey-injection.mjs',
'scripts/macos-capsule-spaces-contract.test.mjs', 'scripts/macos-capsule-spaces-contract.test.mjs',
'scripts/macos-speech-usage-description-contract.test.mjs', 'scripts/macos-speech-usage-description-contract.test.mjs',
'scripts/repository-owner-contract.test.mjs',
'scripts/windows-ui-config.test.mjs', 'scripts/windows-ui-config.test.mjs',
'src/lib/hotkeyRecorder.test.ts', 'src/lib/hotkeyRecorder.test.ts',
'src/lib/windowHotkeyFallback.test.ts', 'src/lib/windowHotkeyFallback.test.ts',
@@ -0,0 +1,43 @@
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
const repoRoot = fileURLToPath(new URL('../../..', import.meta.url));
const currentRepo = 'Open-Less/openless';
const legacyRepo = 'appergb/openless';
const repositoryReferences = [
'.github/ISSUE_TEMPLATE/config.yml',
'.github/workflows/android-apk.yml',
'.github/workflows/release-tauri.yml',
'Casks/openless.rb',
'README.md',
'README.zh.md',
'USAGE.md',
'openless-all/app/src-tauri/src/android/updater_logic.rs',
'openless-all/app/src-tauri/src/commands/mod.rs',
'openless-all/app/src-tauri/src/commands/settings.rs',
'openless-all/app/src-tauri/tauri.conf.json',
'openless-all/app/src/components/AutoUpdate.tsx',
'openless-all/app/src/components/SettingsModal.tsx',
'openless-all/app/src/pages/settings/AboutSection.tsx',
'openless-all/app/scripts/write-updater-manifest.mjs',
];
for (const relativePath of repositoryReferences) {
const content = await readFile(join(repoRoot, relativePath), 'utf8');
assert(!content.includes(legacyRepo), `${relativePath} still references the pre-transfer repository`);
}
const tauriConfig = JSON.parse(
await readFile(join(repoRoot, 'openless-all/app/src-tauri/tauri.conf.json'), 'utf8'),
);
const updaterEndpoints = tauriConfig?.plugins?.updater?.endpoints;
assert(Array.isArray(updaterEndpoints) && updaterEndpoints.length > 0, 'desktop updater endpoints are missing');
assert(
updaterEndpoints.every((endpoint) => endpoint.includes(currentRepo)),
'desktop updater endpoints must use the current GitHub repository',
);
console.log('repository-owner-contract.test.mjs passed');
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
const target = process.env.OPENLESS_UPDATE_TARGET; const target = process.env.OPENLESS_UPDATE_TARGET;
const arch = process.env.OPENLESS_UPDATE_ARCH; const arch = process.env.OPENLESS_UPDATE_ARCH;
const repo = process.env.OPENLESS_UPDATE_REPO || 'appergb/openless'; const repo = process.env.OPENLESS_UPDATE_REPO || 'Open-Less/openless';
const mirrorBaseUrl = process.env.OPENLESS_UPDATE_MIRROR_BASE_URL || 'https://fastgit.cc/https://github.com'; const mirrorBaseUrl = process.env.OPENLESS_UPDATE_MIRROR_BASE_URL || 'https://fastgit.cc/https://github.com';
const rawChannel = (process.env.OPENLESS_RELEASE_CHANNEL || 'stable').toLowerCase(); const rawChannel = (process.env.OPENLESS_RELEASE_CHANNEL || 'stable').toLowerCase();
if (rawChannel !== 'stable' && rawChannel !== 'beta') { if (rawChannel !== 'stable' && rawChannel !== 'beta') {
+1 -1
View File
@@ -3909,7 +3909,7 @@ dependencies = [
[[package]] [[package]]
name = "openless" name = "openless"
version = "1.3.15-Beta.1" version = "1.3.15-Beta.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arboard", "arboard",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "openless" name = "openless"
version = "1.3.15-Beta.1" version = "1.3.15-Beta.2"
description = "OpenLess — local voice input that types where your cursor is" description = "OpenLess — local voice input that types where your cursor is"
authors = ["OpenLess"] authors = ["OpenLess"]
edition = "2021" edition = "2021"
@@ -1,7 +1,7 @@
//! Pure Android updater helpers (manifest URLs, version compare). Testable on all targets. //! Pure Android updater helpers (manifest URLs, version compare). Testable on all targets.
pub const MIRROR_BASE: &str = "https://fastgit.cc/https://github.com/appergb/openless"; pub const MIRROR_BASE: &str = "https://fastgit.cc/https://github.com/Open-Less/openless";
pub const DIRECT_BASE: &str = "https://github.com/appergb/openless"; pub const DIRECT_BASE: &str = "https://github.com/Open-Less/openless";
/// Must match `plugins.updater.pubkey` in `tauri.conf.json` (TAURI_SIGNING_PRIVATE_KEY pair). /// Must match `plugins.updater.pubkey` in `tauri.conf.json` (TAURI_SIGNING_PRIVATE_KEY pair).
pub const UPDATER_PUBKEY_B64: &str = pub const UPDATER_PUBKEY_B64: &str =
@@ -104,11 +104,11 @@ mod tests {
let body = r#"<feed> let body = r#"<feed>
<entry> <entry>
<updated>2026-07-15T07:00:00Z</updated> <updated>2026-07-15T07:00:00Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-tauri"/>
</entry> </entry>
<entry> <entry>
<updated>2026-06-17T15:41:46Z</updated> <updated>2026-06-17T15:41:46Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.3.10-4-beta-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.3.10-4-beta-tauri"/>
</entry> </entry>
</feed>"#; </feed>"#;
let latest = crate::commands::parse_latest_beta_from_atom(body) let latest = crate::commands::parse_latest_beta_from_atom(body)
@@ -125,9 +125,9 @@ mod tests {
#[test] #[test]
fn beta_manifest_urls_skip_malformed_modern_tags_from_atom() { fn beta_manifest_urls_skip_malformed_modern_tags_from_atom() {
let body = r#"<feed> let body = r#"<feed>
<entry><link href="https://github.com/appergb/openless/releases/tag/v-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/garbage-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/garbage-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-tauri"/></entry>
</feed>"#; </feed>"#;
let latest = crate::commands::parse_latest_beta_from_atom(body) let latest = crate::commands::parse_latest_beta_from_atom(body)
.expect("Android updater must skip malformed Beta tags"); .expect("Android updater must skip malformed Beta tags");
+20 -20
View File
@@ -1261,13 +1261,13 @@ mod tests {
<entry> <entry>
<id>tag:github.com,2008:Repository/X/v1.2.23-tauri</id> <id>tag:github.com,2008:Repository/X/v1.2.23-tauri</id>
<updated>2026-05-07T09:05:00Z</updated> <updated>2026-05-07T09:05:00Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.2.23-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.2.23-tauri"/>
<title>OpenLess v1.2.23-tauri</title> <title>OpenLess v1.2.23-tauri</title>
</entry> </entry>
<entry> <entry>
<id>tag:github.com,2008:Repository/X/v1.2.24-2-beta-tauri</id> <id>tag:github.com,2008:Repository/X/v1.2.24-2-beta-tauri</id>
<updated>2026-05-08T01:27:23Z</updated> <updated>2026-05-08T01:27:23Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.2.24-2-beta-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.2.24-2-beta-tauri"/>
<title>OpenLess v1.2.24-2-beta-tauri</title> <title>OpenLess v1.2.24-2-beta-tauri</title>
</entry> </entry>
</feed>"#; </feed>"#;
@@ -1275,7 +1275,7 @@ mod tests {
assert_eq!(got.tag_name, "v1.2.24-2-beta-tauri"); assert_eq!(got.tag_name, "v1.2.24-2-beta-tauri");
assert_eq!( assert_eq!(
got.html_url, got.html_url,
"https://github.com/appergb/openless/releases/tag/v1.2.24-2-beta-tauri" "https://github.com/Open-Less/openless/releases/tag/v1.2.24-2-beta-tauri"
); );
assert_eq!(got.published_at, "2026-05-08T01:27:23Z"); assert_eq!(got.published_at, "2026-05-08T01:27:23Z");
} }
@@ -1286,15 +1286,15 @@ mod tests {
<feed> <feed>
<entry> <entry>
<updated>2026-07-15T08:00:00Z</updated> <updated>2026-07-15T08:00:00Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.3.15-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-tauri"/>
</entry> </entry>
<entry> <entry>
<updated>2026-07-15T07:00:00Z</updated> <updated>2026-07-15T07:00:00Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-tauri"/>
</entry> </entry>
<entry> <entry>
<updated>2026-06-17T15:41:46Z</updated> <updated>2026-06-17T15:41:46Z</updated>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.3.10-4-beta-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.3.10-4-beta-tauri"/>
</entry> </entry>
</feed>"#; </feed>"#;
@@ -1307,21 +1307,21 @@ mod tests {
#[test] #[test]
fn parse_latest_beta_from_atom_skips_malformed_modern_tags() { fn parse_latest_beta_from_atom_skips_malformed_modern_tags() {
let body = r#"<feed> let body = r#"<feed>
<entry><link href="https://github.com/appergb/openless/releases/tag/v-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/garbage-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/garbage-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/1.3.15-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/1.3.15-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15.0-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15.0-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1..15-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1..15-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.x-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.x-Beta.1-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.x-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.x-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-extra-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-extra-tauri"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-tauri-extra"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-tauri-extra"/></entry>
<entry><link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.2-Beta.1-tauri"/></entry> <entry><link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.2-Beta.1-tauri"/></entry>
<entry> <entry>
<updated>2026-07-15T07:00:00Z</updated> <updated>2026-07-15T07:00:00Z</updated>
<link href="https://github.com/appergb/openless/releases/tag/v1.3.15-Beta.1-tauri"/> <link href="https://github.com/Open-Less/openless/releases/tag/v1.3.15-Beta.1-tauri"/>
</entry> </entry>
</feed>"#; </feed>"#;
@@ -1335,7 +1335,7 @@ mod tests {
fn parse_latest_beta_from_atom_returns_none_when_only_stable_releases() { fn parse_latest_beta_from_atom_returns_none_when_only_stable_releases() {
let body = r#"<feed> let body = r#"<feed>
<entry> <entry>
<link rel="alternate" type="text/html" href="https://github.com/appergb/openless/releases/tag/v1.2.23-tauri"/> <link rel="alternate" type="text/html" href="https://github.com/Open-Less/openless/releases/tag/v1.2.23-tauri"/>
<updated>2026-05-07T09:05:00Z</updated> <updated>2026-05-07T09:05:00Z</updated>
</entry> </entry>
</feed>"#; </feed>"#;
@@ -478,7 +478,7 @@ pub struct LatestBetaRelease {
pub async fn fetch_latest_beta_release() -> Result<Option<LatestBetaRelease>, String> { pub async fn fetch_latest_beta_release() -> Result<Option<LatestBetaRelease>, String> {
let resp = net::send_with_retry(|| { let resp = net::send_with_retry(|| {
net::http() net::http()
.get("https://github.com/appergb/openless/releases.atom") .get("https://github.com/Open-Less/openless/releases.atom")
.timeout(std::time::Duration::from_secs(15)) .timeout(std::time::Duration::from_secs(15))
}) })
.await .await
@@ -515,7 +515,7 @@ pub(crate) fn parse_latest_beta_from_atom(body: &str) -> Option<LatestBetaReleas
if !is_beta_release_tag(&tag_name) { if !is_beta_release_tag(&tag_name) {
continue; continue;
} }
let html_url = format!("https://github.com/appergb/openless/releases/tag/{tag_name}"); let html_url = format!("https://github.com/Open-Less/openless/releases/tag/{tag_name}");
let published_at = let published_at =
extract_between(entry_body, "<updated>", "</updated>").unwrap_or_default(); extract_between(entry_body, "<updated>", "</updated>").unwrap_or_default();
return Some(LatestBetaRelease { return Some(LatestBetaRelease {
@@ -648,10 +648,10 @@ async fn resolve_beta_manifest_endpoints() -> Result<Vec<url::Url>, String> {
// {{target}} / {{arch}} 占位符由 plugin 在 check 时替换。Rust raw string 用 r#""# // {{target}} / {{arch}} 占位符由 plugin 在 check 时替换。Rust raw string 用 r#""#
// 不需要转义双花括号,比 format! 干净。 // 不需要转义双花括号,比 format! 干净。
let mirror = format!( let mirror = format!(
"https://fastgit.cc/https://github.com/appergb/openless/releases/download/{tag}/latest-{{{{target}}}}-{{{{arch}}}}-beta-mirror.json" "https://fastgit.cc/https://github.com/Open-Less/openless/releases/download/{tag}/latest-{{{{target}}}}-{{{{arch}}}}-beta-mirror.json"
); );
let direct = format!( let direct = format!(
"https://github.com/appergb/openless/releases/download/{tag}/latest-{{{{target}}}}-{{{{arch}}}}-beta.json" "https://github.com/Open-Less/openless/releases/download/{tag}/latest-{{{{target}}}}-{{{{arch}}}}-beta.json"
); );
let mirror_url = url::Url::parse(&mirror).map_err(|e| format!("parse beta mirror url: {e}"))?; let mirror_url = url::Url::parse(&mirror).map_err(|e| format!("parse beta mirror url: {e}"))?;
let direct_url = url::Url::parse(&direct).map_err(|e| format!("parse beta direct url: {e}"))?; let direct_url = url::Url::parse(&direct).map_err(|e| format!("parse beta direct url: {e}"))?;
@@ -894,8 +894,8 @@ pub async fn app_download_and_install_android_update(
) -> Result<(), String> { ) -> Result<(), String> {
// 安全:下载前校验 URL,防止 SSRF(如内网元数据接口、localhost 服务)。 // 安全:下载前校验 URL,防止 SSRF(如内网元数据接口、localhost 服务)。
// 只允许已知的 GitHub 直链和 fastgit 镜像前缀。 // 只允许已知的 GitHub 直链和 fastgit 镜像前缀。
const DIRECT_BASE: &str = "https://github.com/appergb/openless"; const DIRECT_BASE: &str = "https://github.com/Open-Less/openless";
const MIRROR_BASE: &str = "https://fastgit.cc/https://github.com/appergb/openless"; const MIRROR_BASE: &str = "https://fastgit.cc/https://github.com/Open-Less/openless";
if !url.starts_with(DIRECT_BASE) && !url.starts_with(MIRROR_BASE) { if !url.starts_with(DIRECT_BASE) && !url.starts_with(MIRROR_BASE) {
return Err(format!("不信任的更新 URL,拒绝下载: {url}")); return Err(format!("不信任的更新 URL,拒绝下载: {url}"));
} }
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "OpenLess", "productName": "OpenLess",
"version": "1.3.15-Beta.1", "version": "1.3.15-Beta.2",
"identifier": "com.openless.app", "identifier": "com.openless.app",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
@@ -102,8 +102,8 @@
"updater": { "updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDFERUFBODAzNTY0QzMyM0YKUldRL01reFdBNmpxSGE1K0JadlpONXNWTzhJcGZCRGxjUVdIWExNNFJpeUNsSGZwazdlQThhemkK", "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDFERUFBODAzNTY0QzMyM0YKUldRL01reFdBNmpxSGE1K0JadlpONXNWTzhJcGZCRGxjUVdIWExNNFJpeUNsSGZwazdlQThhemkK",
"endpoints": [ "endpoints": [
"https://github.com/appergb/openless/releases/latest/download/latest-{{target}}-{{arch}}.json", "https://github.com/Open-Less/openless/releases/latest/download/latest-{{target}}-{{arch}}.json",
"https://fastgit.cc/https://github.com/appergb/openless/releases/latest/download/latest-{{target}}-{{arch}}-mirror.json" "https://fastgit.cc/https://github.com/Open-Less/openless/releases/latest/download/latest-{{target}}-{{arch}}-mirror.json"
] ]
} }
} }
@@ -26,7 +26,7 @@ import { Btn } from '../pages/_atoms';
const UPDATE_CHECK_TIMEOUT_MS = 15_000; const UPDATE_CHECK_TIMEOUT_MS = 15_000;
// 自动更新失败时的手动下载兜底:直达 GitHub Releases(与「关于」页 RELEASE_NOTES_URL 一致)。 // 自动更新失败时的手动下载兜底:直达 GitHub Releases(与「关于」页 RELEASE_NOTES_URL 一致)。
const RELEASE_DOWNLOAD_URL = 'https://github.com/appergb/openless/releases'; const RELEASE_DOWNLOAD_URL = 'https://github.com/Open-Less/openless/releases';
export type UpdateStatus = export type UpdateStatus =
| 'idle' | 'idle'
@@ -40,8 +40,8 @@ interface ModalNavItem {
href?: string; href?: string;
} }
const HELP_URL = 'https://github.com/appergb/openless#readme'; const HELP_URL = 'https://github.com/Open-Less/openless#readme';
const RELEASE_NOTES_URL = 'https://github.com/appergb/openless/releases'; const RELEASE_NOTES_URL = 'https://github.com/Open-Less/openless/releases';
// 第一组:可选中的 tab;第二组:外部链接(永远不 active)。 // 第一组:可选中的 tab;第二组:外部链接(永远不 active)。
const TAB_ITEMS: ModalNavItem[] = [ const TAB_ITEMS: ModalNavItem[] = [
@@ -14,8 +14,8 @@ import { Card } from '../_atoms';
import { btnGhostStyle, SectionTitle } from './shared'; import { btnGhostStyle, SectionTitle } from './shared';
import { CheckUpdateButton } from './CheckUpdateButton'; import { CheckUpdateButton } from './CheckUpdateButton';
const HELP_URL = 'https://github.com/appergb/openless#readme'; const HELP_URL = 'https://github.com/Open-Less/openless#readme';
const RELEASE_NOTES_URL = 'https://github.com/appergb/openless/releases'; const RELEASE_NOTES_URL = 'https://github.com/Open-Less/openless/releases';
export function AboutSection() { export function AboutSection() {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -67,7 +67,7 @@ export function AboutSection() {
<Card> <Card>
<SectionTitle>{t('settings.about.linksTitle')}</SectionTitle> <SectionTitle>{t('settings.about.linksTitle')}</SectionTitle>
<Row label={t('modal.about.source')}> <Row label={t('modal.about.source')}>
<button style={btnGhostStyle} onClick={() => openExternal('https://github.com/appergb/openless')}> <button style={btnGhostStyle} onClick={() => openExternal('https://github.com/Open-Less/openless')}>
GitHub GitHub
</button> </button>
</Row> </Row>
@@ -87,7 +87,7 @@ export function AboutSection() {
</button> </button>
</Row> </Row>
<Row label={t('modal.about.feedback')}> <Row label={t('modal.about.feedback')}>
<button style={btnGhostStyle} onClick={() => openExternal('https://github.com/appergb/openless/issues')}> <button style={btnGhostStyle} onClick={() => openExternal('https://github.com/Open-Less/openless/issues')}>
{t('modal.about.feedbackBtn')} {t('modal.about.feedbackBtn')}
</button> </button>
</Row> </Row>
@@ -110,4 +110,3 @@ export function AboutSection() {
</> </>
); );
} }