mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix: stop --tag main from failing during npm pack (#125949)
* fix: refuse unsupported OpenClaw source package updates * refactor: narrow main update refusal
This commit is contained in:
committed by
GitHub
parent
3116923ff7
commit
bb92dc61c8
+10
-11
@@ -26,7 +26,6 @@ openclaw update --channel extended-stable
|
||||
openclaw update --channel beta
|
||||
openclaw update --channel dev
|
||||
openclaw update --tag beta
|
||||
openclaw update --tag main
|
||||
openclaw update --dry-run
|
||||
openclaw update --no-restart
|
||||
openclaw update --yes
|
||||
@@ -40,16 +39,16 @@ launcher scripts).
|
||||
|
||||
## Options
|
||||
|
||||
| Flag | Description |
|
||||
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--no-restart` | Skip restarting the Gateway service after a successful update. Package-manager updates that do restart verify the restarted service reports the expected version before the command succeeds. |
|
||||
| `--channel <stable\|extended-stable\|beta\|dev>` | Set the update channel and persist it after core update success. Extended-stable is package-only. |
|
||||
| `--tag <dist-tag\|version\|spec>` | Override the package target for this update only. It cannot be combined with an effective `extended-stable` channel, whose verified exact target is mandatory. For other package installs, `main` maps to `github:openclaw/openclaw#main`; GitHub/git source specs are packed into a temporary tarball before the staged global npm install. |
|
||||
| `--dry-run` | Preview planned actions (channel/tag/target/restart flow) without writing config, installing, syncing plugins, or restarting. |
|
||||
| `--json` | Print machine-readable `UpdateRunResult` JSON. Includes `postUpdate.plugins.warnings` when a managed plugin needs repair, beta-channel plugin fallback details, and `postUpdate.plugins.integrityDrifts` when npm plugin artifact drift is detected during post-update sync. |
|
||||
| `--timeout <seconds>` | Per-step timeout. Default `1800`. |
|
||||
| `--yes` | Skip confirmation prompts (for example downgrade confirmation). |
|
||||
| `--acknowledge-clawhub-risk` | Allow post-update plugin sync to continue past community ClawHub trust warnings without an interactive prompt. Without it, risky community releases are skipped and left unchanged when OpenClaw cannot prompt. Official ClawHub packages and bundled plugin sources bypass this prompt. |
|
||||
| Flag | Description |
|
||||
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--no-restart` | Skip restarting the Gateway service after a successful update. Package-manager updates that do restart verify the restarted service reports the expected version before the command succeeds. |
|
||||
| `--channel <stable\|extended-stable\|beta\|dev>` | Set the update channel and persist it after core update success. Extended-stable is package-only. |
|
||||
| `--tag <dist-tag\|version\|spec>` | Override the package target for this update only. It cannot be combined with an effective `extended-stable` channel, whose verified exact target is mandatory. Package installs reject the `main` shorthand; use `--channel dev` for the supported checkout and build flow. Other explicit package specs keep their package-manager behavior. |
|
||||
| `--dry-run` | Preview planned actions (channel/tag/target/restart flow) without writing config, installing, syncing plugins, or restarting. |
|
||||
| `--json` | Print machine-readable `UpdateRunResult` JSON. Includes `postUpdate.plugins.warnings` when a managed plugin needs repair, beta-channel plugin fallback details, and `postUpdate.plugins.integrityDrifts` when npm plugin artifact drift is detected during post-update sync. |
|
||||
| `--timeout <seconds>` | Per-step timeout. Default `1800`. |
|
||||
| `--yes` | Skip confirmation prompts (for example downgrade confirmation). |
|
||||
| `--acknowledge-clawhub-risk` | Allow post-update plugin sync to continue past community ClawHub trust warnings without an interactive prompt. Without it, risky community releases are skipped and left unchanged when OpenClaw cannot prompt. Official ClawHub packages and bundled plugin sources bypass this prompt. |
|
||||
|
||||
There is no `--verbose` flag. Use `--dry-run` to preview planned actions,
|
||||
`--json` for machine-readable results, and `openclaw update status --json`
|
||||
|
||||
@@ -75,8 +75,6 @@ openclaw update --channel dev
|
||||
# Install a specific npm package spec
|
||||
openclaw update --tag openclaw@2026.4.1-beta.1
|
||||
|
||||
# Install from GitHub main once without persisting the channel
|
||||
openclaw update --tag main
|
||||
```
|
||||
|
||||
Notes:
|
||||
@@ -84,13 +82,11 @@ Notes:
|
||||
- `--tag` applies to **package (npm) installs only**; git installs ignore it.
|
||||
- The tag is not persisted; the next `openclaw update` uses the configured
|
||||
channel.
|
||||
- `--tag main` maps to the npm-compatible spec `github:openclaw/openclaw#main`
|
||||
for that one run. For a persistent moving `main` install, use
|
||||
- The `--tag main` shorthand is rejected for package installs because the
|
||||
workspace checkout is not a self-contained package artifact. Use
|
||||
`openclaw update --channel dev` (package installs switch to a git checkout)
|
||||
or reinstall with the installer's git method:
|
||||
`curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git --version main`.
|
||||
The npm install path rejects GitHub/git source targets outright and points
|
||||
you at the git method instead.
|
||||
- Downgrade protection: if the target version is older than the current
|
||||
version, OpenClaw prompts for confirmation (skip with `--yes`).
|
||||
- Extended-stable always uses its verified exact package target. It is not a
|
||||
|
||||
@@ -60,9 +60,11 @@ OpenClaw cannot safely distinguish an old automatic pin from a user pin; run
|
||||
`openclaw plugins update @openclaw/name` once on the extended-stable channel
|
||||
to opt that plugin back into exact-core tracking.
|
||||
|
||||
`--channel dev` gives a persistent moving GitHub `main` checkout. For a one-off
|
||||
package update, `--tag main` maps to the `github:openclaw/openclaw#main` package
|
||||
spec and installs it directly through the target package manager (npm/pnpm/bun).
|
||||
`--channel dev` gives a persistent moving GitHub `main` checkout. Package
|
||||
installs reject the `--tag main` shorthand because the workspace checkout is
|
||||
not a self-contained package artifact. Use `openclaw update --channel dev` to
|
||||
switch to the supported checkout and build flow. Other explicit package specs
|
||||
keep their package-manager behavior.
|
||||
|
||||
For managed plugins, a missing beta release is a warning, not a failure: the
|
||||
core update can still succeed while a plugin falls back to its recorded
|
||||
|
||||
@@ -4355,12 +4355,6 @@ describe("update-cli", () => {
|
||||
packageSpec: undefined,
|
||||
expectedSpec: "openclaw@9999.0.0",
|
||||
},
|
||||
{
|
||||
name: "main shorthand",
|
||||
options: { yes: true, tag: "main" },
|
||||
packageSpec: undefined,
|
||||
expectedSpec: "github:openclaw/openclaw#main",
|
||||
},
|
||||
{
|
||||
name: "explicit git package spec",
|
||||
options: { yes: true, tag: "github:openclaw/openclaw#main" },
|
||||
@@ -4429,6 +4423,33 @@ describe("update-cli", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
{ name: "real run", options: { yes: true, json: true, tag: "main" } },
|
||||
{ name: "normalized alias", options: { yes: true, json: true, tag: "openclaw@main" } },
|
||||
{
|
||||
name: "dry-run",
|
||||
options: { dryRun: true, json: true, tag: "main", yes: true },
|
||||
},
|
||||
] as const)("refuses --tag main before package resolution: $name", async ({ options }) => {
|
||||
mockPackageInstallStatus(createCaseDir("openclaw-update-main-refusal"));
|
||||
|
||||
await updateCommand(options);
|
||||
|
||||
const result = lastWriteJsonCall() as UpdateRunResult | undefined;
|
||||
expect(result).toMatchObject({
|
||||
status: "error",
|
||||
reason: "unsupported-package-target",
|
||||
steps: [],
|
||||
});
|
||||
expect(packageInstallCommandCall()).toBeUndefined();
|
||||
expectNoSideEffects(resolveGlobalManager, replaceConfigFile, runGatewayUpdate);
|
||||
if ("dryRun" in options && options.dryRun) {
|
||||
expect(cleanupStaleManagedServiceUpdateHandoffs).not.toHaveBeenCalled();
|
||||
}
|
||||
expect(defaultRuntime.exit).toHaveBeenCalledWith(1);
|
||||
expect(getErrorOutput()).toContain("openclaw update --channel dev");
|
||||
});
|
||||
|
||||
it("fails package updates when the installed correction version does not match the requested target", async () => {
|
||||
const tempDir = createCaseDir("openclaw-update");
|
||||
const nodeModules = path.join(tempDir, "node_modules");
|
||||
|
||||
@@ -165,7 +165,6 @@ export function registerUpdateCli(program: Command) {
|
||||
["openclaw update --channel beta", "Switch to beta channel (git + npm)"],
|
||||
["openclaw update --channel dev", "Switch to dev channel (git + npm)"],
|
||||
["openclaw update --tag beta", "One-off update to a dist-tag or version"],
|
||||
["openclaw update --tag main", "One-off package update from GitHub main"],
|
||||
["openclaw update --dry-run", "Preview actions without changing anything"],
|
||||
["openclaw update --no-restart", "Update without restarting the service"],
|
||||
["openclaw update --json", "Output result as JSON"],
|
||||
@@ -187,7 +186,7 @@ ${theme.heading("Switch channels:")}
|
||||
- Use --channel stable|extended-stable|beta|dev to persist the update channel in config
|
||||
- Run openclaw update status to see the active channel and source
|
||||
- Use --tag <dist-tag|version|spec> for a one-off package update without persisting
|
||||
- Use --tag main for a one-off package update from GitHub main
|
||||
- Use --channel dev for the moving GitHub main checkout; package installs reject --tag main
|
||||
|
||||
${theme.heading("Non-interactive:")}
|
||||
- Use --yes to accept downgrade prompts
|
||||
|
||||
@@ -106,7 +106,8 @@ export async function reportPreMutationUpdateFailure(params: {
|
||||
reason:
|
||||
| ExtendedStableFailureReason
|
||||
| typeof EXTENDED_STABLE_TAG_UNSUPPORTED_REASON
|
||||
| "npm lifecycle policy preflight";
|
||||
| "npm lifecycle policy preflight"
|
||||
| "unsupported-package-target";
|
||||
message?: string;
|
||||
opts: UpdateCommandOptions;
|
||||
controlPlaneUpdateSentinelMeta: ControlPlaneUpdateSentinelMetaFile["meta"] | null;
|
||||
|
||||
@@ -289,11 +289,17 @@ async function updateCommandInternal(
|
||||
}
|
||||
|
||||
const explicitTag = normalizeTag(opts.tag);
|
||||
if (channel === "extended-stable" && explicitTag) {
|
||||
const unsupportedMainTag = updateInstallKind === "package" && explicitTag === "main";
|
||||
if ((channel === "extended-stable" && explicitTag) || unsupportedMainTag) {
|
||||
await reportPreMutationUpdateFailure({
|
||||
root,
|
||||
installKind: updateInstallKind,
|
||||
reason: EXTENDED_STABLE_TAG_UNSUPPORTED_REASON,
|
||||
reason: unsupportedMainTag
|
||||
? "unsupported-package-target"
|
||||
: EXTENDED_STABLE_TAG_UNSUPPORTED_REASON,
|
||||
message: unsupportedMainTag
|
||||
? "`--tag main` cannot update a package install. Run `openclaw update --channel dev` to switch to the supported Git checkout and build flow."
|
||||
: undefined,
|
||||
opts,
|
||||
controlPlaneUpdateSentinelMeta,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user