Skip to content

Commit 3cbb0f7

Browse files
committed
ci(release): migrate OSS release channel to FC presigned uploads, drop CI-side AK/SK
- Rewrite oss-direct-upload.mjs as an FC client: OIDC token → release-prepare presign → runner uploads straight to OSS → release-finalize (FC-side HEAD reconcile + stable manifest version guard); remove all V1 signing code - publish.yml: remove the seven BAILIAN_OSS_* secrets, use the shared FC_TRIGGER_URL + FC_RELEASE_AUDIENCE instead (reuses the npm OIDC id-token: write permission) - publish.md: document the FC channel and its configuration surface
1 parent 1f6b551 commit 3cbb0f7

5 files changed

Lines changed: 274 additions & 356 deletions

File tree

.github/workflows/publish.yml

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,15 @@ jobs:
7070
- name: publish-stable
7171
env:
7272
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73-
# OSS release channel runs fully in CI: upload + reconcile + manifest.json.
74-
# All values come from repo Settings → Secrets — no OSS defaults live in
75-
# code. Leave AK/SK unset to skip the OSS channel; once enabled,
76-
# bucket/region/prefix are required.
77-
BAILIAN_OSS_AK: ${{ secrets.BAILIAN_OSS_AK }}
78-
BAILIAN_OSS_SK: ${{ secrets.BAILIAN_OSS_SK }}
79-
BAILIAN_OSS_BUCKET: ${{ secrets.BAILIAN_OSS_BUCKET }}
80-
BAILIAN_OSS_REGION: ${{ secrets.BAILIAN_OSS_REGION }}
81-
BAILIAN_OSS_ENDPOINT: ${{ secrets.BAILIAN_OSS_ENDPOINT }}
82-
BAILIAN_RELEASE_PREFIX: ${{ secrets.BAILIAN_RELEASE_PREFIX }}
83-
BAILIAN_STATIC_PREFIX: ${{ secrets.BAILIAN_STATIC_PREFIX }}
73+
# OSS release channel goes through the FC release function (presigned
74+
# upload + reconcile + manifest.json): this repo holds no OSS
75+
# credentials, the job only presents its GitHub OIDC token (requires
76+
# id-token: write above). The trigger URL is the shared
77+
# FC_TRIGGER_URL (same function serves publish-skills; actions are
78+
# routed by URL path); leave it unset to skip the OSS channel.
79+
# Bucket / prefix / allowlists live in the FC function.
80+
FC_TRIGGER_URL: ${{ vars.FC_TRIGGER_URL }}
81+
FC_RELEASE_AUDIENCE: ${{ vars.FC_RELEASE_AUDIENCE }}
8482
run: node tools/release/publish-stable.mjs ${{ inputs.package == 'knowledge-studio-cli' && '--knowledge' || '' }}
8583

8684
publish-channel:
@@ -130,14 +128,10 @@ jobs:
130128
- name: publish-channel
131129
env:
132130
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
133-
# OSS release channel — same Settings-injected values as stable.
134-
BAILIAN_OSS_AK: ${{ secrets.BAILIAN_OSS_AK }}
135-
BAILIAN_OSS_SK: ${{ secrets.BAILIAN_OSS_SK }}
136-
BAILIAN_OSS_BUCKET: ${{ secrets.BAILIAN_OSS_BUCKET }}
137-
BAILIAN_OSS_REGION: ${{ secrets.BAILIAN_OSS_REGION }}
138-
BAILIAN_OSS_ENDPOINT: ${{ secrets.BAILIAN_OSS_ENDPOINT }}
139-
BAILIAN_RELEASE_PREFIX: ${{ secrets.BAILIAN_RELEASE_PREFIX }}
140-
BAILIAN_STATIC_PREFIX: ${{ secrets.BAILIAN_STATIC_PREFIX }}
131+
# OSS release channel — same FC-backed flow as stable; no OSS
132+
# credentials in this repo (see publish-stable env notes).
133+
FC_TRIGGER_URL: ${{ vars.FC_TRIGGER_URL }}
134+
FC_RELEASE_AUDIENCE: ${{ vars.FC_RELEASE_AUDIENCE }}
141135
run: node tools/release/publish-channel.mjs ${{ inputs.package == 'knowledge-studio-cli' && '--knowledge' || '' }} --channel "${{ inputs.channel }}"
142136

143137
# bailian-kb-dsh is the dsh plugin (downstream host adapter): independent version,

