diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef31e9f..486a8be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,11 @@ -# vela-plugin 与 VelaShell.PluginSdk.Build 的日常验证。 +# vela-plugin 的日常验证。 # 发布不走这里(见 release.yml),但**发布会做的事这里全都做一遍** —— # 唯一差别是不推 nuget.org。 # +# 本仓库自 2026-09-11 起只产出一个包:VelaShell.PluginSdk.Build 搬去了 +# VelaShellLabs/velashell-plugin-sdk(它与契约同版本发布才对),端到端冒烟随它一起搬走, +# 打包器也在那边自带(VelaShell.PluginSdk.Packer)。本仓库因此不再有任何下游。 +# # 注意本仓库**不需要任何机密**:程序集不做强名称签名(那只开在 velashell-plugin-sdk # 那一支),推送用 OIDC。于是 fork PR 与主分支跑的是完全同一条路径,没有"拿不到密钥 # 就降级"的分支要维护。 @@ -49,9 +53,6 @@ jobs: # 那时它是 $null —— 而 `$null -ne 0` 为真,会把一次成功判成失败。 if ($LASTEXITCODE) { exit $LASTEXITCODE } - # 跨仓库的 Avalonia 版本锁核对(VELA1005 / VELA1006)就在这一步的构建里发生: - # VelaShell.PluginSdk 包把权威版本导出成 $(VelaSdkPinnedAvaloniaVersion), - # VelaShell.PluginSdk.Build 的 VerifyAvaloniaVersionPin 拿它跟本仓库的副本比。 - name: Test shell: pwsh run: | @@ -63,30 +64,13 @@ jobs: run: | $version = '${{ steps.version.outputs.version }}' New-Item -ItemType Directory -Force artifacts/nuget | Out-Null - # 顺序不能反:VelaShell.PluginSdk.Build 的 AddVelaCliToPackage 要去 - # src/VelaShell.Plugin.Cli/bin/Release/ 收打包器的产物。 - $projects = @( - 'src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj', - 'src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj' - ) - foreach ($project in $projects) { - dotnet pack $project -c Release -o artifacts/nuget -p:VelaToolsVersion=$version --nologo - if ($LASTEXITCODE -ne 0) { exit 1 } - } + dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget -p:VelaToolsVersion=$version --nologo + if ($LASTEXITCODE -ne 0) { exit 1 } Get-ChildItem artifacts/nuget | Select-Object -ExpandProperty Name - # 端到端冒烟:拿刚打出的包,站在插件作者的位置上走一遍 - # (最小插件工程 → 还原 → 构建 → 出 .vpx → 读回容器 → 查共享程序集有没有漏)。 - # 夹具在 tests/smoke/,细节见 scripts/Invoke-Smoke.ps1 的注释。 - # 这一步不是形式:插件工程是**仓库外环境**,仓库内的 Directory.Build.props 一条也 - # 吃不到,而历史上两个最难查的坑(CA2252 全线报错、AXAML 编译器到不了插件工程) - # 都只有在这个前提下才会显形。 - - name: Smoke test (plugin project -> build -> .vpx) - shell: pwsh - run: | - & ./scripts/Invoke-Smoke.ps1 -Feed ./artifacts/nuget -Version '${{ steps.version.outputs.version }}' - if ($LASTEXITCODE) { exit $LASTEXITCODE } - + # 注:插件工程的端到端冒烟(最小插件工程 → 构建 → 出 .vpx)不在这里跑了 —— + # 它验的是 VelaShell.PluginSdk.Build,那个包 2026-09-11 搬去了 velashell-plugin-sdk, + # 冒烟连同 tests/smoke/ 夹具一起跟了过去,那边也自带打包器。本仓库与它再无构建期关系。 - uses: actions/upload-artifact@v7 with: name: nuget-packages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11b2e12..5d75858 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,17 +1,20 @@ -# 插件工具链(CLI + 构建支持包)的发布流水线:在 GitHub 页面**发布 Release** 时自动触发。 +# vela-plugin 的发布流水线:在 GitHub 页面**发布 Release** 时自动触发。 # -# 一次发布产出两个 NuGet 包,共用 Release 标签里的那个版本号: +# 一次发布产出一个 NuGet 包,版本号取自 Release 标签: # # VelaShell.Plugin.Cli dotnet tool `vela-plugin` -# VelaShell.PluginSdk.Build 插件工程引用的那一个包(targets + 打包器 + 依赖锁) # -# 这两个**必须同版本发**:.Build 把 vela-plugin 的构建产物收进包的 tools/,它的 targets -# 直接调那个打包器的命令面(`validate` / `pack`)。命令行参数改了而 targets 没跟上, -# 现象是插件作者构建到一半 Exec 失败 —— 所以它俩是一个发布单元,拆库时刻意留在同仓库。 +# 2026-09-11 起 **VelaShell.PluginSdk.Build 不在本仓库发**:它搬去了 +# VelaShellLabs/velashell-plugin-sdk,在那边与契约包同版本、同一次发布。插件工程用的打包器 +# 也在那边自带(VelaShell.PluginSdk.Packer,与契约同仓库、同一次构建)。 # -# **另外三个包不在这里发**(2026-08-27 拆库起): -# VelaShell.PluginSdk / .Testing …… VelaShellLabs/velashell-plugin-sdk -# VelaShell.Plugin.Templates ……… VelaShellLabs/velashell-plugin-templates +# 于是本仓库**没有任何下游**:vela-plugin 是面向人的工具(商店、开发内环、签名、体检), +# 发不发版与插件作者能不能 `dotnet build -t:PackVpx` 出包毫无关系。两边都过同一个 +# VpxContainer(在 VelaShell.PluginSdk 里),包格式的一致性由类型保证,不靠版本号约定。 +# +# **其余的包不在这里发**: +# VelaShell.PluginSdk / .Testing / .Build …… VelaShellLabs/velashell-plugin-sdk +# VelaShell.Plugin.Templates ………………… VelaShellLabs/velashell-plugin-templates # 三个仓库各有各的版本号。本仓库发 1.5.3 不代表契约动了,也不要求模板跟着发。 # # 📌 版本号:**发版前在本地落好、随功能改动一起合进 main**。 @@ -23,14 +26,11 @@ # 下面的 Stamp 步骤只改 runner 上的工作区,**不回写仓库**:产物版本号因此永远等于 # Release 标签,与仓库里当时提交了什么无关。忘了第 ① 步的兜底是 CI 的版本同步体检。 # -# ⚠️ 想让插件作者吃到**新契约**,得另外抬两个 csproj 里 VelaShell.PluginSdk 的 -# PackageReference 版本(Set-Version.ps1 刻意不碰它;Dependabot 会替你提 PR)—— -# 那是一次独立的决定,不该被"发个补丁版"顺手带上。抬完 VerifyAvaloniaVersionPin -# 会在构建期核对 Avalonia 版本锁是否也要跟着动(VELA1006)。 -# -# ⚠️ 发完新版 .Build 之后,若希望 `dotnet new velaplugin` 生成的工程指向它, -# 要去 velashell-plugin-templates 抬 VelaBuildPackageVersion 再发一版模板。 -# 不做也不会坏 —— 新建的工程只是继续引用上一版 .Build 包,那是完全可用的。 +# ⚠️ 想让 vela-plugin 吃到**新契约**,得另外抬 src/VelaShell.Plugin.Cli 里 +# VelaShell.PluginSdk 的 PackageReference 版本(Set-Version.ps1 刻意不碰它; +# Dependabot 会替你提 PR)—— 那是一次独立的决定,不该被"发个补丁版"顺手带上。 +# 注意它管的只是**打包器自己**读清单与 .vpx 容器用的那份契约;插件作者的编译目标契约 +# 由 velashell-plugin-sdk 的 .Build 决定,与本仓库无关。 # # 推送用 **NuGet Trusted Publishing(OIDC)**,不存 API Key: # NuGet/login 拿本次运行的 GitHub OIDC 令牌去 nuget.org 换一把**短时效**的推送密钥, @@ -57,7 +57,7 @@ on: required: true type: string dryRun: - description: '只打包与冒烟,不推送 nuget.org' + description: '只打包,不推送 nuget.org' required: false default: false type: boolean @@ -105,7 +105,6 @@ jobs: if ($LASTEXITCODE) { exit $LASTEXITCODE } git --no-pager diff --stat - # 跨仓库的 Avalonia 版本锁核对(VELA1005 / VELA1006)就在这一步的构建里发生。 - name: Test shell: pwsh run: | @@ -117,26 +116,12 @@ jobs: run: | $version = '${{ steps.version.outputs.version }}' New-Item -ItemType Directory -Force artifacts/nuget | Out-Null - # 顺序不能反:VelaShell.PluginSdk.Build 的 AddVelaCliToPackage 要去 - # src/VelaShell.Plugin.Cli/bin/Release/ 收打包器的产物。 - $projects = @( - 'src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj', - 'src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj' - ) - foreach ($project in $projects) { - dotnet pack $project -c Release -o artifacts/nuget -p:VelaToolsVersion=$version --nologo - if ($LASTEXITCODE -ne 0) { exit 1 } - } + dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget -p:VelaToolsVersion=$version --nologo + if ($LASTEXITCODE -ne 0) { exit 1 } Get-ChildItem artifacts/nuget | Select-Object -ExpandProperty Name - # 端到端冒烟:完全站在插件作者的位置上 —— 从刚打出的包还原、构建、出 .vpx, - # 最后确认包能被容器读回来、共享程序集没漏进插件输出目录。任何一步失败都不该发出去。 - - name: Smoke test (plugin project -> build -> .vpx) - shell: pwsh - run: | - & ./scripts/Invoke-Smoke.ps1 -Feed ./artifacts/nuget -Version '${{ steps.version.outputs.version }}' - if ($LASTEXITCODE) { exit $LASTEXITCODE } - + # 注:插件工程的端到端冒烟随 VelaShell.PluginSdk.Build 搬去了 velashell-plugin-sdk, + # 那边自带打包器,与本仓库无关。 - uses: actions/upload-artifact@v7 with: name: nuget-packages diff --git a/AGENTS.md b/AGENTS.md index c93d105..7f572a3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,38 +37,42 @@ VelaShell 生态的**全部文档**集中在一个仓库: - **例外**:留在代码仓库里的少数几份文件不适用上述规则,因为它们服务的是「在这个仓库里写代码」 这件事,搬走只会离使用场景更远。各仓库的例外清单见下面第三节。 -## 三、本仓库:velashell-plugin-cli(命令行与构建支持包) +## 三、本仓库:velashell-plugin-cli(插件命令行工具) -产出 `VelaShell.Plugin.Cli`(dotnet tool `vela-plugin`)与 `VelaShell.PluginSdk.Build` -(插件工程**只需引用这一个包**)。两者**始终同版本发**:`.Build` 把 `vela-plugin` 的构建产物 -收进包的 `tools/`,它的 targets 直接调那个打包器的命令面,参数改了而 targets 没跟上, -现象是插件作者构建到一半 `Exec` 失败。 +产出**一个**包:`VelaShell.Plugin.Cli`(dotnet tool `vela-plugin`)。 + +`VelaShell.PluginSdk.Build` 已于 2026-09-11 搬去 `VelaShellLabs/velashell-plugin-sdk` +—— 它决定的是插件作者**编译时看到的那份契约**,所以属于契约仓库,在那边与契约同版本发布。 +端到端冒烟(`scripts/Invoke-Smoke.ps1` + `tests/smoke/`)随它一起搬走了。 + +### 本仓库没有下游 + +插件工程 `dotnet build -t:PackVpx` 用的**不是**这个工具:`.Build` 自带一个三条命令的打包器 +(那边的 `VelaShell.PluginSdk.Packer`)。两边都走 `VelaShell.PluginSdk` 里的同一个 +`VpxContainer`,包格式一致由类型保证,不靠版本号约定 —— 所以改 `vela-plugin` 的命令面 +不会波及任何别的仓库,也没有跨仓库的后续动作要做。 + +`vela-plugin` 自己的定位:面向人的完整工具(商店、开发内环、签名、体检)。 ### 构建与测试 ```bash dotnet build VelaShell.Plugin.Cli.slnx dotnet test VelaShell.Plugin.Cli.slnx -c Debug - -# 端到端冒烟:拿刚打出的包当插件作者走一遍 -dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget -dotnet pack src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj -c Release -o artifacts/nuget -pwsh scripts/Invoke-Smoke.ps1 -Feed ./artifacts/nuget -Version <版本> +dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget ``` -冒烟夹具在 `tests/smoke/`:一个手写的最小插件工程,刻意带两个空的 -`Directory.Build.props`/`.targets` 来切断向上查找 —— **插件工程是仓库外环境,仓库内的构建约定 -一条也吃不到**,冒烟的全部价值就在这里。改打包器或 targets 后必须跑它。 - -### 两个跨仓库旋钮(都不由 Set-Version.ps1 管) +### 唯一的跨仓库旋钮(不由 Set-Version.ps1 管) | 旋钮 | 在哪 | 抬它意味着 | | --- | --- | --- | -| `VelaShell.PluginSdk` 的 `PackageReference` | 两个 csproj,**必须同版本** | 插件作者的编译目标契约变新。只改了输出格式的补丁版不该顺手带上 | -| `VelaAvaloniaVersion` | `Directory.Build.props` | 权威在 sdk 仓库,这里只是副本。漂了报 `VELA1006` | +| `VelaShell.PluginSdk` 的 `PackageReference` | `src/VelaShell.Plugin.Cli` 的 csproj | **打包器自己**读清单与 `.vpx` 容器用的那份契约变新。只改了输出格式的补丁版不该顺手带上 | + +版本刻意写成**字面量**、不抽成 MSBuild 属性:`Version="$(...)"` 会让 Dependabot 与 +`dotnet add package` 认不出这条依赖。 -契约 SDK 的版本刻意写成**字面量**、不抽成 MSBuild 属性:`Version="$(...)"` 会让 -Dependabot 与 `dotnet add package` 认不出这条依赖。 +Avalonia 版本锁与它的构建期核对(`VELA1000` / `VELA1006`)在本仓库已不存在 —— +随 `.Build` 搬去了 sdk 仓库,权威值本来就在那里。 ### 发版脚本会写 velashell-docs diff --git a/Directory.Build.props b/Directory.Build.props index 5b49234..081f353 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,17 +14,22 @@ diff --git a/README.md b/README.md index b1e159b..8a9f542 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ -# VelaShell 插件工具链(CLI + 构建支持包) +# VelaShell 插件命令行工具 -[VelaShell](https://github.com/joesdu/VelaShell) 插件作者用的**工具**:命令行与 MSBuild 支持。 +[VelaShell](https://github.com/joesdu/VelaShell) 插件作者用的**命令行工具**。 | 包 | 内容 | | --- | --- | | [`VelaShell.Plugin.Cli`](https://www.nuget.org/packages/VelaShell.Plugin.Cli) | `vela-plugin`(dotnet tool):从插件商店装/升/卸插件、校验清单、打 `.vpx`、签名/验签、挂载到本机宿主调试 | -| [`VelaShell.PluginSdk.Build`](https://www.nuget.org/packages/VelaShell.PluginSdk.Build) | 插件工程**只需引用这一个包**:MSBuild targets + 随包分发的打包器 + 契约程序集 + Avalonia 版本锁 | + +> 写插件要引用的那个包是 [`VelaShell.PluginSdk.Build`](https://www.nuget.org/packages/VelaShell.PluginSdk.Build), +> 它在 [`velashell-plugin-sdk`](https://github.com/VelaShellLabs/velashell-plugin-sdk) +> (2026-09-11 从本仓库搬过去,与契约包同版本发布)。那个包**自带打包器**,所以插件工程 +> `dotnet build -t:PackVpx` 不必安装任何全局工具 —— 也就是说,它与本仓库无关。 ## 快速上手 @@ -25,14 +29,19 @@ vela-plugin update # 以后升级 写自己的插件:见 [开发指南](https://github.com/VelaShellLabs/velashell-docs/blob/main/zh/templates/dev-guide.md)。 -## 为什么这两个包在同一个仓库 +## `.Build` 为什么搬走了 + +`VelaShell.PluginSdk.Build` 决定的是**插件作者编译时看到的那份契约**,所以它属于契约仓库: +放在那里它用 `ProjectReference` 引契约、与契约同版本同一次发布,「.Build 引用的是哪一版 +SDK」这个旋钮连同它漂移的可能一并消失。2026-09-11 搬走的就是这个理由。 -`VelaShell.PluginSdk.Build` 把 `vela-plugin` 的构建产物**收进包的 `tools/`**,它的 targets -直接调那个打包器的命令面(`validate` / `pack`)。命令行参数改了而 targets 没跟上,现象是 -插件作者构建到一半 `Exec` 失败 —— 所以它俩是**一个发布单元**,始终同版本发。 +打包器跟着一起去了那边(`VelaShell.PluginSdk.Packer`,只有 `validate` / `pack` / `info` +三条命令)。这不是重复造轮子:`.vpx` 的定义 —— `VpxContainer` 与 `PluginManifestReader` —— +本来就在 `VelaShell.PluginSdk` 里,`vela-plugin` 也只是它的一个调用方。让 `.Build` 绕一趟 +本仓库,换来的只是一个要人盯着的跨仓库版本旋钮。 -拆库时也考虑过把 `.Build` 放进 sdk 仓库(名字看起来更像一家),但那会让依赖反向: -sdk 仓库要去引用 CLI 包,于是 SDK 发版被 CLI 卡住 —— 正是拆库要消掉的那种强一致。 +**于是本仓库没有下游。** `vela-plugin` 是面向人的完整工具(商店、开发内环、签名、体检), +发不发版与插件作者能不能出包毫无关系;两边都过同一个 `VpxContainer`,包格式一致由类型保证。 ## 插件生态的仓库分布 @@ -40,17 +49,22 @@ sdk 仓库要去引用 CLI 包,于是 SDK 发版被 CLI 卡住 —— 正是拆 | 仓库 | 产出 | 什么时候发 | | --- | --- | --- | -| [`velashell-plugin-sdk`](https://github.com/VelaShellLabs/velashell-plugin-sdk) | `VelaShell.PluginSdk`、`.Testing` | 契约有增删改时 | -| **本仓库** `velashell-plugin-cli` | `VelaShell.Plugin.Cli`、`VelaShell.PluginSdk.Build` | 工具/打包/MSBuild 逻辑变化时 | +| [`velashell-plugin-sdk`](https://github.com/VelaShellLabs/velashell-plugin-sdk) | `VelaShell.PluginSdk`、`.Testing`、`.Build` | 契约有增删改时,或 MSBuild/打包逻辑变化时 | +| **本仓库** `velashell-plugin-cli` | `VelaShell.Plugin.Cli` | 命令行工具本身变化时 | | [`velashell-plugin-templates`](https://github.com/VelaShellLabs/velashell-plugin-templates) | `VelaShell.Plugin.Templates` | 模板内容变化,或要把新建工程指到新版 Build 包时 | +每条依赖都是一条 NuGet **已发布包**的引用,版本写死: + 依赖方向是单向的,没有环: ``` -velashell-plugin-sdk 契约,无上游 - ↓ NuGet: VelaShell.PluginSdk ← 版本写在两个 csproj 的 PackageReference 上 -velashell-plugin-cli ← 本仓库 - ↓ NuGet: VelaShell.PluginSdk.Build ← 模板里那个 sdkVersion 默认值 +velashell-plugin-sdk 契约 + .Build + 打包器,无上游 + ↓ NuGet: VelaShell.PluginSdk ← 版本写在 src/VelaShell.Plugin.Cli 的 csproj 上 +velashell-plugin-cli ← 本仓库,vela-plugin + (没有下游 —— 谁都不引用它) + +velashell-plugin-sdk + ↓ NuGet: VelaShell.PluginSdk.Build ← 模板生成的工程里那一行 velashell-plugin-templates ``` @@ -59,40 +73,29 @@ velashell-plugin-templates [VelaShellLabs/velashell-docs](https://github.com/VelaShellLabs/velashell-docs)(**全部文档**, 2026-08-30 起各仓库的 `docs/` 都搬到了那里)。 -## 两个跨仓库旋钮 +## 唯一的跨仓库旋钮 -**都不由 `Set-Version.ps1` 管**——它们是需要想清楚的独立决定: +`src/VelaShell.Plugin.Cli` 里 `VelaShell.PluginSdk` 的 `PackageReference` —— +**不由 `Set-Version.ps1` 管**,它是一次需要想清楚的独立决定:抬它 = 打包器自己拿哪一版 +契约去读 `plugin.json` 与 `.vpx` 容器。发一个只改了输出格式的补丁版时不该顺手带上。 -| 旋钮 | 在哪 | 抬它意味着 | -| --- | --- | --- | -| `VelaShell.PluginSdk` 的 `PackageReference`(引用哪一版契约 SDK) | `src/VelaShell.Plugin.Cli` 与 `src/VelaShell.PluginSdk.Build` 两个 csproj,**必须同版本** | 插件作者的**编译目标契约**变新。发一个只改了输出格式的补丁版时不该顺手带上 | -| `VelaAvaloniaVersion`(锁给插件工程的 Avalonia 版本) | `Directory.Build.props` | 权威在 sdk 仓库,这里只是副本。改它必须跟着 SDK 走 | - -契约 SDK 的版本刻意写成**字面量**、不抽成 MSBuild 属性:`Version="$(...)"` 会让 -Dependabot 与 `dotnet add package` 认不出这条依赖,而这个包正是要靠它们来更新的。 +版本刻意写成**字面量**、不抽成 MSBuild 属性:`Version="$(...)"` 会让 Dependabot 与 +`dotnet add package` 认不出这条依赖,而这个包正是要靠它们来更新的。 -第二个有构建期硬核对:`VelaShell.PluginSdk` 包把权威值导出成 -`$(VelaSdkPinnedAvaloniaVersion)`,`VerifyAvaloniaVersionPin` 拿它跟本仓库的副本、 -以及包里给插件工程的默认值三者相比,漂了就报 `VELA1006`。 +> 插件作者的**编译目标**契约不在这里 —— 那由 sdk 仓库的 `VelaShell.PluginSdk.Build` +> 决定。Avalonia 版本锁同理:副本与它的构建期核对(`VELA1000` / `VELA1006`)都随 `.Build` +> 搬去了 sdk 仓库,权威值本来就在那里。 ## 在本仓库里开发 ```bash dotnet build VelaShell.Plugin.Cli.slnx dotnet test VelaShell.Plugin.Cli.slnx -c Debug - -# 端到端冒烟:拿刚打出的包当插件作者走一遍 -dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget -dotnet pack src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj -c Release -o artifacts/nuget -pwsh scripts/Invoke-Smoke.ps1 -Feed ./artifacts/nuget -Version 1.5.0 +dotnet pack src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj -c Release -o artifacts/nuget ``` -冒烟的夹具在 [`tests/smoke/`](tests/smoke/):一个手写的最小插件工程,与 `velaplugin-ui` -模板同形。它刻意带两个空的 `Directory.Build.props`/`.targets` 来切断向上查找 —— -**插件工程是仓库外环境,仓库内的构建约定一条也吃不到**,而这个冒烟的全部价值就在这里。 - -想验一版还没发布的契约 SDK:在 sdk 仓库 `dotnet pack -o <这里>/local-packages`, -再把两个 csproj 里 `VelaShell.PluginSdk` 的版本临时指过去(见 `nuget.config` 的注释)。 +插件工程的端到端冒烟(最小插件工程 → 构建 → 出 `.vpx`)随 `VelaShell.PluginSdk.Build` +搬去了 sdk 仓库(`scripts/Invoke-Smoke.ps1` + `tests/smoke/`),那边自带打包器,与本仓库无关。 本仓库**不做强名称签名**,因此不需要 `STRONG_NAME_KEY` —— 未签名程序集可以引用 已签名的,方向是对的。 diff --git a/VelaShell.Plugin.Cli.slnx b/VelaShell.Plugin.Cli.slnx index af814db..8eab619 100644 --- a/VelaShell.Plugin.Cli.slnx +++ b/VelaShell.Plugin.Cli.slnx @@ -23,7 +23,6 @@ - diff --git a/scripts/Invoke-Smoke.ps1 b/scripts/Invoke-Smoke.ps1 deleted file mode 100644 index 4243b27..0000000 --- a/scripts/Invoke-Smoke.ps1 +++ /dev/null @@ -1,129 +0,0 @@ -#Requires -Version 7.0 -<# -.SYNOPSIS - 端到端冒烟:拿刚打出来的包,站在**插件作者**的位置上走一遍。 - -.DESCRIPTION - 拆库(2026-08-27)之前这一步是"装模板 → dotnet new → 构建 → 出 .vpx"。模板搬去 - VelaShellLabs/velashell-plugin-templates 之后,本仓库不能再依赖那个包来验自己的包 - —— 否则模板仓库出问题会让本仓库的 CI 无端变红,而且发本仓库的包时还得先有模板包。 - - 所以夹具改成自带:tests/smoke/ 下是一个**手写的最小插件工程**,与 velaplugin-ui - 模板同形(命令 + 面板 + 编译期 AXAML)。本脚本把它复制到临时目录、把包版本填进去、 - 从给定的本地源还原,然后: - - 1. `dotnet build -t:PackVpx` —— 覆盖 targets 的全部四件事:共享程序集不落地、 - Avalonia 版本核对、清单编译期校验、一步出包; - 2. 确认 bin/vpx/ 下真的有 .vpx; - 3. 用 vela-plugin info 把容器读回来(魔数、摘要、清单); - 4. 确认插件输出目录里**没有**共享程序集 —— 出现了就说明 exclude=Runtime 的链路断了。 - - 夹具刻意放在临时目录而不是原地构建:tests/smoke/ 里那两个空的 - Directory.Build.props/.targets 已经切断了向上查找,但复制出去更贴近真实 - (插件作者的工程不在本仓库里)。 - -.PARAMETER Feed - 本地 NuGet 源目录,里面应有刚打出的 VelaShell.PluginSdk.Build.<版本>.nupkg - 与 VelaShell.Plugin.Cli.<版本>.nupkg。 - -.PARAMETER Version - 要验的 VelaShell.PluginSdk.Build 版本号。 - -.PARAMETER CliDll - 用来做第 3 步读回校验的 vela-plugin。默认取本仓库的 Release 构建产物。 - (第 1 步用的是**包里自带**的那份,由 targets 自己解析 —— 那一步才是真正在验打包器。) - -.PARAMETER WorkDirectory - 工作目录。默认取 RUNNER_TEMP(CI)或系统临时目录。 - -.EXAMPLE - pwsh scripts/Invoke-Smoke.ps1 -Feed ./artifacts/nuget -Version 1.5.0 -#> -[CmdletBinding()] -param( - [Parameter(Mandatory)] [string] $Feed, - [Parameter(Mandatory)] [string] $Version, - [string] $CliDll, - [string] $WorkDirectory -) - -$ErrorActionPreference = 'Stop' -Set-StrictMode -Version Latest - -$root = Split-Path -Parent $PSScriptRoot -$feedPath = (Resolve-Path $Feed).Path -$fixture = Join-Path $root 'tests/smoke' -if (-not (Test-Path $fixture)) { throw "冒烟夹具不存在:$fixture" } - -if (-not $CliDll) { - $CliDll = Join-Path $root 'src/VelaShell.Plugin.Cli/bin/Release/net11.0/VelaShell.Plugin.Cli.dll' -} -if (-not (Test-Path $CliDll)) { - throw "找不到 vela-plugin:$CliDll。先跑一次 ``dotnet build src/VelaShell.Plugin.Cli -c Release``,或用 -CliDll 指定。" -} - -if (-not $WorkDirectory) { - $WorkDirectory = Join-Path ($env:RUNNER_TEMP ?? [IO.Path]::GetTempPath()) 'vela-plugin-smoke' -} -if (Test-Path $WorkDirectory) { Remove-Item -Recurse -Force $WorkDirectory } -New-Item -ItemType Directory -Force $WorkDirectory | Out-Null - -Write-Host "== 冒烟:VelaShell.PluginSdk.Build $Version ==" -Write-Host " 源 $feedPath" -Write-Host " 工作区 $WorkDirectory" - -# ── 铺夹具 ────────────────────────────────────────────────────────────────── -Copy-Item -Recurse -Force (Join-Path $fixture '*') $WorkDirectory - -$csproj = Join-Path $WorkDirectory 'Smoke.csproj' -$text = [IO.File]::ReadAllText($csproj) -if ($text -notmatch 'VELA_BUILD_VERSION') { - throw "tests/smoke/Smoke.csproj 里找不到 VELA_BUILD_VERSION 占位符;夹具改过了?" -} -[IO.File]::WriteAllText($csproj, $text.Replace('VELA_BUILD_VERSION', $Version)) - -# 很关键:不清掉的话机器上已有的 nuget.org 缓存或别的源可能把**上一版** -# 同名包喂进来,冒烟就验不到刚打出的这一版了。nuget.org 仍要留着 —— Avalonia 从那来。 -@" - - - - - - - - -"@ | Set-Content (Join-Path $WorkDirectory 'nuget.config') - -Push-Location $WorkDirectory -try { - # ── 1. 构建 + 出包 ────────────────────────────────────────────────────── - dotnet build -c Release -t:PackVpx --nologo - if ($LASTEXITCODE -ne 0) { throw "插件工程构建失败(见上方输出)。" } - - # ── 2. 产物在不在 ─────────────────────────────────────────────────────── - $vpx = Get-ChildItem 'bin/vpx/*.vpx' -ErrorAction SilentlyContinue | Select-Object -First 1 - if (-not $vpx) { throw "PackVpx 没产出 .vpx。" } - Write-Host " 产物 $($vpx.Name)" - - # ── 3. 容器读得回来吗 ─────────────────────────────────────────────────── - dotnet $CliDll info $vpx.FullName - if ($LASTEXITCODE -ne 0) { throw "vela-plugin info 读不回刚打出的 .vpx。" } - - # ── 4. 共享程序集有没有漏进插件输出目录 ───────────────────────────────── - # 漏了就说明 exclude=Runtime 的链路断了。这不是"包大了一点"的问题: - # 装载器一律让这些程序集回落到宿主那份,插件目录里那些副本只会误导人, - # 让人以为版本是自己带的那份说了算。 - $leaked = Get-ChildItem 'bin/Release/net11.0' -Filter '*.dll' | - Where-Object { $_.Name -like 'Avalonia*' -or $_.Name -eq 'VelaShell.PluginSdk.dll' } - if ($leaked) { - throw "共享程序集漏进了插件输出目录:$($leaked.Name -join ', ')" - } - - Write-Host "== 冒烟通过 ==" -} -finally { - Pop-Location -} - -exit 0 diff --git a/scripts/Set-Version.ps1 b/scripts/Set-Version.ps1 index 2fc2992..3428c7f 100644 --- a/scripts/Set-Version.ps1 +++ b/scripts/Set-Version.ps1 @@ -4,14 +4,16 @@ 把工具链版本号写进本仓库里所有需要它的地方。 .DESCRIPTION - 本仓库产出两个**同版本发布**的包(理由见 Directory.Build.props 的注释): + 本仓库产出一个包: VelaShell.Plugin.Cli dotnet tool `vela-plugin` - VelaShell.PluginSdk.Build 插件工程引用的那一个包 + + (VelaShell.PluginSdk.Build 已于 2026-09-11 搬去 VelaShellLabs/velashell-plugin-sdk, + 在那边与契约包同版本发布。理由见 Directory.Build.props 的注释。) 落点三处: - Directory.Build.props —— 两个包的版本 + Directory.Build.props —— 包版本的默认值 zh/cli/cli.md 版本横幅 ┐ 这两处在 velashell-docs 仓库, en/cli/cli.md version banner ┘ 是**可选**落点,见 -DocsRoot @@ -19,11 +21,11 @@ 2026-08-30 全部文档搬到 VelaShellLabs/velashell-docs 之后,它们不在本仓库的 checkout 里,所以找不到就跳过。 - **注意本脚本不碰 VelaShell.PluginSdk 的引用版本。** 那是"本仓库引用哪一版契约 SDK", - 与"本仓库自己发什么版本"是两件事 —— 拆库(2026-08-27)之后正是要让它们分开: - 发一个只改了 vela-plugin 输出格式的补丁版,不该顺手把插件作者的编译目标契约也换掉。 - 要抬契约版本就直接改两个 csproj 里的 PackageReference(或合掉 Dependabot 的 PR), - 那是一次独立的、需要想清楚的决定。 + **注意本脚本不碰 VelaShell.PluginSdk 的引用版本。** 那是"打包器自己拿哪一版契约去读 + 清单与 .vpx 容器",与"本仓库自己发什么版本"是两件事 —— 拆库(2026-08-27)之后正是要让 + 它们分开。要抬就直接改 src/VelaShell.Plugin.Cli 的 PackageReference(或合掉 Dependabot + 的 PR),那是一次独立的、需要想清楚的决定。 + (插件作者的**编译目标**契约与本仓库无关,由 velashell-plugin-sdk 的 .Build 决定。) **不在本仓库的落点**(各自由所在仓库的同名脚本管): · VelaPluginApi.SdkVersion / apiLevel 纪律 ……… velashell-plugin-sdk @@ -31,10 +33,9 @@ · velashell-docs 里 zh|en/templates/dev-guide.md 的 PackageReference 片段 … velashell-plugin-templates - ⚠️ 有一条跨仓库的**手工**后续动作:本仓库发了新版 VelaShell.PluginSdk.Build 之后, - 若希望 `dotnet new velaplugin` 生成的工程指向新版,要去 templates 仓库把 - VelaBuildPackageVersion 抬上来再发一版模板。不做也不会坏 —— 新建的工程只是 - 继续引用上一版 .Build 包,那是完全可用的。 + 本仓库**没有下游**:插件工程出包用的打包器由 velashell-plugin-sdk 的 + VelaShell.PluginSdk.Build 自带,不是这个工具。所以发版不需要通知谁、也没有跨仓库的 + 后续动作要做。 发版流水线在解析出 Release 标签之后**第一件事**也会跑本脚本 (见 .github/workflows/release.yml),因此产物永远与标签一致。它只改 runner 上的 diff --git a/src/VelaShell.Plugin.Cli/README.md b/src/VelaShell.Plugin.Cli/README.md index ade6e9f..a9182c5 100644 --- a/src/VelaShell.Plugin.Cli/README.md +++ b/src/VelaShell.Plugin.Cli/README.md @@ -63,9 +63,9 @@ vela-plugin dev init # 生成 IDE 启动配置(读 ~/.velashell/host.json > 安装收据**做事后防篡改(密钥在宿主进程里,CLI 造不出来);作为交换,能在装之前做完的检查 > 命令行一条不少。要那层事后保护就走管理页。 -打包不必装这个工具:`VelaShell.PluginSdk.Build` 包内已带同一份可执行体, -插件工程 `dotnet build -t:PackVpx` 直接出包。装全局工具是为了开发内环、体检、 -签名与包检查。 +打包不必装这个工具:`VelaShell.PluginSdk.Build` 包内自带一个打包器,插件工程 +`dotnet build -t:PackVpx` 直接出包(两边走同一套 `.vpx` 容器实现,包格式完全一致)。 +装全局工具是为了开发内环、体检、签名与包检查。 - 命令行手册: - 插件开发指南: diff --git a/src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj b/src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj index bde3c49..67e59bc 100644 --- a/src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj +++ b/src/VelaShell.Plugin.Cli/VelaShell.Plugin.Cli.csproj @@ -8,8 +8,10 @@ velashell;plugin;cli;dotnet-tool;vpx + 注:插件工程 `dotnet build -t:PackVpx` 用的**不是**这个工具 —— VelaShell.PluginSdk.Build + 自带一个只有三条命令的打包器(velashell-plugin-sdk 的 VelaShell.PluginSdk.Packer)。 + 两边都过 VelaShell.PluginSdk 里的同一个 VpxContainer,所以包格式天然一致; + 装这个全局工具是为了商店、开发内环、签名与包检查。 --> true vela-plugin diff --git a/src/VelaShell.PluginSdk.Build/README.md b/src/VelaShell.PluginSdk.Build/README.md deleted file mode 100644 index 4b956c0..0000000 --- a/src/VelaShell.PluginSdk.Build/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# VelaShell.PluginSdk.Build - -VelaShell 插件工程唯一需要引用的包。引一个,下面这些全都到位: - -```xml - -``` - -| 它做了什么 | 为什么 | -| --- | --- | -| 传递引入 `VelaShell.PluginSdk`(契约)与 **与宿主版本一致的 Avalonia**,均为编译期引用 | 装载器强制插件与宿主共享这两类程序集;版本不一致会在用户机器上才炸 | -| `EnableDynamicLoading=true`、`plugin.json` 进输出目录 | 插件是被动态装载的组件,ALC 靠 `deps.json` 解析自带依赖 | -| 共享程序集的运行时资产不落插件目录 | 放进去也不会被加载,只是撑大包体 | -| Avalonia 版本冲突从警告升为错误(NU1608/NU1605) | 版本漂移必须在构建期就红,而不是装机后才现形 | -| 构建后按宿主同一套规则校验 `plugin.json` | 杜绝"本机构建过、宿主装不上" | -| `dotnet build -t:PackVpx` 一步出 `.vpx` | 打包器随包分发,不必安装任何全局工具 | - -## 出包 - -```bash -dotnet build -c Release -t:PackVpx -# → bin/vpx/<插件id>-<版本>.vpx - -# 带签名(密钥用 `vela-plugin keygen` 生成,不要提交进仓库) -dotnet build -c Release -t:PackVpx -p:VelaSigningKey=/path/to/key.pem -``` - -## 可调属性 - -| 属性 | 默认 | 说明 | -| --- | --- | --- | -| `VelaPluginManifest` | `$(MSBuildProjectDirectory)\plugin.json` | 清单路径 | -| `VelaVpxOutputDirectory` | `bin\vpx\` | `.vpx` 产物目录 | -| `VelaSigningKey` | 空 | 打包时用的 PEM 私钥 | -| `VelaPackMask` | `true` | 是否对载荷做掩码变换 | -| `VelaValidateManifestOnBuild` | `true` | 构建后是否校验清单 | -| `VelaSkipAvaloniaVersionCheck` | `false` | 跳过 Avalonia 版本一致性检查 | - -完整开发指南: diff --git a/src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj b/src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj deleted file mode 100644 index 72c6ee9..0000000 --- a/src/VelaShell.PluginSdk.Build/VelaShell.PluginSdk.Build.csproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - VelaShell.PluginSdk.Build - VelaShell 插件工程的构建支持包:一次引用即得到契约程序集、与宿主版本一致的 Avalonia、共享程序集不落地的处理、清单编译期校验,以及 `dotnet build -t:PackVpx` 一步出 .vpx 包。插件工程只需引用本包。 - velashell;plugin;msbuild;vpx;sdk - - - false - - false - false - false - - $(NoWarn);NU5128 - $(TargetsForTfmSpecificContentInPackage);AddVelaCliToPackage - - - - - - - - - compile; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - <_VelaAvaloniaPin>@(PackageReference->WithMetadataValue('Identity','Avalonia')->'%(Version)') - <_VelaAvaloniaPin>$(_VelaAvaloniaPin.Replace('[','').Replace(']','')) - - - - - - - - - - - - - - - - - <_VelaCliOutputDir>$(MSBuildThisFileDirectory)..\VelaShell.Plugin.Cli\bin\$(Configuration)\$(TargetFramework)\ - - - <_VelaCliFile Include="$(_VelaCliOutputDir)*.dll;$(_VelaCliOutputDir)*.json" /> - - - - - - diff --git a/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.props b/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.props deleted file mode 100644 index 4ac47ec..0000000 --- a/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.props +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - true - - - true - - - $(MSBuildProjectDirectory)\plugin.json - - - 12.1.2 - - - $(WarningsAsErrors);NU1608;NU1605 - - - true - - - true - - - - - - - - diff --git a/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.targets b/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.targets deleted file mode 100644 index 2d8e9b1..0000000 --- a/src/VelaShell.PluginSdk.Build/build/VelaShell.PluginSdk.Build.targets +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - $(MSBuildThisFileDirectory)..\tools\net11.0\VelaShell.Plugin.Cli.dll - $(MSBuildProjectDirectory)\bin\vpx\ - - - - - - - - runtime - - - - - - - - - - - - - - - <_VelaAvaloniaRef Include="@(ReferencePath)" Condition="'%(ReferencePath.NuGetPackageId)' == 'Avalonia'" /> - - - - - - - - - - - - - - - - <_VelaPackArgs>pack "$(TargetDir.TrimEnd('\'))" --output "$(VelaVpxOutputDirectory.TrimEnd('\'))" - <_VelaPackArgs Condition="'$(VelaPackMask)' != 'true'">$(_VelaPackArgs) --no-mask - <_VelaPackArgs Condition="'$(VelaSigningKey)' != ''">$(_VelaPackArgs) --key "$(VelaSigningKey)" - - - - - diff --git a/tests/smoke/DemoPanel.axaml b/tests/smoke/DemoPanel.axaml deleted file mode 100644 index 9f1ac00..0000000 --- a/tests/smoke/DemoPanel.axaml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - -