Apache Maka CLI npm 发布全流程:Nightly 快照、npm Stage 与 Finalize 受控发布实战
【免费下载链接】makaApache Maka (Incubating) is a high-performance agent workspace that keeps a complete record of everything it did.项目地址: https://gitcode.com/GitHub_Trending/mak/maka
本指南是 Apache Maka(Incubating)发布maka-agentnpm 安装渠道的官方运行手册(runbook),覆盖从定时 Nightly 快照、正式版本暂存(Stage)、npm 2FA 人工批准到 Finalize 定稿的完整受控流水线。读者将掌握 Maka 如何在 Apache 孵化器约束下以"源发布为准、npm 为便利包"的模型安全发布 CLI,以及各环节的可验证命令、故障恢复策略与所有权边界。
发布模型:ASF 源发布是唯一权威,npm 是便利包
Maka 的发布体系建立在一个明确的分层模型上:IPMC 批准的源码归档(source archive)才是 Apache Release;npm 包、桌面安装包和 GitHub Release 资产都是从该已批准源构建的"便利包"(convenience packages),不构成额外的 ASF 发布产物。
在这一模型下,版本权威也保持单一:根目录 package.json 是 Maka 产品的唯一版本权威(当前为0.2.0),packages/cli/package.json必须与之完全一致(同样为0.2.0)。每一次公开发布的 npm 版本都必须来自共享打包工作流校验过的精确 tarball,不允许在验证、暂存、批准、定稿之间重建。
正式的发布路径之前还有一道更早的检查:源码 RC 的 npm 预检运行手册(对应 .github/workflows/asf-npm-candidate.yml)。该预检不需要任何发布凭据,只从v<version>-incubating-rc<rc>标注 tag 构建一个干净源的 npm tarball 并在全平台矩阵上验证安装能力,作为源码 RC 的诊断证据。它的 tarball不会带入正式发布:源码获批后,Stage 从最终产品 tag(同一获批 commit)重建,成为 npm 暂存与 registry 校验的"字节权威"。
发布不变量(Release invariants)
这些不变量是整个发布体系的底线约束,任何操作都不得违反:
- 产品 Release 工作流只能从精确获批的 ASF 源候选 tag 触发;npm Stage 与产品 Finalize 都从
main触发,Stage 只把由此产生的产品v<version>tag 当作已校验的发布数据(data),而非可信代码。 - 已批准的稳定版本发布到
latest渠道;开发快照发布到nightly渠道。不存在next渠道,nightly永远不得改动latest。 - 不创建 npm 专属的 Git tag 或 GitHub Release。
Release工作流在 npm 暂存之前创建产品v<version>tag 和 Draft;Finalize 是该 Draft 的唯一发布者。 - GitHub Release 保持 Draft 状态,直到 npm Finalize 和桌面端远程 Runtime Host 验收都成功。Draft 为 npm 提供产品身份,其正式发布是产品的最终动作。
- 正式发布只允许执行
npm stage publish;由人类包维护者使用 npm 2FA 批准暂存包。只有 Product Nightly 可以不经人工直接执行npm publish --tag nightly。 - 验证、暂存、批准、定稿之间不得重建。
- 绝不复用已公开的版本号。正式产品修复必须使用新的 patch/minor/major 版本。
四条工作流边界
整个发布流水线由四份工作流协作完成,职责严格分离:
- npm-publication.yml 是唯一的 Trusted Publisher 调用方。它只从
main运行,将正式发布路由到以精确产品 tag 为数据输入的 Stage 流程,同时负责发布 npm Nightly。工作流提供channel(nightly/formal)与version两个手动输入,并内置定时调度cron: '17 18 * * *'(UTC)用于 Nightly。 - release-cli-stage.yml(Stage CLI npm release)解析已存在的产品 tag 与 GitHub Release:
authorize、validate两个 job 不带 OIDC,从产品 commit 构建并校验一个不可变 tarball;带 OIDC 的stagejob 只执行经过评审的main发布者代码,分别记录产品源与发布者双重身份,并把校验过的字节提交到 npm 暂存区。 - **desktop-nightly.yml(Desktop Nightly)**只在 npm Nightly 成功后启动,只消费其不可变版本文件,并通过经过认证的
workflow_run事件取得源 commit 与上游 run 身份。 - **release-cli-finalize.yml(Finalize product release)**只接受精确的、成功的 Stage run、Release build run 与自包含发布记录。
main上经过评审的校验器检查公开 registry 字节、签名、provenance、dist-tag、不可变构建产物与实时 Draft 摘要,随后在受保护的product-releaseEnvironment 等待;桌面端独立验收通过后,批准以受保护的工作流身份对精确便利包做 attestation、发布 GitHub Release,并一步完成 Stable/Latest 分类。
一次性控制平面配置
GitHub Environment(以.asf.yaml为权威)
检查入库的 .asf.yaml 是npm-publication、nightly、product-release三个 Environment 的唯一权威配置来源。该文件被合入main后,需确认 ASF 协调(reconciliation)产生了:
npm-publication:选中main分支规则,无审批门,保证定时 Nightly 可自动发布(见.asf.yaml中required_reviewers: []);nightly:选中main分支规则,无审批门,保证 Desktop Nightly 可自动发布;product-release:选中main分支规则,必需评审人M4n5ter,且禁止自评(prevent_self_review: true);- 仓库策略允许时禁用管理员绕过。
另外.asf.yaml中还定义了名为 "Immutable release tags" 的 tag ruleset:对所有v*tag 禁止删除与强制推送,从 Git 层面保证产品 tag 的不可变性。检查或修复协调需要仓库管理权限;不要在 GitHub 上另建一套手动 Environment 策略。Finalize 使用 GitHub Actions OIDC 为精确便利包创建 Sigstore provenance,并将离线校验 bundle 存放到资产旁边,全程不需要仓库管理凭据、签名私钥或 npm token。
npm Trusted Publisher
在maka-agent包设置中配置一个GitHub Actions Trusted Publisher:
| 字段 | 值 |
|---|---|
| Organization or user | apache |
| Repository | maka |
| Workflow filename | npm-publication.yml |
| Environment name | npm-publication |
| Allowed actions | npm publish和npm stage publish |
工作流文件名区分大小写,且不含.github/workflows/前缀。正式暂存与直接 Nightly 发布共用同一个npm-publicationEnvironment,其部署规则只放行main。它没有 GitHub 审批门(因为定时 Nightly 是自动的);正式发布仍需暂存后的人类 npm 2FA 批准。不要配置第二个发布者或 npm token。
首次 OIDC Stage 成功后,将包发布访问权限设置为Require two-factor authentication and disallow tokens,然后吊销过期的发布 token;此变更不得移除人类包所有者或恢复访问通道。仓库变量NPM_NIGHTLY_ENABLED在.asf.yaml完成 Environment 协调、Trusted Publisher 匹配之前保持未设置;之后置为true并手动运行一次 Nightly,再依赖定时调度。该变量只控制 npm;Desktop 有自己独立的DESKTOP_NIGHTLY_ENABLED滚动门(见 desktop-nightly.yml 中的vars.DESKTOP_NIGHTLY_ENABLED == 'true'判断)。
Product Nightly:开发者快照渠道
定时触发的 npm-publication.yml 从精确的定时maincommit 生成一个不可变版本,校验四平台maka-agenttarball,并发布到nightlytag。版本号的生成逻辑在 scripts/product-nightly.mjs 中:格式为
<productVersion>-dev.<runNumber>.<YYYYMMDD>例如0.2.0-dev.42.20260829,其中 runNumber 来自GITHUB_RUN_NUMBER,日期来自构建日。该脚本同时要求产品版本本身必须是稳定的正式版本(不允许 prerelease 产品版本),并通过 scripts/release-version.mjs 中的parseProductNightlyVersion/assertProductNightlyAdvances严格校验 Nightly 版本的三段式 prerelease(dev+ 正整数 run + 8 位日期)以及新 run 必须严格大于当前nightlytag 的 run。
只有当精确版本与 dist-tag 都已公开后,成功的 Nightly 工作流才会触发 desktop-nightly.yml。Desktop 只消费该版本;经过认证的上游事件提供精确源 commit。打包的 Desktop 记录精确的 Runtime Host 安装说明符(例如maka-agent@0.2.0-dev.42.20260829),绝不安装可变的nightlytag。
两个工作流按此顺序发布(防止 Desktop 宣传 npm 尚不存在的 Runtime Host 版本,同时保持 npm Nightly 独立于桌面打包):
- 要求候选 npm run 号比当前
nightlytag 更新; - 带 provenance 将精确 npm tarball 发布到
nightly; - 要求从公共 registry 能读到精确版本与
nightlytag(工作流内会轮询最多 45 分钟,每次 20 秒,见npm-publication.yml的 publish job); - 构建、校验并 attest 精确的 Desktop 包与 GitHub
dev元数据; - 将受保护的
v<version>tag 绑定到精确源 commit,并验证desktopNightlyReleaseAssetNames定义的精确 Draft 资产; - Draft 完整后才发布 GitHub prerelease 且禁用 Latest。
一次失败的 npm 或 Desktop 运行绝不在原地重跑(工作流的 identity job 会以github.run_attempt != 1直接拒绝),因为每次尝试都有不可变的 npm 版本。请启动一次全新的 npm Nightly:
gh workflow run npm-publication.yml --ref main -f channel=nightlyNightly 是开发者快照,不是 Apache 发布,不得从终端用户下载页推广。开发者可显式安装移动渠道maka-agent@nightly;产品自动化必须使用 Desktop 记录的精确版本。
准备一次正式发布
将所有计划中的包、文档与发布变更合并到
main,准备 ASF 源候选,并完成 podling 与 Incubator PMC 两轮投票。确认在获批源 commit 上,根 package.json、apps/desktop/package.json 与 packages/cli/package.json 的稳定目标版本相同且未被占用。正式 npm 发布只推进
latest。从精确获批的
v<version>-incubating-rc<rc>tag 触发产品Release工作流(.github/workflows/release.yml),并以同一 tag 作为source_reference_tag输入;确认其 Draftv<version>Release 指向获批 commit。npm 暂存消费这个身份,且不能先于它发生。确认目标版本在公共与暂存状态中都不存在:
version=0.2.0 npm view "maka-agent@$version" version --registry https://registry.npmjs.org/ npm stage list maka-agent --registry https://registry.npmjs.org/第一条命令应报告目标版本不存在。若暂存区已有同名 stage,应解决它而不是再次提交相同版本。
确认
npm-publicationEnvironment 与 Trusted Publisher 仍与上文一致,且负责批准的 npm 账号已启用 2FA。
暂存候选版本(Stage)
从经过评审的
main触发工作流,提供精确产品版本:version=0.2.0 gh workflow run npm-publication.yml --ref main \ -f channel=formal \ -f version="$version"确认产生的 run 使用
main。工作流把v<version>及其 Draft 当作数据解析,要求该 tag commit 仍是main的祖先,不带 OIDC构建候选,并把 npm provenance 绑定到经评审的main发布者工作流与精确 run。等待可复用包校验 job(.github/workflows/cli-package-validation.yml)通过:构建一个 tarball,并在 Linux x64/arm64、macOS arm64、Windows x64 上安装校验 CLI,同时在 Linux x64 上运行真实的 Harbor 与 Pier Docker 单元。
从 run 摘要与
cli-staged-release-<attempt>构件记录成功的 Stage 工作流 run ID、run attempt、源 commit、版本与暂存产物校验和。
若 Stage 工作流未成功结束,绝不在 npm 上批准任何东西。
Stage 的产物身份记录在release.json(由 scripts/release-cli-publication.mjs 的prepare-stage写入,schemaVersion 4),它同时携带source(仓库与 commit)和publisher(工作流、commit、runId、runAttempt)双重身份,是后续 Finalize 验证的证据锚点。
在 npm 上检查并批准
检查与批准命令要求Node.js 22.14.0 或更新、npm 11.15.0 或更新。Stage 工作流使用自己的受评审工具链:工作流中固定的 Node.js 版本(22.19.0,见 release-cli-stage.yml)与仓库packageManager钉死的精确 npm 版本(根 package.json 当前为npm@11.19.0)。
npm stage list maka-agent --registry https://registry.npmjs.org/ stage_id=replace-with-reviewed-stage-id npm stage view "$stage_id" --registry https://registry.npmjs.org/ npm stage download "$stage_id" --registry https://registry.npmjs.org/批准前必须:
- 要求包名、版本、dist-tag、provenance 与源仓库和 Stage run 一致;
- 将下载的暂存 tarball 的 SHA-256 与工作流构件的
.tgz.sha256比对; - 检查文件清单与打包的
README.md; - 确认 tarball 属于记录的 Stage run 与源 commit。
批准前一刻,重新核对 Stage run 记录的实时产品权威:
set -eu source_commit=replace-with-stage-recorded-commit node scripts/product-release-authority.mjs verify-draft \ "v$version" "$source_commit" apache/maka校验器必须成功。若 tag 不存在、被移动、不再位于main上、对应 GitHub Release 不再是稳定 Draft 或已被标记为 prerelease,立即停止。该verify-draft命令在 scripts/product-release-authority.mjs 中的实现会检查 tag 的远端 commit 精确匹配、commit 是main的祖先,以及 Release 必须是 Draft 且非 prerelease。
只批准这一个 stage ID。npm 要求 2FA,并在批准过程中把包公开:
npm stage approve "$stage_id" --registry https://registry.npmjs.org/同样的评审与批准也可以从 npmjs.com 上包的Staged Packages页面进行。批准后检查公开 tag:
version=0.1.0 npm view maka-agent dist-tags --json --registry https://registry.npmjs.org/latest必须指向已批准版本;nightly(若存在)保持独立。
Finalize 产品发布
npm 报告版本公开后:
- 在
main上打开Actions → Finalize product release → Run workflow。 - 输入成功的 Stage run ID 与 attempt、成功的 Release build run ID 与 attempt、以及版本(对应 release-cli-finalize.yml 的
stage_run_id、stage_run_attempt、release_run_id、release_run_attempt、version五个输入)。 - 让 inspection job 校验公开 tarball 的字节、校验和、清单、npm 签名、Trusted Publishing provenance 与精确的
latestdist-tag。该校验会重新下载 registry 字节(见 release-cli-publication.mjs 的fetch-registry:同时核对sha256、sha512integrity 与sha1shasum),并执行npm audit signatures --json --include-attestations后解析 SLSA provenance v1 语句,逐字段核对构建定义、工作流路径、run 身份与源码 commit(matchesReleaseProvenance)。 - 当 publication job 在
product-releaseEnvironment 等待批准时,完成产品清单要求的跨机器验收。 - 批准 Environment。确认工作流把每个实时 Draft 摘要与精确 Release attempt 的发布记录匹配,创建并上传
Maka-<version>-attestation.sigstore.json(由actions/attest生成 bundle 后重命名),发布便利 Release,并无需额外手动操作即把稳定 Release 置为 Latest。发布动作由 product-release-authority.mjs 的publish-draft完成:先上传 attestation bundle、核对 Draft 资产精确匹配,再通过 PATCHdraft=false&prerelease=false&make_latest=true一次性发布,最后轮询确认 Latest 指向该 tag。
检查最终 registry 状态:
version=0.2.0 npm view "maka-agent@$version" version dist.tarball dist.integrity --json npm view maka-agent dist-tags --json最后,在每个发布平台安装精确公开版本并完成一次真实 TUI/模型回合;在受支持的 Eval 主机上完成至少一个真实实验单元,检查 score、usage、cost 与 artifacts。验收证据要求以 产品发布清单 为权威。
故障恢复矩阵
npm 暂存之前
若npm stage publish之前发生瞬时失败,可从同一产品 tag 重跑 Stage。若需要修改代码或工作流,在main上修复、递增产品版本、创建新产品 tag 与 Draft,再暂存新版本。此时尚无 npm 版本被消耗。
Stage 工作流失败但 npm 中存在 stage
提交是 Stage 工作流的最后一个业务步骤,因此响应丢失可能在工作流不成功时仍留下一个 npm stage。不要批准该孤儿 stage:Finalize 只接受成功的 Stage run attempt。先检查它,再带 2FA 拒绝精确 stage ID,然后开始新的 Stage run:
stage_id=replace-with-reviewed-stage-id npm stage view "$stage_id" --registry https://registry.npmjs.org/ npm stage reject "$stage_id" --registry https://registry.npmjs.org/绝不只凭版本文本拒绝 stage;必须把动作绑定到已检查的 stage ID。
Stage 成功但评审发现问题
拒绝 stage,在main上修复问题,递增产品版本,创建新产品 tag 与 Draft,再暂存新版本。不要为了清空暂存区而批准候选。
npm 批准成功但 Finalize 失败
npm 版本已经不可变,不要再次发布或批准它。保留 Stage run ID、attempt、版本以及 Release run ID、attempt、发布记录与构件。若这些字节与 provenance 有效,在main上修复 Finalize 校验器并对同一不可变 Stage 与 Release 证据重跑。inspection job 是只读的;只有受保护的 publication job 可以执行唯一的 Draft→已发布转换并 attest 其字节。若 npm 身份、构建证据或 Draft 不一致,停止并调查;不要修改产品 tag 或 GitHub Release 来让校验通过。若发布请求后报告失败,先检查精确 Release:成功的发布不得重复执行。
公开发布版本有缺陷
先把受影响的 dist-tag 移回先前已验证的版本:
known_good=0.2.0 npm dist-tag add "maka-agent@$known_good" latest然后只弃用(deprecate)有缺陷的版本,并引导用户到已恢复的 dist-tag(它已指向已验证版本):
bad_version=0.2.1 recovery_tag=latest npm deprecate "maka-agent@$bad_version" "Known issue; install maka-agent@$recovery_tag."验证 tag,修复缺陷,并通过完整的 Stage + Finalize 流程发布新版本。不要用npm unpublish作为常规回滚:移除不可变的依赖字节可能破坏既有安装,也不会恢复受评审的发布链。
Nightly 有缺陷时,发起一次全新 run 让新的不可变版本推进nightly。若需立即回滚,人类包所有者可以把nightly移回先前验证过的 Nightly 版本,并只弃用有缺陷的精确版本。绝不让latest指向 Nightly。
所有权与紧急恢复
- GitHub 仓库管理员拥有
npm-publicationEnvironment 配置;发布维护者负责触发、暂存包检查、npm 2FA 批准与最终验收。 - npm 包所有者负责 Trusted Publisher、发布访问权限、维护者与 dist-tag 恢复。
- Trusted Publishing 生效期间至少保留一位启用 2FA 的人类所有者;移除当前直接所有者前,先加入计划的 npm 组织发布团队与另一位直接人类恢复维护者,并验证两条路径。
- 工作流不得获得长效 npm token。若 OIDC、Environment 或信任关系被破坏,暂停发布并修复该控制平面,而不是用
npm publish绕过暂存。 - npm 账号丢失时,使用其账号恢复方法或另一位已验证的包所有者。在建立第二位所有者之前,恢复依赖当前所有者的 npm 恢复凭据;把完成该所有权跟进视为运营负债。
- 若仓库或 npm 发布者设置意外变更,移除或禁用信任关系,保留工作流与 npm 审计证据,恢复已评审配置,并对任何完整性存疑的候选使用新版本。
仓库内相关文档
- npm 源码 RC 预检(ASF_NPM_RELEASE.md):发布前无需凭据的兼容性检查契约
- 产品发布清单(RELEASE_CHECKLIST.md):Finalize 前验收证据的权威要求
- Desktop Nightly 说明(DESKTOP_NIGHTLY.md):桌面端 nightly 渠道机制
- CLI npm 发布中文版:本文档的简体中文对照
- ASF 源发布流程(ASF_SOURCE_RELEASE.md):源归档发布与投票流程
关键实现与校验脚本集中在 scripts/product-nightly.mjs、scripts/release-version.mjs、scripts/release-cli-publication.mjs 与 scripts/product-release-authority.mjs,发布控制平面则以 .asf.yaml 与.github/workflows/下四份工作流为权威,可供进一步深入阅读。
【免费下载链接】makaApache Maka (Incubating) is a high-performance agent workspace that keeps a complete record of everything it did.项目地址: https://gitcode.com/GitHub_Trending/mak/maka
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考