docs/agents/publish.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,33 @@ publish-stable.mjs / publish-channel.mjs ← 唯一发版入口
1919
└─ binary(lib/binary-release
2020
→ binary-build
2121
→ gh-release
22-
→ oss-direct-upload)
22+
→ oss-direct-upload → FC release 通道
2323
```
2424

2525
`tools/release/lib/binary-release.mjs` 等是实现,一般不要单独当发版入口(调试可用)。
2626

27+
### OSS 通道:FC 预签名上传(仓库不持有任何 OSS 凭据)
28+
29+
二进制与静态文件(changelog)上 OSS 不再由 CI 持 AK/SK 直传,而是经 FC 函数
30+
(bailian-docs-llm-wiki-crawl 的 `release-prepare` / `release-finalize` action):
31+
32+
1. CI 用本 job 的 GitHub OIDC token(`id-token: write`)调 `release-prepare`;FC 验签
33+
(白名单仓库 + ref)后返回 OSS 预签名 PUT URL(30 分钟过期)
34+
2. runner 拿 URL 直传 OSS(文件体不经过 FC)
35+
3. CI 调 `release-finalize`:FC 用函数角色 STS 凭证做 HEAD 字节数对账;stable 额外
36+
维护 `manifest.json` / `latest.json`(newer-version 守卫在 FC 侧)
37+
38+
配置面:
39+
40+
| 位置 | 变量 | 说明 |
41+
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
42+
| GitHub Variables | 触发 URL 复用共享的 `FC_TRIGGER_URL`(publish-skills 同源,同一 FC 函数按 URL 路径路由 action);另需 `FC_RELEASE_AUDIENCE` | 未设 URL 则跳过 OSS 通道(不阻塞 npm 发布);复用意味着 FC 部署完成前不要合入 release 工具链改动 |
43+
| FC 函数 env | `RELEASE_OIDC_AUD` / `RELEASE_ALLOWED_REPOS` / `RELEASE_ALLOWED_REFS` | 鉴权策略;audience 需与 CI 侧一致 |
44+
| FC 函数 env | `OSS_BUCKET` / `OSS_REGION` / `OSS_RELEASE_PREFIX` / `OSS_STATIC_PREFIX` | bucket 与 key 前缀(原七组 OSS secrets 收敛至此) |
45+
46+
改动 FC 侧逻辑(验签策略 / 对账 / manifest 守卫)去 bailian-docs-llm-wiki-crawl 仓库;
47+
本仓库只维护 client(`tools/release/lib/oss-direct-upload.mjs`)。
48+
2749
### bailian-kb-dsh(独立版本、npm-only)
2850

2951
同一个 Publish 入口,`package=bailian-kb-dsh`。它走单独的 `tools/release/publish-kb-dsh.mjs`,不复用 `publish-stable.mjs` / `publish-channel.mjs`(版本独立、无 binary、无 OSS CDN)。详见 [dsh-plugin.md](dsh-plugin.md#发布)
@@ -88,7 +110,7 @@ node tools/release/publish-channel.mjs --channel test --knowledge --dry-run
88110

89111
## CI 基础设施
90112

91-
- **认证**:npm OIDC Trusted Publishing(无 token),需要 `id-token: write` 权限
113+
- **认证**:npm OIDC Trusted Publishing(无 token),需要 `id-token: write` 权限;OSS 通道复用同一 OIDC token 向 FC 证明身份(见上文「OSS 通道」)
92114
- **GitHub Release**`contents: write` + `GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}`(stable / channel 均需)
93115
- **Node 版本**:24(npm 11.5+ 才支持 OIDC token 交换)
94116
- **Bun**`oven-sh/setup-bun`,版本钉死在 workflow 中

packages/core/src/install/cdn.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/**
22
* End-user binary download base (OSS). CI publishes release assets and rolling
3-
* channel manifests here directly (tools/release/lib/oss-direct-upload.mjs);
4-
* no external FC is involved.
3+
* channel manifests here via the FC release channel
4+
* (tools/release/lib/oss-direct-upload.mjs): the runner uploads through
5+
* FC-presigned URLs and holds no OSS credentials itself.
56
*
67
* Layout under the base:
78
* v<version>/<asset>.zip —— immutable per-version binaries + SHA256SUMS

tools/release/lib/binary-release.mjs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
* `v<betaVersion>` Release (identical binaries).
1414
*
1515
* Re-runs are idempotent via `gh release upload --clobber` (see gh-release.mjs).
16-
* After the GitHub upload the same assets are pushed straight to OSS from the
17-
* runner and HEAD-reconciled — all in-process, no external FC (see oss-direct-upload.mjs).
16+
* After the GitHub upload the same assets go to OSS through the FC release
17+
* channel: FC-presigned PUT URLs + FC-side HEAD reconcile, so the runner holds
18+
* no OSS credentials (see oss-direct-upload.mjs).
1819
*
1920
* Called by publish-stable.mjs / publish-channel.mjs.
2021
* Debug:
@@ -245,9 +246,9 @@ export async function releaseBinaryArtifacts(rawOptions = {}) {
245246
filePaths: [join(ROOT, "CHANGELOG.md"), join(ROOT, "CHANGELOG.zh.md")],
246247
dryRun,
247248
});
248-
// Push the exact Release assets straight to OSS from the runner, then
249-
// HEAD-reconcile. Stable releases additionally maintain release/manifest.json
250-
// (newer-version guard). Throws on failure — CI is the only OSS writer.
249+
// Mirror the exact Release assets to OSS through the FC channel (presigned
250+
// upload + FC-side HEAD reconcile). Stable releases additionally maintain
251+
// release/manifest.json (newer-version guard, FC-side). Throws on failure.
251252
const plans = ossMirrorPlans({ dir, version, mode, files });
252253
const mirror = await mirrorReleaseAssetsToOss({ plans, dryRun });
253254
if (mode === "stable" && !mirror.skipped) {

0 commit comments

Comments
 (0)