Skip to content

DeepSeek Harness 拥有两套 CI 表面(GitHub Actions 负责 TypeScript monorepo 及其 Python SDK;GitLab CI 负责原生 Python wheel),外加一整套本地开发工具——lefthook git 钩子、oxlint、knip、jscpd,以及不变量/拼接链接卫生门禁。发布走基于 family 的版本号更新(release/dsh-* / release/vendor-*),并在打标签前把版本号提交进仓库。本页梳理整个工程化流水线。

GitLab CI:Python 发布形态

.gitlab-ci.yml 针对 Python 发布标签(python-v<major>.<minor>.<patch>…)运行。两个阶段:buildpublish

  • sdk-wheel 构建无密钥 SDK wheel。
  • runtime-linux-x64runtime-linux-arm64runtime-macos-arm64 各自为对应目标构建打包的单 exe 运行时,然后验证:Python 冒烟(python scripts/smoke-python-runtime.py)、Linux 下通过 readelf 检查 glibc ≤ 2.28、经 Docker 镜像做 manylinux 冒烟、macOS 部署目标检查。
  • publish-pythontwine 把四个 .whl 上传到项目的 Package Registry,并用“标签 vs package.json 版本”断言护住。GitLab 不覆盖已有版本,因此每次发布都需要新的 python-v<version> 标签。

标签对版本断言是核心:test "$CI_COMMIT_TAG" = "python-v$DSH_VERSION" || exit 1

GitHub Actions:PR 门禁

.github/workflows/ci.yml 是必跑的 PR 流水线。它在 runner 池与并发上相当讲究;关键车道(除注明外为 Node 24)如下:

任务运行于做什么
node-24 / staticLinux 企业池pnpm run check:ci:static
node-24-coverageLinuxpnpm run check:ci:coverage(穷尽覆盖率)
node-24-consumersLinuxpnpm run check:ci:consumers(快照、制品、基于 Playwright 的 web)
node-compat(矩阵)ubuntu-latestNode 22.1926check:node-compat
python-sdkubuntu-latestuv 的 Python 3.10 无密钥套件
python-runtime可复用构建发布形态的 Linux x64 exe 构建
windowsubuntu-latestWine:运行 scripts/wine-windows-gates.sh(Wine 下的 Windows Node)
windows-native真实 Windowscheck:ci:windows-complete
serial-linux-selfhosted / serial-windowsself-hosted仅 push 的 standby 演练(为 failover 池提供热备证据)
all-checks-passedubuntu-latestif: always() 汇总裁决;任一所依赖任务非成功即失败

门禁脚本来自 scripts/run-gates.tscheck:cicheck:ci:linux-primarycheck:ci:staticcheck:ci:coveragecheck:ci:snapshotcheck:ci:artifactscheck:ci:consumerscheck:ci:windows-* 都是对各自 run-gates.ts 编排的薄 npm-script 包装。环境旋钮约束并发:DSH_GATE_CONCURRENCYDSH_COVERAGE_MAX_WORKERSDSH_SNAPSHOT_MAX_CONCURRENCYDSH_E2E_MAX_WORKERSDSH_OXLINT_THREADSDSH_PUBLINT_CONCURRENCY

工作流 env 中写死的 CI 政策要点:DSH_TELEMETRY_DISABLED=1(CI 运行绝不向生产遥测端点上报)、fetch-depth(供归档门禁)、Web 门禁用 Playwright Chromium、prepare-ci-bubblewrap.sh 解除沙箱套件的 namespace 限制,以及经仓库变量 DSH_CI_FAILOVER_LINUX / DSH_CI_FAILOVER_WINDOWS 把任务改指到自有 self-hosted 池的 failover 机制。

发布流程(从 git 可见)

发布流程是版本化且仅标签:

bash
$ git log --oneline --grep=release -15
abe560f81e release(dsh)
8c1e8d9890 build(release): publish the dsh family publicly
8a954b2eca release(dsh): 0.1.0-rc.3
60b04b6ef7 release(dsh): 0.1.0-rc.2
22ab3beac1 release(dsh): 0.1.0-rc.1
7bedce822f release(vendor)

scripts/release/ 实现它:

