From a1201e99fc26573e44bdd87ee3f2ead475b07344 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 20 Jun 2026 21:46:57 +0200 Subject: [PATCH] fix(release): validate npm publish wrapper args --- scripts/openclaw-npm-publish.sh | 30 ++++++++-- test/scripts/openclaw-npm-publish.test.ts | 70 +++++++++++++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 test/scripts/openclaw-npm-publish.test.ts diff --git a/scripts/openclaw-npm-publish.sh b/scripts/openclaw-npm-publish.sh index cad512195aea..95bf6d5b3ae6 100644 --- a/scripts/openclaw-npm-publish.sh +++ b/scripts/openclaw-npm-publish.sh @@ -2,11 +2,33 @@ set -euo pipefail -mode="${1:-}" -publish_target="${2:-}" +usage() { + echo "usage: bash scripts/openclaw-npm-publish.sh --publish [package.tgz]" +} -if [[ "${mode}" != "--publish" ]]; then - echo "usage: bash scripts/openclaw-npm-publish.sh --publish [package.tgz]" >&2 +if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then + usage + exit 0 +fi + +if [[ "${1:-}" != "--publish" ]]; then + usage >&2 + exit 2 +fi +shift + +publish_target="" +if [[ "${1:-}" == "--" ]]; then + shift +fi +if [[ "$#" -gt 0 ]]; then + case "$1" in + -*) echo "error: unexpected npm publish target option: $1" >&2; exit 2 ;; + *) publish_target="$1"; shift ;; + esac +fi +if [[ "$#" -gt 0 ]]; then + echo "error: unexpected npm publish argument: $1" >&2 exit 2 fi diff --git a/test/scripts/openclaw-npm-publish.test.ts b/test/scripts/openclaw-npm-publish.test.ts new file mode 100644 index 000000000000..db4c1d9adb82 --- /dev/null +++ b/test/scripts/openclaw-npm-publish.test.ts @@ -0,0 +1,70 @@ +// OpenClaw NPM Publish tests cover publish wrapper argument safety. +import { spawnSync } from "node:child_process"; +import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import { afterEach, describe, expect, it } from "vitest"; + +const scriptPath = "scripts/openclaw-npm-publish.sh"; +const tempDirs: string[] = []; + +function makeTempDir(prefix: string): string { + const dir = mkdtempSync(path.join(tmpdir(), prefix)); + tempDirs.push(dir); + return dir; +} + +function runPublishWrapper(args: string[]) { + return spawnSync("bash", [scriptPath, ...args], { + cwd: process.cwd(), + encoding: "utf8", + }); +} + +afterEach(() => { + for (const dir of tempDirs.splice(0)) { + rmSync(dir, { force: true, recursive: true }); + } +}); + +describe("openclaw npm publish wrapper", () => { + it("prints help without resolving release metadata", () => { + const result = runPublishWrapper(["--help"]); + + expect(result.status).toBe(0); + expect(result.stdout.trim()).toBe( + "usage: bash scripts/openclaw-npm-publish.sh --publish [package.tgz]", + ); + expect(result.stderr).toBe(""); + }); + + it("rejects missing publish mode before resolving release metadata", () => { + const result = runPublishWrapper([]); + + expect(result.status).toBe(2); + expect(result.stdout).toBe(""); + expect(result.stderr.trim()).toBe( + "usage: bash scripts/openclaw-npm-publish.sh --publish [package.tgz]", + ); + }); + + it("rejects option-like publish targets before npm publish", () => { + const result = runPublishWrapper(["--publish", "--tag"]); + + expect(result.status).toBe(2); + expect(result.stdout).toBe(""); + expect(result.stderr.trim()).toBe("error: unexpected npm publish target option: --tag"); + }); + + it("rejects extra publish arguments before npm publish", () => { + const tempRoot = makeTempDir("openclaw-npm-publish-"); + const tarball = path.join(tempRoot, "openclaw.tgz"); + writeFileSync(tarball, "placeholder", "utf8"); + + const result = runPublishWrapper(["--publish", tarball, "extra"]); + + expect(result.status).toBe(2); + expect(result.stdout).toBe(""); + expect(result.stderr.trim()).toBe("error: unexpected npm publish argument: extra"); + }); +});