mirror of
https://github.com/baoweise-bot/aimili-vpngate.git
synced 2026-09-06 08:07:04 +08:00
release: prepare v2.1.1
This commit is contained in:
@@ -7,9 +7,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: Existing formal tag to publish, for example v2.1.0
|
||||
description: Existing formal tag to publish, for example v2.1.1
|
||||
required: true
|
||||
default: v2.1.0
|
||||
default: v2.1.1
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
shell: bash
|
||||
run: |
|
||||
title="AimiliVPN V$(cut -d. -f1,2 VERSION) 正式版"
|
||||
title="AimiliVPN V$(tr -d '\r\n' < VERSION) 正式版"
|
||||
if gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
|
||||
gh release upload "${RELEASE_TAG}" dist/* --clobber --repo "${GITHUB_REPOSITORY}"
|
||||
gh release edit "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file RELEASE_NOTES.md
|
||||
|
||||
+59
-14
@@ -1,19 +1,64 @@
|
||||
# AimiliVPN V2.1 正式版
|
||||
# AimiliVPN V2.1.1 正式版
|
||||
|
||||
V2.1 是仅从 `main` 主分支发布的首个正式版本标志。
|
||||
V2.1.1 是一次以稳定性、浏览器兼容性和 VPS 实际使用体验为重点的维护更新。本次版本已在 Ubuntu 22.04 VPS 上通过安装、节点获取、代理出口、节点切换、断开与恢复测试。
|
||||
|
||||
## 本次更新
|
||||
## Bug 修复
|
||||
|
||||
- 节点来源按“VPNGate 官方 HTTPS -> 官方 HTTP -> GitHub Pages HTTPS -> GitHub Pages HTTP -> VPS 本地快照 -> 内置初始快照”自动回退。
|
||||
- 修复节点获取缓慢、连接断开和切换失败时误伤现有连接的问题。
|
||||
- 恢复节点延迟列,区分本机实测值与 VPNGate 官方预估值。
|
||||
- 加入国旗、实时多选国家筛选、国家范围持久化和单节点测试。
|
||||
- Web 管理端加入正式版更新检测,只检查 GitHub 最新稳定 Release,并根据 Python 源码或 Docker 部署方式显示对应更新命令。
|
||||
- `install.sh` 和 `ml update` 统一只更新 `origin/main`。
|
||||
- GitHub Release 提供一个适用于 Linux `amd64`、`386`、`arm64`、`armv7` 的通用 Python 源码包与 SHA-256 校验文件。
|
||||
- GHCR 提供经过逐架构冒烟测试的 `amd64`、`386`、`arm64`、`arm/v7` Docker 镜像,并同时发布 `2.1.0`、`2.1`、`latest` 标签。
|
||||
- Docker 用户默认拉取 GitHub 预构建镜像,也可以使用仓库中的 Dockerfile 在 VPS 本地构建。
|
||||
- 修复 Edge 和部分 Chromium 浏览器打开管理页面后高占用、卡顿甚至浏览器失去响应的问题:移除高成本的 `backdrop-filter`、固定背景和远程字体依赖,并为“减少动态效果”系统设置提供兼容处理。
|
||||
- 修复前端每 10 秒轮询时,即使节点和状态完全没有变化,仍会重新排序、生成表格 HTML 和刷新页面的问题;相同快照现在会直接跳过渲染。
|
||||
- 修复节点列表已经按每页 50 条分页,但分页栏始终隐藏,导致第 51 条之后的节点无法查看的问题。
|
||||
- 修复多个轮询请求可能重叠、页面切到后台后仍持续刷新,以及日志窗口重复拉取和渲染过多内容造成的卡顿。
|
||||
- 修复连接、断开、单节点检测、收藏和设置操作可能被连续点击重复提交的问题,并为网络请求增加合理的超时与失败恢复。
|
||||
- 修复弹窗关闭、键盘焦点、Esc、Tab 循环和移动端滚动在不同浏览器中的不一致行为。
|
||||
- 修复登录和管理密码被意外删除首尾空格的问题;前端和 `ml password` 现在保持一致。
|
||||
- 修复 SOCKS5 客户端未提供“无需认证”方法时,服务端仍错误接受连接的问题。
|
||||
- 修复 `ml status` 一直显示旧版 `v2.0`,以及首次安装提示 5-30 秒但实际最多等待 90 秒的问题。
|
||||
- 修复正式版 GitHub Actions 发布脚本的 Shell 块问题。
|
||||
|
||||
## 兼容范围
|
||||
## 性能与体验优化
|
||||
|
||||
应用依赖 Linux TUN、OpenVPN、iptables 和策略路由,因此正式支持 Linux 主机。Docker 也必须运行在具备 `/dev/net/tun` 的 Linux 主机上,并授予 `NET_ADMIN` 与 `NET_RAW` 能力。
|
||||
- 节点接口继续移除不需要发送到浏览器的 OpenVPN 配置正文,约百个节点的响应保持在较小体积。
|
||||
- 节点请求自动合并;页面不可见时暂停普通轮询;节点表最多渲染 50 行,日志窗口最多渲染最近 300 行,服务端最多读取最近 500 条日志。
|
||||
- 国家多选、状态筛选、IP 类型筛选、收藏面板和分页均在前端即时响应,不需要重新请求节点数据。
|
||||
- 管理弹窗补齐标准对话框语义、可见焦点、焦点恢复和屏幕阅读器状态提示。
|
||||
- 登录、节点更新、代理检测、节点切换、断开、设置保存和日志接口统一加入超时控制,网络异常时不会无限等待。
|
||||
- 安装器生成的账号、密码和安全路径改用 Python `secrets` 加密安全随机源。
|
||||
|
||||
## 文档与功能更新
|
||||
|
||||
- Web 管理端版本标识和更新检测升级为完整的 `V2.1.1 正式版`,仍只跟踪 GitHub `main` 稳定分支和正式 Release。
|
||||
- README 重新整理快速安装、代理连接、VPS 推荐、项目推广和法律使用边界,删除重复的版本流水账与虚拟币赞助内容。
|
||||
- 保留简体中文主文档,并提供 English、日本語、한국어说明。
|
||||
- 正式版继续提供 HTTP 和 SOCKS5 两种代理协议,兼容不同 VPS 和客户端环境。
|
||||
|
||||
## 验证结果
|
||||
|
||||
- Ubuntu 22.04 x86_64 VPS 一键安装成功,服务保持运行且无异常重启。
|
||||
- HTTP 与 SOCKS5 代理出口验证通过。
|
||||
- 节点测试、切换、断开和恢复原节点的完整流程通过。
|
||||
- 本地 34 项单元测试、Python 编译、前端 JavaScript 语法、`install.sh` 语法和 Docker Compose 配置检查通过。
|
||||
- 99 个节点分页为 50/49,国家多选、空状态、收藏、设置、网关、日志和 Web 更新检测均通过浏览器交互测试。
|
||||
- 11.5 秒空闲轮询观测期间,相同节点快照产生 0 次 DOM 变更。
|
||||
- 390x844 手机视口和 1440x900 桌面视口没有页面级横向溢出或控件重叠。
|
||||
|
||||
## 下载与兼容架构
|
||||
|
||||
- GitHub Release 提供 `aimilivpn-v2.1.1-linux-source.tar.gz` 通用 Linux Python 源码包和 `sha256sums.txt`。
|
||||
- GHCR 发布 `2.1.1`、`2.1`、`latest` 三组镜像标签。
|
||||
- Docker 镜像在发布前分别对 `linux/amd64`、`linux/386`、`linux/arm64`、`linux/arm/v7` 执行构建和导入冒烟测试。
|
||||
- Docker 需要 Linux、`/dev/net/tun`、host 网络以及 `NET_ADMIN`、`NET_RAW` 能力。
|
||||
|
||||
## 更新方式
|
||||
|
||||
Python 源码安装:
|
||||
|
||||
```bash
|
||||
ml update
|
||||
```
|
||||
|
||||
Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
+2
-2
@@ -204,9 +204,9 @@ def get_app_version():
|
||||
try:
|
||||
with open(os.path.join(INSTALL_DIR, "VERSION"), "r", encoding="utf-8") as f:
|
||||
version = f.read().strip().lstrip("vV")
|
||||
return version or "2.1.0"
|
||||
return version or "2.1.1"
|
||||
except Exception:
|
||||
return "2.1.0"
|
||||
return "2.1.1"
|
||||
|
||||
def load_ui_cfg():
|
||||
import json
|
||||
|
||||
@@ -461,8 +461,8 @@ class ManagerLogicTests(unittest.TestCase):
|
||||
self.assertEqual(519, entries[-1]["index"])
|
||||
|
||||
def test_web_update_controls_only_expose_stable_main_channel(self) -> None:
|
||||
self.assertEqual("2.1.0", manager.APP_VERSION)
|
||||
self.assertEqual("V2.1 正式版", manager.APP_VERSION_LABEL)
|
||||
self.assertEqual("2.1.1", manager.APP_VERSION)
|
||||
self.assertEqual("V2.1.1 正式版", manager.APP_VERSION_LABEL)
|
||||
self.assertIn("检测更新", manager.INDEX_HTML)
|
||||
self.assertIn("/api/check_update", manager.INDEX_HTML)
|
||||
self.assertIn("/tree/main", manager.INDEX_HTML)
|
||||
@@ -490,6 +490,13 @@ class ManagerLogicTests(unittest.TestCase):
|
||||
self.assertIn("5-90 秒", install_text)
|
||||
self.assertIn('new_pwd = input("请输入新管理密码 (不能为空): ")', install_text)
|
||||
|
||||
def test_release_workflow_uses_full_patch_version(self) -> None:
|
||||
workflow_text = (manager.ROOT_DIR / ".github" / "workflows" / "release.yml").read_text(encoding="utf-8")
|
||||
|
||||
self.assertIn("default: v2.1.1", workflow_text)
|
||||
self.assertIn("AimiliVPN V$(tr -d '\\r\\n' < VERSION) 正式版", workflow_text)
|
||||
self.assertNotIn("cut -d. -f1,2 VERSION", workflow_text)
|
||||
|
||||
def test_latest_release_check_ignores_non_version_name_text(self) -> None:
|
||||
release = {
|
||||
"tag_name": "v2.2.0",
|
||||
@@ -513,8 +520,8 @@ class ManagerLogicTests(unittest.TestCase):
|
||||
|
||||
def test_latest_release_check_reports_current_formal_version(self) -> None:
|
||||
release = {
|
||||
"tag_name": "v2.1.0",
|
||||
"name": "AimiliVPN V2.1 正式版",
|
||||
"tag_name": "v2.1.1",
|
||||
"name": "AimiliVPN V2.1.1 正式版",
|
||||
"draft": False,
|
||||
"prerelease": False,
|
||||
}
|
||||
@@ -522,7 +529,7 @@ class ManagerLogicTests(unittest.TestCase):
|
||||
result = manager.check_latest_release()
|
||||
|
||||
self.assertFalse(result["update_available"])
|
||||
self.assertEqual("V2.1 正式版", result["current_version_label"])
|
||||
self.assertEqual("V2.1.1 正式版", result["current_version_label"])
|
||||
|
||||
def test_latest_release_check_reports_source_update_command(self) -> None:
|
||||
release = {"tag_name": "v2.2.0", "draft": False, "prerelease": False}
|
||||
|
||||
+5
-6
@@ -130,14 +130,13 @@ UPDATE_COMMAND = (
|
||||
)
|
||||
|
||||
ROOT_DIR = Path(sys.executable).resolve().parent if globals().get("__compiled__") else Path(__file__).resolve().parent
|
||||
DEFAULT_APP_VERSION = "2.1.0"
|
||||
DEFAULT_APP_VERSION = "2.1.1"
|
||||
try:
|
||||
_version_text = (ROOT_DIR / "VERSION").read_text(encoding="utf-8").strip()
|
||||
except OSError:
|
||||
_version_text = DEFAULT_APP_VERSION
|
||||
APP_VERSION = _version_text if re.fullmatch(r"\d+\.\d+(?:\.\d+)?", _version_text) else DEFAULT_APP_VERSION
|
||||
APP_VERSION_SHORT = ".".join(APP_VERSION.split(".")[:2])
|
||||
APP_VERSION_LABEL = f"V{APP_VERSION_SHORT} 正式版"
|
||||
APP_VERSION_LABEL = f"V{APP_VERSION} 正式版"
|
||||
GITHUB_REPOSITORY = "baoweise-bot/aimili-vpngate"
|
||||
GITHUB_REPOSITORY_URL = f"https://github.com/{GITHUB_REPOSITORY}"
|
||||
GITHUB_MAIN_BRANCH_URL = f"{GITHUB_REPOSITORY_URL}/tree/main"
|
||||
@@ -3986,12 +3985,12 @@ INDEX_HTML = r"""<!doctype html>
|
||||
<div class="dropdown">
|
||||
<button id="github_btn" class="btn-primary" type="button" aria-expanded="false" aria-controls="github_dropdown" style="background: rgba(255, 255, 255, 0.08); border: 1px solid var(--border-color); color: var(--text-primary);">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 16 16" style="vertical-align: middle; margin-right: 4px;"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
|
||||
<span id="github_version_label">V2.1 正式版</span>
|
||||
<span id="github_version_label">V2.1.1 正式版</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width:12px; height:12px; margin-left: 2px;" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" /></svg>
|
||||
</button>
|
||||
<div id="github_dropdown" class="dropdown-content github-dropdown">
|
||||
<div class="version-current">
|
||||
<div id="current_version_label" class="version-current-label">V2.1 正式版</div>
|
||||
<div id="current_version_label" class="version-current-label">V2.1.1 正式版</div>
|
||||
<div id="deployment_mode_label" class="version-current-meta">Python 源码部署 · 更新通道:main</div>
|
||||
</div>
|
||||
<button id="check_update_btn" type="button" onclick="checkForUpdate(event)">
|
||||
@@ -4816,7 +4815,7 @@ function stableSortNodes() {
|
||||
}
|
||||
|
||||
function render(){
|
||||
const versionLabel = state.app_version_label || "V2.1 正式版";
|
||||
const versionLabel = state.app_version_label || "V2.1.1 正式版";
|
||||
if ($("github_version_label")) $("github_version_label").textContent = versionLabel;
|
||||
if ($("current_version_label")) $("current_version_label").textContent = versionLabel;
|
||||
if ($("deployment_mode_label")) {
|
||||
|
||||
Reference in New Issue
Block a user