ci(repository-plugin): authenticate private GitHub source

This commit is contained in:
Tianyi Cui
2026-08-08 18:16:59 +08:00
parent a9af1a33f0
commit a0c64f4906
10 changed files with 29 additions and 12 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md
2026-07-30-static-repository-plugin-format.md: 4823495dabee2101713ac72c8d0cee5bcc6b38d1
2026-07-30-static-repository-plugin-format.zh.md: e5817ca982a71a609c86c5835b803b12f1317e1a
2026-07-30-static-repository-plugin-format.md: 5b1038f8738868a5838d4b20a6d56399c5f11ab6
2026-07-30-static-repository-plugin-format.zh.md: c7cbc588c5ce6982c7c7003815151c9d40956972

View File

@@ -46,4 +46,4 @@ Unknown MCP fields reject. This intentionally excludes OAuth, `auth` objects, `C
## Testing
Focused tests prepare skills and MCP metadata, prove the emitted wrapper contains no imports, reject Work IQ-style OAuth fields, map Expo-style HTTP and DataJunction-style stdio plus environment values, and exercise missing variables. A real Loader test mounts a generated wrapper through the registered builtin, reads its skill through `ctx.skills`, removes the Loader entry, and observes provider cleanup. The CI built-entry acceptance invokes `dsh run` with a GitHub source pinned to the pull request head, lets bundled pnpm fetch and prepare a private dependency-free fixture, then observes the copied skill in the real model request and the prepared wrapper in the immutable cache.
Focused tests prepare skills and MCP metadata, prove the emitted wrapper contains no imports, reject Work IQ-style OAuth fields, map Expo-style HTTP and DataJunction-style stdio plus environment values, and exercise missing variables. A real Loader test mounts a generated wrapper through the registered builtin, reads its skill through `ctx.skills`, removes the Loader entry, and observes provider cleanup. The CI built-entry acceptance invokes `dsh run` with a GitHub source pinned to the pull request head, authenticates to the private pull request repository through job-scoped Git configuration, lets bundled pnpm fetch and prepare its dependency-free fixture, then observes the copied skill in the real model request and the prepared wrapper in the immutable cache.

View File

@@ -46,4 +46,4 @@
## 测试
聚焦测试会准备 skills 与 MCP metadata证明生成包装模块不含 import拒绝 Work IQ 风格的 OAuth 字段,映射 Expo 风格 HTTP 与 DataJunction 风格 stdio 及环境变量,并覆盖缺失变量。真实 Loader 测试通过已注册 builtin 挂载生成包装模块,经 `ctx.skills` 读取其 skill移除 Loader 条目并观察提供方清理。CI 的构建入口验收会用锁定到 PRPull Requesthead 的 GitHub 源调用 `dsh run`,让随附 pnpm 获取并准备一个私有且不含依赖的 fixture测试前置数据然后在真实模型请求中观察已复制的 skill并在不可变缓存中观察已准备的包装模块。
聚焦测试会准备 skills 与 MCP metadata证明生成包装模块不含 import拒绝 Work IQ 风格的 OAuth 字段,映射 Expo 风格 HTTP 与 DataJunction 风格 stdio 及环境变量,并覆盖缺失变量。真实 Loader 测试通过已注册 builtin 挂载生成包装模块,经 `ctx.skills` 读取其 skill移除 Loader 条目并观察提供方清理。CI 的构建入口验收会用锁定到 PRPull Requesthead 的 GitHub 源调用 `dsh run`通过作业作用域的 Git 配置认证私有 PR 仓库,让随附 pnpm 获取并准备其中不含依赖的 fixture测试前置数据然后在真实模型请求中观察已复制的 skill并在不可变缓存中观察已准备的包装模块。

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-08-host-owned-git-repository-plugin-preparation.md
2026-08-08-host-owned-git-repository-plugin-preparation.md: 45e84f9c8a89bb9d1eb7e4521634d16789dea2f0
2026-08-08-host-owned-git-repository-plugin-preparation.zh.md: ba88d5bb351427118d55c357209b496b39c2eb98
2026-08-08-host-owned-git-repository-plugin-preparation.md: 47410bf3c55455a971ec347eab4e8b37ea26c6a5
2026-08-08-host-owned-git-repository-plugin-preparation.zh.md: 64c37543d34147c41fc7a362040c7ada8fde0652

View File

@@ -18,7 +18,7 @@ The fixed authoring format now requires exact `scripts.prepack: "dsh-plugin-prep
`@deepseek-ai/dsh-repository-plugin` materializes short-lived POSIX and Windows command wrappers that invoke its own built `dsh-plugin-prepare` entry. `RepositoryCache` accepts caller-owned executable directories, resolves them absolutely, and prepends them to the credential-scrubbed lifecycle `PATH` passed to bundled pnpm. The command directory exists only for the installation transaction and is removed on success or failure. The repository remains trusted package-manager input: DSH supplies one command, but other lifecycle scripts and dependencies still execute under the existing trust contract.
The Node 24 consumer lane passes an exact source derived from the pull request head repository and SHA. Its built-entry acceptance launches the real `apps/cli/lib/bin.js run` command with a one-run patch selecting a `private: true`, dependency-free GitHub fixture. It requires the run to reach the mock LLM, finds the repository skill description in the actual model request, and verifies the generated wrapper and copied skill under the immutable DSH cache. The test fails if CI omits the exact source instead of silently skipping.
The Node 24 consumer lane passes an exact source derived from the pull request head repository and SHA. Because that repository is private, the workflow writes a job-scoped Git configuration that uses the read-only job token for GitHub HTTPS and rewrites pnpm's SSH fallback to that authenticated transport. Its built-entry acceptance launches the real `apps/cli/lib/bin.js run` command with a one-run patch selecting a `private: true`, dependency-free GitHub fixture. It requires the run to reach the mock LLM, finds the repository skill description in the actual model request, and verifies the generated wrapper and copied skill under the immutable DSH cache. The test fails if CI omits the exact source instead of silently skipping.
## Alternatives considered
@@ -33,10 +33,11 @@ The Node 24 consumer lane passes an exact source derived from the pull request h
## Consequences
- A repository author can commit the fixed `.dsh-plugin/package.json` and source assets to GitHub without publishing either the Plugin or its preparation helper to npm.
- Private GitHub sources use the host's standard Git authentication. CI proves that path with a temporary read-only configuration rather than persistent runner credentials.
- `prepack`, not `prepare`, is part of the pre-release authoring format. Invalid lifecycle metadata fails during source preparation or installed-package validation instead of producing an ambiguous partial format.
- Exact source strings still identify immutable cache generations; a changed ref or source configuration selects another generation.
- This repair does not expand the contribution surface: prepared repository Plugins still contribute only declared skills and common MCP definitions, while arbitrary package lifecycle code remains trusted installation code rather than a model-facing Cordis Plugin API.
## Testing
`packages/ui/app-boot/tests/repository-cache.spec.ts` runs a local Git subpath through bundled pnpm with an injected command directory and proves that visible environment survives while credential-shaped variables are scrubbed. `packages/cordis/repository-plugin/tests/repository-plugin.spec.ts` pins the exact `prepack` metadata and temporary command cleanup. `apps/cli/tests/github-repository-plugin.built.e2e.ts` is the product acceptance: fresh DSH home, exact live GitHub source, actual built `dsh run`, real headless composition, mock LLM request observation, and prepared cache inspection.
`packages/ui/app-boot/tests/repository-cache.spec.ts` runs a local Git subpath through bundled pnpm with an injected command directory and proves that visible environment survives while credential-shaped variables are scrubbed. `packages/cordis/repository-plugin/tests/repository-plugin.spec.ts` pins the exact `prepack` metadata and temporary command cleanup. `examples/headless-agent/tests/keyless-smoke.e2e.ts` keeps the checked-in prepared fixture on that source contract. `apps/cli/tests/github-repository-plugin.built.e2e.ts` is the product acceptance: fresh DSH home, exact authenticated private GitHub source, actual built `dsh run`, real headless composition, mock LLM request observation, and prepared cache inspection.

