fix(release): keep package output names local · openclaw/openclaw@b67775f
vincentkoc
·
2026-06-17
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -78,6 +78,12 @@ function readEqualsOptionValue(value, optionName) {
|
78 | 78 | return value; |
79 | 79 | } |
80 | 80 | |
| 81 | +function validateOutputName(value) { |
| 82 | +if (!/^[A-Za-z0-9][A-Za-z0-9._-]*\.t(?:ar\.)?gz$/u.test(value)) { |
| 83 | +throw new Error(`--output-name must be a tarball filename, not a path: ${value}`); |
| 84 | +} |
| 85 | +} |
| 86 | + |
81 | 87 | export function parseArgs(argv) { |
82 | 88 | const options = { |
83 | 89 | outputDir: "", |
@@ -111,6 +117,9 @@ export function parseArgs(argv) {
|
111 | 117 | throw new Error(`unknown argument: ${arg}`); |
112 | 118 | } |
113 | 119 | } |
| 120 | +if (options.outputName) { |
| 121 | +validateOutputName(options.outputName); |
| 122 | +} |
114 | 123 | return options; |
115 | 124 | } |
116 | 125 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -131,9 +131,16 @@ export function parseArgs(argv) {
|
131 | 131 | throw new Error(`unknown argument: ${arg}`); |
132 | 132 | } |
133 | 133 | } |
| 134 | +validateOutputName(options.outputName); |
134 | 135 | return options; |
135 | 136 | } |
136 | 137 | |
| 138 | +function validateOutputName(value) { |
| 139 | +if (!/^[A-Za-z0-9][A-Za-z0-9._-]*\.t(?:ar\.)?gz$/u.test(value)) { |
| 140 | +throw new Error(`--output-name must be a tarball filename, not a path: ${value}`); |
| 141 | +} |
| 142 | +} |
| 143 | + |
137 | 144 | export function validateOpenClawPackageSpec(spec) { |
138 | 145 | if (!OPENCLAW_PACKAGE_SPEC_RE.test(spec)) { |
139 | 146 | throw new Error( |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -96,6 +96,23 @@ describe("package-openclaw-for-docker", () => {
|
96 | 96 | } |
97 | 97 | }); |
98 | 98 | |
| 99 | +it("rejects package artifact output names that escape the output directory", () => { |
| 100 | +for (const outputName of [ |
| 101 | +"../openclaw-current.tgz", |
| 102 | +"nested/openclaw-current.tgz", |
| 103 | +"openclaw-current.zip", |
| 104 | +".openclaw-current.tgz", |
| 105 | +]) { |
| 106 | +expect(() => parseArgs(["--output-name", outputName])).toThrow( |
| 107 | +`--output-name must be a tarball filename, not a path: ${outputName}`, |
| 108 | +); |
| 109 | +} |
| 110 | + |
| 111 | +expect(parseArgs(["--output-name", "openclaw-current.tar.gz"]).outputName).toBe( |
| 112 | +"openclaw-current.tar.gz", |
| 113 | +); |
| 114 | +}); |
| 115 | + |
99 | 116 | it("uses build-all as the single bounded package artifact build step", async () => { |
100 | 117 | const calls: Array<{ |
101 | 118 | command: string; |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -165,6 +165,23 @@ describe("resolve-openclaw-package-candidate", () => {
|
165 | 165 | }); |
166 | 166 | }); |
167 | 167 | |
| 168 | +it("rejects package candidate output names that escape the output directory", () => { |
| 169 | +for (const outputName of [ |
| 170 | +"../openclaw-current.tgz", |
| 171 | +"nested/openclaw-current.tgz", |
| 172 | +"openclaw-current.zip", |
| 173 | +".openclaw-current.tgz", |
| 174 | +]) { |
| 175 | +expect(() => parseArgs(["--output-name", outputName])).toThrow( |
| 176 | +`--output-name must be a tarball filename, not a path: ${outputName}`, |
| 177 | +); |
| 178 | +} |
| 179 | + |
| 180 | +expect(parseArgs(["--output-name", "openclaw-current.tar.gz"]).outputName).toBe( |
| 181 | +"openclaw-current.tar.gz", |
| 182 | +); |
| 183 | +}); |
| 184 | + |
168 | 185 | it("resolves npm package candidates through the Windows npm.cmd toolchain shim", () => { |
169 | 186 | const execPath = "C:\\nodejs\\node.exe"; |
170 | 187 | const npmCmdPath = path.win32.resolve(path.win32.dirname(execPath), "npm.cmd"); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。