feat: implement Deploy a Package for Tentacle and SSH
摘要
实现 Deploy a Package(Squid.TentaclePackage)端到端能力,覆盖 Tentacle / SSH / Windows 安装路径、配置改写、安装策略、归档 Feed,以及 PR review 收口修复。
包身份与获取
- 统一包身份:
PackageId作为 action-levelPackageReferenceName;包哈希改为 SHA-256 - 归档源 Feed 支持(NuGet / GitHub / HTTP 等);拒绝 Docker / Helm 容器图表源
-
Identity ≠ path segment:外部
PackageId/Version保留原值,路径段使用稳定编码(安全字符原值,否则prefix--+ SHA-256 前 12 hex),支持 GitHubowner/repo - NuGet Feed URI 归一化(剥离
/v3service-index,修正 nuget.org 下载地址) - 获取失败立即终止部署(不再继续空包安装)
-
服务端 zip-slip / plain tar 安全检查:
PackageArchiveSafety在 package acquisition 阶段 fail-closed;plain tar 不再吞掉RejectIfUnsafe - 仅对归档型 action 注入
Acquire Packages;K8s 容器选包不再走 archive acquisition - Create Release 校验:
PackageReferenceName必填、FeedId > 0;拒绝空白版本
Intent / Handler / 渲染
-
DeployPackageIntent/ 安装路径规划 /DeployPackageActionHandler - Tentacle 原始归档渲染 + Calamari bootstrap(不重打包 YAML)
- SSH 持久化安装:缓存、版本目录、Bash PreDeploy / PostDeploy 约定
- SSH 使用真实归档名 / 扩展名,并对齐本地获取与远端缓存路径
- 动作属性先变量展开再提升到 deployment variables,避免
#{tokens}泄漏到 agent
安装策略与配置改写
- 安装策略:skip / purge / retention / current pointer / rollback
- Rollback 默认 false;显式 True 覆盖 PreDeploy 和 PostDeploy;Tentacle/SSH 语义一致
- 安装成功后再跑 package retention;回滚 restore 失败时保留备份
- Calamari 配置改写管线:substitute / transforms / configuration variables / structured config
- SSH 对 canonical rewrite keys fail-closed(含
Squid.Action.JsonConfigVariables.*),不静默 no-op - SSH zip-slip 防护:服务端先验 + extract 前 list entry;兼容 Info-ZIP 与 BusyBox
步骤控制
- 步骤超时按秒解析(兼容 TimeSpan / 分钟输入)
- 动作执行支持重试策略(
RetriesEnabled/RetriesCount)
PR review 收口(本轮)
- 删除源码字符串断言测试,改为真实 service/phase 行为测试
- Deploy Package E2E 拆分 Smoke / Full;PR 仅跑 smoke,nightly/full 保留完整矩阵
- 收敛重复策略 E2E,Unit/Calamari 承担策略矩阵
- Linux smoke / full workflow 显式构建
squid-calamari,避免 bootstrap 缺二进制
Closes #451 (closed)
代码量(相对 origin/main,HEAD=09f6a28d)
| 范围 | 文件 | 行变更(+/-) |
|---|---|---|
| 全分支 | 107 | +10896 / -285 |
源码 src/**
|
48 | +2760 / -151 |
测试 tests/**
|
53 | +8064 / -118 |
CI .github/**
|
6 | +72 / -16 |
统计命令:
git diff --shortstat origin/main...HEAD/src/tests/.github相对收口前约
+14551 / -278,净新增约下降 25%+(主要来自重复 E2E 收敛,不是删唯一边界)。
补充(Deploy Package 相关文件体量,按路径/符号关键字统计当前 HEAD 行数):
- 相关源码约 28 个文件、3486 行
- 相关测试约 34 个文件、8801 行、约 235 个
[Fact]/[Theory] - tests/src 行数比约 2.53
测试分层
| 层级 | 应验证 | 不应重复验证 | PR 是否默认跑 |
|---|---|---|---|
| Unit | path encoding、wire key、archive safety、renderer/script 分支、Acquire/Release 行为 | 真实进程/网络/agent | 是(Tests workflow) |
| Calamari | extract/rewrite/commit/rollback/retention 文件系统策略矩阵 | server pipeline、Halibut | 是;PR 排除 DeployPackageFull 大矩阵,保留 4 个 smoke |
| Pipeline contract E2E | Release → acquisition → intent → renderer → task state | 每个平台全部安装策略 | 是(K8s Pipeline,仅 smoke;full 走完整 filter) |
| Real transport E2E | payload/transfer/shell/agent bootstrap 边界 | coordinator 已覆盖的策略组合 | 是(Linux/Windows smoke) |
| Mixed / multi-target | transport 协作、选择、失败传播 | 单 target happy path | 否(默认 full) |
PR Smoke 必须保留
- Web:model round-trip、package search string contract、manual package ID、Release payload feedId
- Core unit:GitHub identity encoding、canonical JSON SSH fail-closed、plain tar hostile entry、rollback script branch
- Calamari:1 happy + 1 rewrite composition + 1 rollback + 1 purge/preserve
- Tentacle pipeline:Polling happy + Listening happy
- SSH:happy + hostile archive rejection + canonical rewrite fail-closed
- Linux real agent:production bootstrap happy(Listening + Polling)
- Windows real agent:production bootstrap happy(Listening + Polling)
- Mixed:不进默认 PR smoke
Category 与 workflow
- 精确类别:
DeployPackageSmoke/Full、DeployPackageLinuxSmoke/Full、DeployPackageWindowsSmoke/Full、DeployPackageWindowsHostSmoke/Full -
pull_request默认只跑*Smoke - nightly/manual / full workflow 跑
*Smoke|*Full -
workflow_dispatch保留 filter override - path detection 覆盖 production Deploy Package 路径,不只依赖测试文件变更
当前 Deploy Package 相关方法分层约:
- Smoke:14
- Full:58
三平台覆盖(收口后)
| 平台 / 层 | 说明 |
|---|---|
| Linux agent | bootstrap Listening/Polling smoke;缺失 Calamari / 并发 ticket 等进 full |
| Windows agent / host | bootstrap smoke;PowerShell convention 与 host rewrite 边界进 full |
| SSH | happy + hostile/fail-closed 边界;策略细分矩阵下沉到 unit/Calamari |
| Pipeline / mixed | Polling/Listening happy 进 smoke;multi-target / mixed 进 full |
CI(tip 09f6a28d)
全部关键检查已通过:
-
Tests(Unit / Integration / Tentacle / Calamari) -
Tentacle Linux Smoke E2E -
Tentacle Windows Smoke E2E -
K8s Pipeline E2E
Web UI「Deploy a Package → Windows Tentacle」主路径与多场景已验收通过。
Windows 环境修复后复测:
-
0.3.0-win-retest/ Deploy#48:Acme.WinWeb@1.0.0→ Success onreal windows -
0.3.1-win-v101/ Deploy#49:Acme.WinWeb@1.0.1→ Success onreal windows - 安装目录:
C:\apps\squid-pw-ui\happy - 日志含 PreDeploy/PostDeploy 与
DeployPackage: installed to ... - 本机已确认 marker=
windows-ui-package-1.0.1,pre/post 脚本产物存在
关联前端
- SquidWeb#60:Deploy a Package step editor + package search contract + 编辑器职责拆分
测试计划
-
定向 Unit:DeployPackage / path encoding / archive safety / SSH renderer / rollback -
定向 Calamari:coordinator / config rewrite / deploy package -
PR smoke CI:Linux / Windows / Tests / K8s -
Nightly full matrix 持续观察