From a722d19cd95950af8ee128162c963935aad4f1cf Mon Sep 17 00:00:00 2001 From: k2safe Date: Sun, 20 Sep 2026 00:32:04 +0800 Subject: [PATCH] feat: add sdk isolation release gate --- Makefile | 5 +++- README.md | 2 ++ docs/08-development-plan.md | 2 +- docs/reports/phase-7-sdk-release.md | 27 ++++++++++++++++++++ docs/sdk/README.md | 2 ++ docs/sdk/release.md | 38 +++++++++++++++++++++++++++++ scripts/test-sdk-isolation.sh | 34 ++++++++++++++++++++++++++ 7 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 docs/reports/phase-7-sdk-release.md create mode 100644 docs/sdk/release.md create mode 100755 scripts/test-sdk-isolation.sh diff --git a/Makefile b/Makefile index 34bb203..7fcc38a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ GO ?= go -.PHONY: fmt test vet build integration +.PHONY: fmt test vet build integration sdk-check fmt: $(GO) fmt ./... cd sdk/go && $(GO) fmt ./... @@ -28,3 +28,6 @@ build: integration: ./scripts/test-mysql.sh + +sdk-check: + ./scripts/test-sdk-isolation.sh diff --git a/README.md b/README.md index cf5aa13..c7be092 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ make integration 受理层负载采样工具见 [有界受理负载工具](docs/api/load.md),只允许在隔离命名空间或一次性数据库中运行;它不自动重试、不启动 Worker,也不提供生产容量承诺。 +SDK 独立发布门禁使用 `make sdk-check`,在 `GOWORK=off` 下检查完整依赖图,并运行 SDK 的竞态测试、vet 和全包构建;规则和接入边界见 [SDK 发布门禁](docs/sdk/release.md)。 + 修改已应用迁移时会触发校验和拒绝;新增结构使用新的前向迁移。初始结构尚未部署生产。 ## 文档入口 diff --git a/docs/08-development-plan.md b/docs/08-development-plan.md index fc67181..5e7168e 100644 --- a/docs/08-development-plan.md +++ b/docs/08-development-plan.md @@ -31,7 +31,7 @@ | P4 Weave 主流程 | SDK 定义构建与发布校验、实例、顺序/分支/结构化并行汇合、信号/定时等待、版本绑定 | 重启接续、早到/重复信号、并行竞争、内部事件重放、发布版本兼容;端到端通用流程 | 已完成平台功能阶段验收:[原功能及W01–W17逐项核对](reports/phase-4-5.md)、[版本/暂停/全停回归](reports/phase-4-5-races.md)、[提交故障边界](reports/phase-6-fault-boundaries.md)。研发发布、固定版本、顺序/分支/有限并行、信号/时间等待、公共API/SDK及可运行示例均已交付;生产拓扑与发布兼容继续P6/P7 | | P5 Weave 恢复与查询 | 有界查询、暂停继续、取消、人工核查恢复、控制门控与审计 | 轮次与尝试独立预算;暂停/开始/回执/超时竞争;恢复保留预算;未知结果不盲目重复 | 已完成平台功能阶段验收:[原功能核对](reports/phase-4-5.md)。有界查询、独立预算、暂停继续/取消、六类恢复、历史/筛选/事件/来源与SDK场景均已交付;真实竞争、COMMIT断线及进程全停保留原身份、截止和预算。运维、容量与首版发布继续P6/P7 | | P6 生产验证与运维 | 完整监控、凭据轮换、备份恢复、滚动升级、运行手册、可复现负载和故障工具 | 对照生产验收清单执行,报告环境/指标/遗留项;容量、RPO/RTO 按真实拓扑验证 | 进行中;已补[精确故障边界](reports/phase-6-fault-boundaries.md)和[进程观测](reports/phase-6-observability.md);继续业务积压/阶段延迟、凭据轮换及其余生产门槛 | -| P7 首版交付核对 | SDK 兼容与发布准备、完整 API 手册、场景示例、全量回归及交付清单 | 新接入者按文档跑通全部示例;所有首版能力可追溯到实现与测试;报告实际生产边界 | 进行中;已补[通用文件转换示例](reports/phase-7-file-conversion.md),仍需 SDK 发布兼容、全量资源充足回归和交付清单 | +| P7 首版交付核对 | SDK 兼容与发布准备、完整 API 手册、场景示例、全量回归及交付清单 | 新接入者按文档跑通全部示例;所有首版能力可追溯到实现与测试;报告实际生产边界 | 进行中;已补[通用文件转换示例](reports/phase-7-file-conversion.md)和[SDK独立发布门禁](reports/phase-7-sdk-release.md),仍需协议兼容矩阵、全量资源充足回归和交付清单 | SDK、文档与示例随 P1–P5 同步开发,P7 是全量核对,不是最后才开始补文档。 diff --git a/docs/reports/phase-7-sdk-release.md b/docs/reports/phase-7-sdk-release.md new file mode 100644 index 0000000..7f31912 --- /dev/null +++ b/docs/reports/phase-7-sdk-release.md @@ -0,0 +1,27 @@ +# P7:SDK 独立发布门禁 + +验证日期:2026-09-20。本批为 SDK 发布准备增加独立 module 门禁,确保业务项目不会隐式依赖 Orbit 服务端模型、迁移或 MySQL。 + +## 门禁内容 + +[`scripts/test-sdk-isolation.sh`](../../scripts/test-sdk-isolation.sh) 在 SDK 目录强制 `GOWORK=off`,检查 go.mod 和完整依赖图,拒绝服务端内部包、平台模型、Pulse/Weave 包及 MySQL 驱动,然后运行: + +- `go test -race ./...` +- `go vet ./...` +- `go build ./...` + +门禁不发布模块、不生成 replace 路径,也不把 API 兼容性结论扩大到未执行的旧/新版本组合。 + +## 实际结果 + +在 Docker Go 1.25 临时 modfile 环境(仓库声明版本为 Go 1.27.1)执行门禁,退出码为 0: + +``@@BT@json +{"sdk_module":"git.yuntuo.hk/k2safe/orbit/sdk/go","independent":true,"package_count":27,"forbidden_dependencies":0} +``@@BT@ + +该轮覆盖 SDK 核心、Worker/事件客户端、流程/任务 API、负载工具和全部可运行示例;新增文件转换示例的单元测试也通过。文档本地链接、shell 语法和 `git diff --check` 同步通过。 + +## 发布边界 + +SDK 当前仍未发布正式版本标签。正式候选还需在资源充足环境用 Go 1.27.1 完成标准全量回归,建立旧 SDK/新服务端、新 SDK/旧服务端的协议兼容矩阵,并在干净 checkout 中验证版本标签、校验和与业务项目 `go mod tidy`。独立门禁不能证明外部业务幂等、TLS、凭据托管或生产容量。 diff --git a/docs/sdk/README.md b/docs/sdk/README.md index e6f3f14..98f2e5e 100644 --- a/docs/sdk/README.md +++ b/docs/sdk/README.md @@ -4,6 +4,8 @@ module:`git.yuntuo.hk/k2safe/orbit/sdk/go`。SDK 使用独立 go.mod,依赖 Go 标准库与 `github.com/coder/websocket v1.8.15`,不引用服务端模型或数据库实现。 +发布候选先执行 [SDK 独立发布门禁](release.md),确认 `GOWORK=off` 下依赖图、竞态测试、vet 和全包构建均通过;门禁不替代协议兼容矩阵或业务副作用回归。 + 任务相对延迟使用SubmitTaskRequest.DelayMS,由数据库首次受理时间计算,原键重报不重新计时;[完整延迟示例](../examples/delayed-task.md)包含Worker执行和历史核对。非零DelayMS不能与AvailableAt同用,旧服务须先升级。 [流程历史查询](../api/workflow-history.md)已提供激活/轮次/信号有界分页、历史等待与预算详情及显式权限的信号操作审计;当前视图与指定历史激活分开。 diff --git a/docs/sdk/release.md b/docs/sdk/release.md new file mode 100644 index 0000000..aca385b --- /dev/null +++ b/docs/sdk/release.md @@ -0,0 +1,38 @@ +# SDK 独立发布门禁 + +SDK 位于独立 Go module `git.yuntuo.hk/k2safe/orbit/sdk/go`。它只能依赖 Go 标准库和显式锁定的 WebSocket 客户端,不引用 Orbit 服务端模型、存储实现、迁移代码或 MySQL 驱动。业务项目通过 SDK 接入,不需要把服务端仓库加入自己的 `go.mod`。 + +## 发布前检查 + +在仓库根目录执行: + +``@@BT@sh +GO=/path/to/go \ +sh scripts/test-sdk-isolation.sh +``@@BT@ + +门禁会强制 `GOWORK=off`,检查 `go.mod` 和完整依赖图,然后运行: + +- `go test -race ./...` +- `go vet ./...` +- `go build ./...` + +成功输出示例: + +``@@BT@json +{"sdk_module":"git.yuntuo.hk/k2safe/orbit/sdk/go","independent":true,"package_count":27,"forbidden_dependencies":0} +``@@BT@ + +`package_count` 随示例增加而变化,不能作为兼容性版本号。门禁只证明源码在当前 Go 工具链下保持独立和可构建,不代表已经发布到远端模块代理,也不替代旧 SDK/新服务端和新 SDK/旧服务端的协议兼容矩阵。 + +## 接入方式 + +SDK 尚未发布正式标签时,开发项目可以使用本地 replace;发布候选必须使用独立 module 的版本标签和干净 checkout 验证。接入方应固定 SDK 版本,升级前先执行自己的接口和业务幂等回归: + +``@@BT@sh +go mod edit -require=git.yuntuo.hk/k2safe/orbit/sdk/go@v0.0.0 +go mod edit -replace=git.yuntuo.hk/k2safe/orbit/sdk/go=/absolute/path/to/orbit/sdk/go +go mod tidy +``@@BT@ + +替换路径只用于本地开发,不能提交到业务项目的发布分支。SDK 不负责 TLS 终止、凭据托管、对象存储或外部副作用核查;这些边界仍由平台接口手册和接入方运行手册定义。 diff --git a/scripts/test-sdk-isolation.sh b/scripts/test-sdk-isolation.sh new file mode 100755 index 0000000..d3049ca --- /dev/null +++ b/scripts/test-sdk-isolation.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# 检查 SDK module 可脱离服务端仓库独立测试、检查和构建。 +set -eu + +TASK_GO=${GO:-go} +TASK_SDK_DIR=${ORBIT_SDK_DIR:-sdk/go} +TASK_DEPS=$(mktemp "${TMPDIR:-/tmp}/orbit-sdk-deps.XXXXXX") +cleanup() { + unlink "$TASK_DEPS" 2>/dev/null || true +} +trap cleanup EXIT HUP INT TERM + +if [ ! -f "$TASK_SDK_DIR/go.mod" ]; then + printf '%s\n' 'SDK go.mod not found.' >&2 + exit 1 +fi +if grep -Eq 'github\.com/go-sql-driver/mysql|git\.yuntuo\.hk/k2safe/orbit/(internal|model|platform|pulse|weave)' "$TASK_SDK_DIR/go.mod"; then + printf '%s\n' 'SDK go.mod contains a forbidden server or database dependency.' >&2 + exit 1 +fi + +(cd "$TASK_SDK_DIR" && GOWORK=off "$TASK_GO" list -mod=readonly -deps ./... >"$TASK_DEPS") +if grep -Eq '^git\.yuntuo\.hk/k2safe/orbit/(internal|model|platform|pulse|weave)(/|$)|github\.com/go-sql-driver/mysql$' "$TASK_DEPS"; then + printf '%s\n' 'SDK dependency graph contains a forbidden server or database package.' >&2 + grep -E 'git\.yuntuo\.hk/k2safe/orbit/(internal|model|platform|pulse|weave)|github\.com/go-sql-driver/mysql' "$TASK_DEPS" >&2 || true + exit 1 +fi + +(cd "$TASK_SDK_DIR" && GOWORK=off "$TASK_GO" test -race ./...) +(cd "$TASK_SDK_DIR" && GOWORK=off "$TASK_GO" vet ./...) +(cd "$TASK_SDK_DIR" && GOWORK=off "$TASK_GO" build ./...) + +TASK_PACKAGE_COUNT=$(cd "$TASK_SDK_DIR" && GOWORK=off "$TASK_GO" list ./... | wc -l | tr -d ' ') +printf '{"sdk_module":"git.yuntuo.hk/k2safe/orbit/sdk/go","independent":true,"package_count":%s,"forbidden_dependencies":0}\n' "$TASK_PACKAGE_COUNT"