View File

@@ -18,7 +18,7 @@ repository 插件的创作契约依赖 `scripts.prepare: "dsh-plugin-prepare"`
`@deepseek-ai/dsh-repository-plugin` 会生成临时的 POSIX 和 Windows 命令包装脚本,用于调用其自有的已构建 `dsh-plugin-prepare` 入口。`RepositoryCache` 接受由调用方持有的可执行文件目录,将它们解析为绝对路径,再前置到传给随附 pnpm、已清除凭据的包生命周期 `PATH`。该命令目录仅存在于安装事务期间无论成功还是失败都会被移除。仓库仍是受信任的包管理器输入DSH 仅提供这一条命令,其他生命周期脚本和依赖仍会按既有信任契约执行。
Node 24 消费方 CI 任务会传入从 PRPull Requesthead 仓库和 SHA 派生的精确源。其构建入口验收会启动真实的 `apps/cli/lib/bin.js run` 命令,并通过一个仅作用于当次运行的 patch 选择 `private: true`、不含依赖的 GitHub fixture。验收要求该次运行到达 mock LLM大语言模型在实际模型请求中找到 repository skill 描述,并验证不可变 DSH 缓存中的生成包装层和已复制 skill。如果 CI 遗漏精确源,测试会失败,而不是静默跳过。
Node 24 消费方 CI 任务会传入从 PRPull Requesthead 仓库和 SHA 派生的精确源。由于该仓库为私有仓库,工作流会写入一份作业作用域的 Git 配置,使用该作业的只读 token 对 GitHub HTTPS 连接进行认证,并将 pnpm 的 SSH 回退路径重写为这一已认证的传输方式。其构建入口验收会启动真实的 `apps/cli/lib/bin.js run` 命令,并通过一个仅作用于当次运行的 patch 选择 `private: true`、不含依赖的 GitHub fixture。验收要求该次运行到达 mock LLM大语言模型在实际模型请求中找到 repository skill 描述,并验证不可变 DSH 缓存中的生成包装层和已复制 skill。如果 CI 遗漏精确源,测试会失败,而不是静默跳过。
## 考虑过的替代方案
@@ -33,10 +33,11 @@ Node 24 消费方 CI 任务会传入从 PRPull Requesthead 仓库和 SHA
## 后果
- 仓库作者可以把修复后的 `.dsh-plugin/package.json` 和源资源提交到 GitHub而无需把插件或其准备辅助程序发布到 NPM。
- 私有 GitHub 源使用宿主的标准 Git 认证。CI 使用临时的只读配置而非运行器上的持久凭据来验证该路径。
- 预发布创作格式使用 `prepack` 而不是 `prepare`。无效的生命周期元数据会在源码准备或已安装包校验阶段导致失败,而不会留下状态不明的半成品格式。
- 精确源字符串仍标识不可变缓存 generation改变 ref 或源配置会选择另一个 generation。
- 本次修复不扩大贡献范围:已准备的 repository 插件仍只贡献已声明的 skills 和通用 MCP 定义,而任意包生命周期代码仍是受信任的安装代码,不是面向模型的 Cordis 插件 API。
## 测试
`packages/ui/app-boot/tests/repository-cache.spec.ts` 会用注入的命令目录通过随附 pnpm 运行本地 Git 子路径,并证明可见环境变量得以保留,而名称符合凭据模式的变量会被清除。`packages/cordis/repository-plugin/tests/repository-plugin.spec.ts` 锁定精确的 `prepack` 元数据和临时命令清理行为。`apps/cli/tests/github-repository-plugin.built.e2e.ts` 是产品验收测试:全新的 DSH 主目录、精确的真实 GitHub 源、实际构建产物的 `dsh run`、真实 headless 组合、mock LLM 请求观测,以及对已准备缓存的检查。
`packages/ui/app-boot/tests/repository-cache.spec.ts` 会用注入的命令目录通过随附 pnpm 运行本地 Git 子路径,并证明可见环境变量得以保留,而名称符合凭据模式的变量会被清除。`packages/cordis/repository-plugin/tests/repository-plugin.spec.ts` 锁定精确的 `prepack` 元数据和临时命令清理行为。`examples/headless-agent/tests/keyless-smoke.e2e.ts` 使签入仓库的已准备 fixture 继续符合该源格式契约。`apps/cli/tests/github-repository-plugin.built.e2e.ts` 是产品验收测试:全新的 DSH 主目录、精确且经过认证的私有 GitHub 源、实际构建产物的 `dsh run`、真实 headless 组合、mock LLM 请求观测,以及对已准备缓存的检查。