脚本作用
bump.ts递增某 family 版本并提交(--family dsh 在成员与根上共享一个版本;--family vendor 每个包一行版本,但整族一起发布)
verify.ts对照 workspace 状态核验发布版本
pack.ts构建并打包 tarball 到 dist/npm
verify-packed-install.ts安装打包 tarball(外加 vendor 与 Landlock tarball)并证明它们能解析
publish.ts把打包好的确切字节上传到 npm

.github/workflows/release.yml每个 PR/push 上运行 release:verifybuildrelease:packrelease:verify-packed-install(只做打包证明:整组发布集仍可打包),再由一个由 environment: npm-publish 门禁单独保护的 publish 任务,在从 dsh-v* 标签手动触发时上传字节。被拼接的框架族经单独的 release-vendor.yml 发布;Landlock 原生包经 native/landlock-run 发布。依赖编辑改变载荷时,lefthook 会重新生成 THIRD_PARTY_NOTICES.md

开发工具

lefthook git 钩子(lefthook.yml

postinstall 运行 node scripts/install-lefthook.mjs。本地钩子刻意保持快速检查点;完整矩阵由 CI 负责:

  • pre-commit:stage 文件 lint(tsx scripts/run-oxlint.ts --config .oxlintrc.staged.json)、*.i18n.yaml 的翻译配对、归档 agent note 检查、空白符 git diff --cached --check、vendor 清单守卫,以及第三方通知重新生成(重新生成并 git add THIRD_PARTY_NOTICES.md)。
  • pre-merge-commit:翻译配对 + 归档 note。
  • pre-pushpnpm run typecheck

oxlint(run-oxlint.ts.oxlintrc.json

npm run lint = build:lib:host 然后 tsx scripts/run-oxlint.ts .contracts-ready 变体在客户端契约构建后运行)。.oxlintrc.json 在顶层把 correctness 规则关掉,再按 override 范围重新启用严格的、多为类型感知的规则;它忽略 vendor/**native/***.config.ts。钩子用的是更严的 --fix staged 变体(.oxlintrc.staged.json)。

knip 未用代码检查(knip.json

npm run knipknip --treat-config-hints-as-errors)检测整个 workspace 中未用的依赖/文件/导出。vendor 与 python/sdk-runtime 被忽略;若干二进制(bwrappwshsandbox-exec,…)与依赖(@yarnpkg/cli-distlightningcss)被加入白名单。

jscpd 重复代码(jscpd.json

npm run duplicationminTokens: 60minLines: 6mode: "mild" 运行 jscpd --config .jscpd.json packages scripts,并用 ignorePattern 处理显式的 /* jscpd:ignore-start */ … /* jscpd:ignore-end */ 块(不变量伴生包与导出中大量使用)。

hygiene 组合

pnpm run hygiene 串起深层门禁:rescope-vendor:checkknippublintconstraintsverify-dsh-package-licensesverify-package-invariantsverify-built-package-invariantsverify-cordis-configverify-node-next-typesverify-runtime-closureverify-vendored-links。这些保证发布前 workspace 内部一致。

贡献流程

CONTRIBUTING.md 说明项目处于早期阶段,目前不接受外部 PR;贡献通过 GitHub Discussions、生态插件(经 dsh-plugin 主题)与社区内容发生。这是个刻意设置的关卡,把团队 PR 评审精力聚焦在内部,同时围绕 harness 培育生态。

工具

工具版本(根 package.json devDependencies)
vitest^4.1.8
oxlint
oxlint-tsgolint
knip^6.16.1
jscpd^5.0.12
lefthook^2.1.9
tsx^4.22.4
typescript^6.0.3
publint^0.3.21
tsdown^0.22.2

延伸阅读

  • 测试策略— 每个 check:ci:* 门禁实际跑什么。
  • 运行时不变量verify-package-invariants 门禁与伴生包。
  • 拼接库verify-vendored-linksrescope-vendor 与 family 发布。
  • .gitlab-ci.yml— Python wheel 流水线及其标签守卫。
  • scripts/run-gates.tsscripts/release/bump.ts— 门禁编排与 family 版本化。
  • lefthook.yml— 具体的 pre-commit/pre-push 任务及其 glob。