From 406f1a074f286256197c1e4a2829268f076f9fc2 Mon Sep 17 00:00:00 2001 From: Estrella Pan Date: Thu, 8 Oct 2026 16:04:48 +0200 Subject: [PATCH] =?UTF-8?q?fix(4.0):=20=E6=8F=92=E4=BB=B6=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E9=BB=98=E8=AE=A4=20min=5Fab=5Fversion=20=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=204.0.0-beta.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit semver 中 4.0.0-beta.N 低于 4.0.0,原默认值与文档命令会使全部 4.0 beta 用户无法安装目录插件。 --- backend/src/test/test_plugin_catalog.py | 10 +++++++--- docs/dev/plugins/signing.md | 6 +++--- docs/en/dev/plugins/signing.md | 6 +++--- docs/ja/dev/plugins/signing.md | 6 +++--- scripts/build_plugin_catalog.py | 10 +++++++--- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/backend/src/test/test_plugin_catalog.py b/backend/src/test/test_plugin_catalog.py index ccb4a2a2..4a80c004 100644 --- a/backend/src/test/test_plugin_catalog.py +++ b/backend/src/test/test_plugin_catalog.py @@ -241,7 +241,11 @@ class TestInstall: class TestReleaseScript: - async def test_catalog_built_by_release_script_installs(self, tmp_path, keypair): + # 默认 --min-ab 须放行 4.0 的 beta 宿主(semver 中 4.0.0-beta.N < 4.0.0) + @pytest.mark.parametrize("app_version", ["4.0.0-beta.1", "4.0.0"]) + async def test_catalog_built_by_release_script_installs( + self, tmp_path, keypair, app_version + ): script = ( Path(__file__).resolve().parents[3] / "scripts" / "build_plugin_catalog.py" ) @@ -258,7 +262,7 @@ class TestReleaseScript: archive.parent.mkdir() archive.write_bytes(build_zip(tmp_path)) - module.build([archive], tmp_path / "release", key_path, "4.0.0") + module.build([archive], tmp_path / "release", key_path) released = tmp_path / "release" @@ -270,7 +274,7 @@ class TestReleaseScript: root=tmp_path / "plugins", pubkey_path=pubkey_path, client=httpx.AsyncClient(transport=httpx.MockTransport(handler)), - app_version="4.0.0", + app_version=app_version, ) [entry] = await installer.fetch_catalog() assert entry["extension_points"] == ["rename_strategy"] diff --git a/docs/dev/plugins/signing.md b/docs/dev/plugins/signing.md index 23d1a17a..aeac4717 100644 --- a/docs/dev/plugins/signing.md +++ b/docs/dev/plugins/signing.md @@ -26,7 +26,7 @@ AB 从 GitHub release `plugins` 下载 `catalog.json`。目录包含: "kind": "plugin", "extension_points": ["notifier"], "sdk": ">=0.5,<1", - "min_ab_version": "4.0.0", + "min_ab_version": "4.0.0-beta.1", "description": "…", "asset": "ntfy-notifier-0.1.0.zip", "sha256": "…" @@ -75,11 +75,11 @@ API: ```bash uv run --no-project --with cryptography python scripts/build_plugin_catalog.py \ - --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0 \ + --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0-beta.1 \ --out release-assets dist/*.zip ``` - 脚本输出 `catalog.json`、各 zip 及其 `.sig`。 + 脚本输出 `catalog.json`、各 zip 及其 `.sig`。`--min-ab` 不要写成 `4.0.0`:按 semver,`4.0.0-beta.N` 低于 `4.0.0`,4.0 beta 用户将无法安装。 4. 维护者把整个目录上传到 release `plugins`(覆盖旧文件)。 用户端通过 `GET /api/v1/plugins/catalog` 看到新版本。 diff --git a/docs/en/dev/plugins/signing.md b/docs/en/dev/plugins/signing.md index 697b31e6..b3ff0bea 100644 --- a/docs/en/dev/plugins/signing.md +++ b/docs/en/dev/plugins/signing.md @@ -26,7 +26,7 @@ AB downloads `catalog.json` from the GitHub release `plugins`. The catalog conta "kind": "plugin", "extension_points": ["notifier"], "sdk": ">=0.5,<1", - "min_ab_version": "4.0.0", + "min_ab_version": "4.0.0-beta.1", "description": "…", "asset": "ntfy-notifier-0.1.0.zip", "sha256": "…" @@ -75,11 +75,11 @@ Only a maintainer who has the signing private key can publish the catalog. The s ```bash uv run --no-project --with cryptography python scripts/build_plugin_catalog.py \ - --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0 \ + --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0-beta.1 \ --out release-assets dist/*.zip ``` - The script writes `catalog.json`, the zips and their `.sig` files. + The script writes `catalog.json`, the zips and their `.sig` files. Do not set `--min-ab` to `4.0.0`: in semver, `4.0.0-beta.N` is lower than `4.0.0`, so 4.0 beta users cannot install the plugin. 4. The maintainer uploads the whole directory to the release `plugins` (and overwrites the old files). A user sees the new version through `GET /api/v1/plugins/catalog`. diff --git a/docs/ja/dev/plugins/signing.md b/docs/ja/dev/plugins/signing.md index 2eb95b98..f5ae7743 100644 --- a/docs/ja/dev/plugins/signing.md +++ b/docs/ja/dev/plugins/signing.md @@ -26,7 +26,7 @@ AB は GitHub release `plugins` から `catalog.json` をダウンロードし "kind": "plugin", "extension_points": ["notifier"], "sdk": ">=0.5,<1", - "min_ab_version": "4.0.0", + "min_ab_version": "4.0.0-beta.1", "description": "…", "asset": "ntfy-notifier-0.1.0.zip", "sha256": "…" @@ -75,11 +75,11 @@ API: ```bash uv run --no-project --with cryptography python scripts/build_plugin_catalog.py \ - --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0 \ + --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0-beta.1 \ --out release-assets dist/*.zip ``` - スクリプトは `catalog.json`、各 zip、およびその `.sig` を出力します。 + スクリプトは `catalog.json`、各 zip、およびその `.sig` を出力します。`--min-ab` に `4.0.0` を指定しないでください。semver では `4.0.0-beta.N` は `4.0.0` より低いため、4.0 beta のユーザーがインストールできなくなります。 4. メンテナーがディレクトリ全体を release `plugins` にアップロードします(古いファイルは上書きします)。 ユーザーは `GET /api/v1/plugins/catalog` で新しいバージョンを確認できます。 diff --git a/scripts/build_plugin_catalog.py b/scripts/build_plugin_catalog.py index 57329fb9..97d1bdad 100644 --- a/scripts/build_plugin_catalog.py +++ b/scripts/build_plugin_catalog.py @@ -3,7 +3,7 @@ 用法(需要更新签名私钥,见 CLAUDE.md 的发布说明):: uv run --no-project --with cryptography python scripts/build_plugin_catalog.py \ - --key ~/.autobangumi/update-signing-key.pem --min-ab 4.0.0 \ + --key ~/.autobangumi/update-signing-key.pem \ --out release-assets dist/*.zip 输入是 ``ab-plugin pack`` 打出的 zip。输出目录里有 ``catalog.json``、每个 zip 以及 @@ -24,6 +24,8 @@ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.serialization import load_pem_private_key CATALOG_SCHEMA = 2 +# semver 中 4.0.0-beta.N < 4.0.0,写 4.0.0 会把全部 4.0 beta 宿主挡在外面 +DEFAULT_MIN_AB = "4.0.0-beta.1" def _entry(archive: Path, min_ab: str) -> dict: @@ -48,7 +50,9 @@ def _sign(key: Ed25519PrivateKey, path: Path) -> None: Path(str(path) + ".sig").write_text(base64.b64encode(signature).decode() + "\n") -def build(archives: list[Path], out: Path, key_path: Path, min_ab: str) -> Path: +def build( + archives: list[Path], out: Path, key_path: Path, min_ab: str = DEFAULT_MIN_AB +) -> Path: key = load_pem_private_key(key_path.read_bytes(), password=None) if not isinstance(key, Ed25519PrivateKey): raise SystemExit("签名密钥必须是 ed25519") @@ -72,6 +76,6 @@ if __name__ == "__main__": parser.add_argument("archives", nargs="+", type=Path) parser.add_argument("--key", required=True, type=Path) parser.add_argument("--out", required=True, type=Path) - parser.add_argument("--min-ab", default="4.0.0") + parser.add_argument("--min-ab", default=DEFAULT_MIN_AB) args = parser.parse_args() print(build(args.archives, args.out, args.key, args.min_ab))