Skip to content

Commit 092f1b4

Browse files
Timcodex
andcommitted
Restore bundled CLI permissions before publishing npm archives
Artifact downloads strip executable modes. Restore both Unix CLI modes before packing, then smoke-test the actual npm archive and its native addon and CLI. The current 0.51.1 archive fails this check before the permission repair and passes afterward; the published npm version is immutable. Co-Authored-By: OpenAI Codex <noreply@openai.com>
1 parent 4596413 commit 092f1b4

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎.github/workflows/publish.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ jobs:
105105
- name: Install dependencies (skip build — we have prebuilts)
106106
run: npm install --ignore-scripts
107107

108+
- name: Restore bundled CLI permissions
109+
run: chmod 755 prebuilds/linux-x64/doltlite prebuilds/darwin-arm64/doltlite
110+
111+
- name: Smoke test npm archive
112+
run: node scripts/test-package.js
113+
108114
- name: Verify npm publish identity
109115
run: |
110116
npm config get registry

‎scripts/test-package.js‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"use strict"
2+
3+
const assert = require("node:assert/strict")
4+
const fs = require("node:fs")
5+
const os = require("node:os")
6+
const path = require("node:path")
7+
const { execFileSync } = require("node:child_process")
8+
9+
const root = path.resolve(__dirname, "..")
10+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "doltlite-package-"))
11+
12+
try {
13+
const packed = JSON.parse(execFileSync("npm", [
14+
"pack", "--ignore-scripts", "--json", "--pack-destination", tmp,
15+
], { cwd: root, encoding: "utf8" }))
16+
execFileSync("tar", ["xzf", path.join(tmp, packed[0].filename), "-C", tmp])
17+
const packageRoot = path.join(tmp, "package")
18+
for (const platform of ["linux-x64", "darwin-arm64"]) {
19+
const cli = path.join(packageRoot, "prebuilds", platform, "doltlite")
20+
assert.notEqual(fs.statSync(cli).mode & 0o111, 0, `${platform} CLI is not executable`)
21+
}
22+
const { DatabaseSync, binPath } = require(packageRoot)
23+
const db = new DatabaseSync(":memory:")
24+
try {
25+
assert.equal(db.prepare("SELECT doltlite_engine() AS engine").get().engine, "prolly")
26+
db.exec("CREATE TABLE t(id INTEGER PRIMARY KEY); INSERT INTO t VALUES(1)")
27+
assert.equal(db.prepare("SELECT count(*) AS n FROM t").get().n, 1)
28+
} finally {
29+
db.close()
30+
}
31+
assert.equal(execFileSync(binPath(), [":memory:", "SELECT doltlite_engine();"], {
32+
encoding: "utf8",
33+
}).trim(), "prolly")
34+
console.log("npm archive: native addon and executable bundled CLIs PASS")
35+
} finally {
36+
fs.rmSync(tmp, { recursive: true, force: true })
37+
}

0 commit comments

Comments
 (0)