Files
maka/docs/cli-npm-release.md
agent-radar 7be535059e
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 19:05:14 +08:00

370 lines
19 KiB
Markdown

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# Maka CLI npm release operations
[简体中文](./cli-npm-release.zh-CN.md)
This runbook is the operational authority for publishing the `maka-agent` npm installation channels. The root `package.json` remains the sole Maka product-version authority, and `packages/cli/package.json` must match it. Every public npm version must come from an exact tarball validated by the shared package workflow.
The IPMC-approved source archive on ASF distribution infrastructure is the Apache release. npm,
Desktop installers, and GitHub Release assets are convenience packages built from that approved
source identity; they are not additional ASF release artifacts.
The source-RC [npm preflight](../.github/ASF_NPM_RELEASE.md) is an earlier, credential-free
compatibility check. Its tarball is not carried into publication. After source approval, Stage
rebuilds from the final product tag at the same approved commit and becomes the byte authority for
npm staging and registry verification. This matches Apache OpenDAL's incubating practice while
retaining Maka's stronger protected-Environment, staged-publishing, 2FA, and Finalize controls.
## Release invariants
- Dispatch the product Release workflow only from the exact approved ASF source candidate tag.
Dispatch both npm Stage and product Finalize from `main`; Stage accepts the resulting product
`v<version>` tag only as verified release data.
- Publish approved stable versions under `latest`. Publish developer snapshots under `nightly`.
There is no `next` channel, and `nightly` must never modify `latest`.
- Do not create an npm-specific Git tag or GitHub Release. The `Release` workflow creates the
product `v<version>` tag and Draft before npm staging; Finalize is the sole publisher of that Draft.
- Keep that GitHub Release in Draft until npm Finalize and Desktop remote Runtime Host acceptance
succeed. The Draft supplies npm's product identity; its publication is the final product action.
- Formal publication may only run `npm stage publish`; a human package maintainer approves the
staged package with npm 2FA. Product Nightly alone may run `npm publish --tag nightly` directly.
- Do not rebuild between validation, staging, approval, and finalization.
- Never reuse a public version. Formal product fixes require a new patch, minor, or major version.
The workflow boundaries are:
1. [npm publication](../.github/workflows/npm-publication.yml) is the only Trusted Publisher caller.
It runs exclusively from `main`, routes formal publication for an exact product tag supplied as
data, and publishes npm Nightly.
2. [Stage CLI npm release](../.github/workflows/release-cli-stage.yml) resolves the existing product
tag and GitHub Release. Jobs without OIDC build and validate one immutable tarball from that
product commit. The OIDC job executes only reviewed `main` publisher code, records the separate
product-source and publisher identities, and submits the validated bytes to npm staging.
3. [Desktop Nightly](../.github/workflows/desktop-nightly.yml) starts only after a successful npm
Nightly run, consumes only its immutable version file, and takes the source commit and upstream
run identity from the authenticated `workflow_run` event.
4. [Finalize product release](../.github/workflows/release-cli-finalize.yml) accepts only the exact
successful Stage run, Release build run, and self-contained publication record. The current
reviewed verifier on `main` checks the public registry bytes, signature, provenance, dist-tag,
immutable build artifacts, and live Draft digests, then waits at the protected `product-release`
Environment. After independent Desktop acceptance, approval attests the exact convenience
artifacts with the protected workflow identity, publishes the GitHub Release, and applies its
Stable/Latest classification in one operation.
## One-time control-plane configuration
### GitHub Environment
The checked-in `.asf.yaml` is the authority for the `npm-publication`, `nightly`, and `product-release`
Environments. After it reaches
`main`, confirm ASF reconciliation produced:
- a selected `main` branch rule for `npm-publication`, with no approval gate so the
scheduled Nightly can publish automatically;
- a selected `main` branch rule for `nightly`, with no approval gate so Desktop Nightly can publish automatically;
- a selected `main` branch rule for `product-release`, with `M4n5ter` as required reviewer and
self-review disabled;
- administrator bypass disabled where repository policy permits it.
Repository administration permission is required to inspect or repair reconciliation. Do not maintain
a second manual Environment policy in GitHub. Finalize uses GitHub Actions OIDC to create Sigstore
provenance for the exact convenience artifacts and stores the offline verification bundle beside
them. It requires no repository-administration credential, signing key, or npm token.
### npm Trusted Publisher
In the `maka-agent` package settings, configure one GitHub Actions trusted publisher:
| Field | Value |
| --- | --- |
| Organization or user | `apache` |
| Repository | `maka` |
| Workflow filename | `npm-publication.yml` |
| Environment name | `npm-publication` |
| Allowed actions | `npm publish` and `npm stage publish` |
The workflow filename is case-sensitive and contains no `.github/workflows/` prefix. Both formal
staging and direct Nightly publication use the same `npm-publication` Environment. Its deployment
rules admit only `main`. It has no GitHub approval gate because the
scheduled Nightly is automatic; formal publication still requires human npm 2FA approval after
staging. Do not configure a second publisher or npm token.
After the first OIDC Stage succeeds, set package publishing access to **Require two-factor
authentication and disallow tokens**, then revoke obsolete publish tokens. Do not remove the human
package owner or recovery access as part of that change.
Keep the repository variable `NPM_NIGHTLY_ENABLED` unset until `.asf.yaml` has reconciled the
Environment and the Trusted Publisher matches it. Then set it to `true` and run one manual Nightly
before relying on the schedule. This variable controls npm only; Desktop has its own independent
`DESKTOP_NIGHTLY_ENABLED` rollout gate.
## Product Nightly
The scheduled `npm-publication.yml` run creates one immutable version such as
`0.2.0-dev.42.20260829` from the exact scheduled `main` commit, validates the four-platform
`maka-agent` tarball, and publishes it under `nightly`. Only after the exact version and dist-tag are
public does the successful workflow trigger `desktop-nightly.yml`. Desktop consumes only that
version; the authenticated upstream event supplies the exact source commit. The packaged Desktop
records the exact Runtime Host setup specifier, for example `maka-agent@0.2.0-dev.42.20260829`; it
never installs the mutable `nightly` tag.
The two workflows publish in this order:
1. require the candidate npm run number to be newer than the current `nightly` tag;
2. publish the exact npm tarball with provenance under `nightly`;
3. require both the exact version and `nightly` tag to be readable from the public registry;
4. build, verify, and attest the exact Desktop packages and GitHub `dev` metadata;
5. bind a protected `v<version>` tag to the exact source commit and verify all nine draft assets;
6. publish the GitHub prerelease with Latest disabled only after the draft is complete.
This ordering prevents Desktop from advertising a Runtime Host version that npm does not have and
keeps npm Nightly independent from Desktop packaging. A failed npm or Desktop run is never rerun in
place because each attempt has an immutable npm version; start a fresh npm Nightly run instead:
```sh
gh workflow run npm-publication.yml --ref main -f channel=nightly
```
Nightly is a developer snapshot, not an Apache release. Do not promote it from end-user download
pages. Developers may install the moving channel explicitly with `maka-agent@nightly`; product
automation must use the exact version recorded by Desktop.
## Prepare a release
1. Merge all intended package, documentation, and release changes to `main`, prepare the ASF source
candidate, and complete both the podling and Incubator PMC votes.
2. Confirm the root product version, `apps/desktop/package.json`, and
`packages/cli/package.json` have the same unused stable target version at the approved source
commit. Formal npm publication only advances `latest`.
3. Dispatch the product `Release` workflow from the exact approved
`v<version>-incubating-rc<rc>` tag, supplying that same tag as `source_reference_tag`. Confirm its
Draft `v<version>` Release points to the approved commit. npm staging consumes this identity and
cannot precede it.
4. Confirm the target version is absent from both public and staged package state:
```sh
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/
```
The first command should report that the target version is not present. Resolve any existing
stage instead of submitting the same version again.
5. Confirm the `npm-publication` Environment and Trusted Publisher still match the values above and the
approving npm account has 2FA enabled.
## Stage the candidate
1. Dispatch the workflow from reviewed `main`, supplying the exact product version:
```sh
version=0.2.0
gh workflow run npm-publication.yml --ref main \
-f channel=formal \
-f version="$version"
```
2. Confirm the created run uses `main`. The workflow resolves `v<version>` and its Draft as data,
requires that tag commit to remain an ancestor of `main`, builds the candidate without OIDC, and
binds npm provenance to the reviewed `main` publisher workflow and exact run.
3. Wait for the reusable package validation jobs to pass. They build one tarball and validate the
installed CLI on Linux x64/arm64, macOS arm64, and Windows x64, plus real Harbor and Pier
Docker cells on Linux x64.
4. Record the successful Stage workflow run ID, run attempt, source commit, version, and staged
artifact checksum from the run summary and `cli-staged-release-<attempt>` artifact.
Do not approve anything on npm if the Stage workflow did not finish successfully.
## Inspect and approve on npm
Use Node.js 22.14.0 or newer and npm 11.15.0 or newer for the inspection and approval commands below. The Stage workflow uses its own reviewed toolchain: the Node.js version pinned in the workflow and the exact npm version pinned in the repository's `packageManager`.
```sh
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/
```
Before approval:
- require the package name, version, dist-tag, provenance, and source repository to match the Stage
run;
- compare the downloaded staged tarball's SHA-256 with the workflow artifact's `.tgz.sha256`;
- inspect the file inventory and the packaged `README.md`;
- confirm the tarball belongs to the recorded Stage run and source commit.
Immediately before approval, recheck the live product authority recorded by the Stage run:
```sh
set -eu
source_commit=replace-with-stage-recorded-commit
node scripts/product-release-authority.mjs verify-draft \
"v$version" "$source_commit" apache/maka
```
The verifier must succeed. Stop if the tag is absent, moved, no longer on `main`, the matching
GitHub Release is no longer a stable Draft, or is marked as a prerelease.
Approve only that stage ID. npm requires 2FA and makes the package public as part of approval:
```sh
npm stage approve "$stage_id" --registry https://registry.npmjs.org/
```
The same review and approval can be performed from the package's **Staged Packages** page on
npmjs.com.
Inspect the public tags after approval:
```sh
version=0.1.0
npm view maka-agent dist-tags --json --registry https://registry.npmjs.org/
```
`latest` must identify the approved version. `nightly`, when present, remains independent.
## Finalize the product release
After npm reports the version as public:
1. Open **Actions → Finalize product release → Run workflow** on `main`.
2. Enter the successful Stage run ID and attempt, the successful Release build run ID and attempt,
and the version.
3. Let the inspection job verify the public tarball bytes, checksum, inventory, npm signature,
Trusted Publishing provenance, and the exact `latest` dist-tag.
4. While the publication job waits for `product-release` approval, complete the product checklist's
cross-machine acceptance against the Draft.
5. Approve the Environment. Confirm the workflow matches every live Draft digest to the exact
Release attempt's publication record, creates and uploads
`Maka-<version>-attestation.sigstore.json`, publishes the convenience Release, and makes a stable
release Latest without a separate manual action.
Check the resulting registry state:
```sh
version=0.2.0
npm view "maka-agent@$version" version dist.tarball dist.integrity --json
npm view maka-agent dist-tags --json
```
Finally, install the exact public version on each release platform and complete one real TUI/model
turn. On the supported Eval host, complete at least one real experiment cell and inspect score,
usage, cost, and artifacts.
The [product release checklist](../.github/RELEASE_CHECKLIST.md) remains the authority for the
acceptance evidence required before approving publication.
## Failure recovery
### Before npm staging
If a transient failure occurs before `npm stage publish`, rerun Stage from the same product tag. If code or workflow changes are required, fix them on `main`, increment the product version, create a new product tag and Draft, and Stage that new version. No npm version has been consumed.
### Stage workflow failed but npm contains a stage
The submission is the Stage workflow's final business step, so a lost response can leave npm with a
stage even when the workflow is not successful. Do not approve that orphan: Finalize accepts only a
successful Stage run attempt.
Inspect it, then reject the exact stage ID with 2FA before starting a new Stage run:
```sh
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/
```
Never reject a stage based only on version text; bind the action to the inspected stage ID.
### Stage succeeded but review found a problem
Reject the stage, fix the problem on `main`, increment the product version, create a new product tag and Draft, and Stage that new version. Do not approve a candidate merely to clear the staging area.
### npm approval succeeded but Finalize failed
The npm version is already immutable. Do not publish or approve it again. Preserve the Stage run ID,
attempt, version, and the Release run ID, attempt, publication record, and artifacts. If those bytes
and provenance are valid, fix the Finalize verifier on `main` and rerun it against the same immutable
Stage and Release evidence.
The inspection job is read-only. Only the protected publication job may perform the single
Draft-to-published transition and attest its bytes. If npm identity, build evidence, or the Draft differs, stop and
investigate; do not modify the product tag or GitHub Release to make verification pass. If failure is
reported after the publication request, inspect the exact Release first: a successful publication
must not be repeated.
### The public version is defective
First move the affected dist-tag back to a previously verified version:
```sh
known_good=0.2.0
npm dist-tag add "maka-agent@$known_good" latest
```
Then deprecate only the defective version and direct users to the recovered dist-tag, which already
points to the verified version:
```sh
bad_version=0.2.1
recovery_tag=latest
npm deprecate "maka-agent@$bad_version" "Known issue; install maka-agent@$recovery_tag."
```
Verify the tags, fix the defect, and release a new version through the complete Stage and Finalize
flow. Do not use `npm unpublish` as routine rollback: removing immutable dependency bytes can break
existing installations and does not restore the reviewed release chain.
For a defective Nightly, dispatch a fresh run so a new immutable version advances `nightly`. If an
immediate rollback is required, a human package owner may move `nightly` to a previously verified
Nightly version and deprecate only the defective exact version. Never point `latest` at a Nightly.
## Ownership and emergency recovery
- GitHub repository admins own the `npm-publication` Environment configuration. The release maintainer
owns dispatch, staged-package inspection, npm 2FA approval, and final
acceptance.
- npm package owners own Trusted Publisher, publishing-access, maintainer, and dist-tag recovery.
- Keep at least one 2FA-protected human owner while trusted publishing is active. Before removing the
current direct owner, add the intended npm organization publishing team and another direct human
recovery maintainer, then verify both paths.
- The workflows must not gain a long-lived npm token. If OIDC, the Environment, or the trust
relationship is broken, pause releases and repair that control plane instead of bypassing staging
with `npm publish`.
- If an npm account is lost, use its account recovery methods or another verified package owner.
Until a second owner is established, recovery depends on the current owner's npm recovery
credentials; treat completing that ownership follow-up as operational debt.
- If repository or npm publisher settings change unexpectedly, remove or disable the trust
relationship, preserve workflow and npm audit evidence, restore the reviewed configuration, and
use a new version for any candidate whose integrity is uncertain.
## References
- [ASF Incubator distribution guide: npm](https://incubator.apache.org/guides/distribution.html#npm)
- [Apache OpenDAL incubating Node.js release workflow](https://github.com/apache/opendal/blob/v0.44.0/.github/workflows/bindings_nodejs.yml)
- [Apache OpenDAL incubating release guide](https://github.com/apache/opendal/blob/v0.44.0/website/community/committers/release.md)
- [npm staged publishing](https://docs.npmjs.com/staged-publishing/)
- [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/)
- [npm dist-tags](https://docs.npmjs.com/cli/dist-tag/)
- [npm deprecation](https://docs.npmjs.com/cli/v11/commands/npm-deprecate/)
- [GitHub deployment environments](https://docs.github.com/en/actions/reference/workflows-and-actions/deployments-and-environments)