From f44f5b20573d0ddcefc98ef43d69f9482b5a9c2b Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 13:43:36 -0700 Subject: [PATCH 1/9] Add Windows ARM64 prebuild coverage --- .github/workflows/ci.yml | 188 ++++++++++++++++++++++++------ README.md | 2 +- libopus/config/win/arm64/config.h | 45 +++++++ scripts/verify-packed-package.mjs | 98 ++++++++++++++++ src/tests/test.js | 14 ++- 5 files changed, 305 insertions(+), 42 deletions(-) create mode 100644 libopus/config/win/arm64/config.h create mode 100644 scripts/verify-packed-package.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26ee50b..d7e0841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ jobs: - ubuntu-22.04 - ubuntu-22.04-arm - windows-2022 + - windows-11-arm steps: - name: Checkout repository @@ -77,6 +78,13 @@ jobs: if: matrix.node == 24 run: pnpm prebuild + - name: Test selected N-API prebuild + if: matrix.node == 24 + env: + PREBUILDS_ONLY: "1" + LIBOPUS_TEST_NATIVE: "1" + run: pnpm test-native + - name: Run tests run: pnpm test @@ -131,7 +139,8 @@ jobs: if [ "${{ matrix.node }}" = "24" ]; then # Build N-API prebuilds for musl, tagging libc so node-gyp-build # can prefer them on Alpine. - pnpm prebuild + pnpm prebuild && + PREBUILDS_ONLY=1 LIBOPUS_TEST_NATIVE=1 pnpm test-native fi && pnpm test ' @@ -179,7 +188,7 @@ jobs: # package builds run in the platform-native jobs above; this job # verifies the OpenBSD prebuild itself. pnpm prebuild - LIBOPUS_TEST_NATIVE=1 node src/tests/test.js + PREBUILDS_ONLY=1 LIBOPUS_TEST_NATIVE=1 node src/tests/test.js - name: Archive OpenBSD prebuilds run: tar -czf prebuilds-openbsd-x64.tar.gz -C prebuilds . @@ -190,10 +199,10 @@ jobs: name: prebuild-openbsd-x64 path: prebuilds-openbsd-x64.tar.gz - verify_release_artifact: - name: Verify packed release on Alpine Linux arm64 + package_release_candidate: + name: Assemble packed release candidate needs: [quality, build, build_musl, build_openbsd] - runs-on: ubuntu-22.04-arm + runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v5 @@ -255,47 +264,152 @@ jobs: exit 1 fi - - name: Verify the packed module in native Alpine arm64 + - name: Upload packed release candidate + uses: actions/upload-artifact@v6 + with: + name: release-candidate + path: artifacts/package/*.tgz + + verify_release_artifact: + name: Verify packed release on ${{ matrix.name }} + needs: package_release_candidate + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - name: Linux glibc x64 + runner: ubuntu-22.04 + platform: linux + architecture: x64 + libc: glibc + - name: Linux glibc arm64 + runner: ubuntu-22.04-arm + platform: linux + architecture: arm64 + libc: glibc + - name: macOS x64 + runner: macos-15-intel + platform: darwin + architecture: x64 + libc: glibc + - name: macOS arm64 + runner: macos-15 + platform: darwin + architecture: arm64 + libc: glibc + - name: Windows x64 + runner: windows-2022 + platform: win32 + architecture: x64 + libc: glibc + - name: Windows arm64 + runner: windows-11-arm + platform: win32 + architecture: arm64 + libc: glibc + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 24 + + - name: Download packed release candidate + uses: actions/download-artifact@v7 + with: + name: release-candidate + path: artifacts/package + + - name: Install and test the packed module + env: + LIBOPUS_EXPECTED_PLATFORM: ${{ matrix.platform }} + LIBOPUS_EXPECTED_ARCH: ${{ matrix.architecture }} + LIBOPUS_EXPECTED_LIBC: ${{ matrix.libc }} + run: node scripts/verify-packed-package.mjs artifacts/package + + verify_release_artifact_musl: + name: Verify packed release on Alpine Linux ${{ matrix.architecture }} + needs: package_release_candidate + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - architecture: x64 + runner: ubuntu-22.04 + - architecture: arm64 + runner: ubuntu-22.04-arm + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Download packed release candidate + uses: actions/download-artifact@v7 + with: + name: release-candidate + path: artifacts/package + + - name: Install and test the packed module in Alpine run: | set -euo pipefail - tar -tzf artifacts/package/*.tgz | grep -E '^package/prebuilds/linux-arm64/.*\.musl\.node$' docker run --rm \ - -v "${{ github.workspace }}/artifacts/package:/package:ro" \ + -v "${{ github.workspace }}:/work:ro" \ + -w /work \ + -e LIBOPUS_EXPECTED_PLATFORM=linux \ + -e LIBOPUS_EXPECTED_ARCH=${{ matrix.architecture }} \ + -e LIBOPUS_EXPECTED_LIBC=musl \ node:24-alpine \ sh -lc ' set -euo pipefail - test "$(uname -m)" = aarch64 - mkdir /consumer - cd /consumer - npm init --yes >/dev/null - npm install --foreground-scripts /package/*.tgz - node - <<"NODE" - const assert = require("node:assert"); - const fs = require("node:fs"); - const { createRequire } = require("node:module"); - const path = require("node:path"); - - const packageRoot = path.resolve("node_modules/libopus-node"); - const packageRequire = createRequire(path.join(packageRoot, "package.json")); - const selected = packageRequire("node-gyp-build").resolve(packageRoot); - - assert.match(selected, /\/prebuilds\/linux-arm64\/.*\.musl\.node$/); - assert(!fs.existsSync(path.join(packageRoot, "build"))); - console.log(`Selected Alpine arm64 musl prebuild: ${selected}`); - NODE - node --input-type=module -e " - import { OpusEncoder } from \"libopus-node\"; - const encoder = new OpusEncoder(16_000, 1); - const pcm = Buffer.alloc(640); - for (let i = 0; i < 320; i++) { - pcm.writeInt16LE(Math.round(12_000 * Math.sin((2 * Math.PI * i) / 40)), i * 2); - } - if (encoder.encode(pcm).length === 0) throw new Error(\"Encoder produced no packet\"); - " + node scripts/verify-packed-package.mjs artifacts/package ' + verify_release_artifact_openbsd: + name: Verify packed release on OpenBSD x86-64 + needs: package_release_candidate + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Download packed release candidate + uses: actions/download-artifact@v7 + with: + name: release-candidate + path: artifacts/package + + - name: Start OpenBSD VM + uses: cross-platform-actions/action@v1.4.0 + with: + operating_system: openbsd + version: "7.8" + architecture: x86-64 + + - name: Install and test the packed module on OpenBSD + shell: cpa.sh {0} + run: | + set -euo pipefail + sudo pkg_add node npm + LIBOPUS_EXPECTED_PLATFORM=openbsd \ + LIBOPUS_EXPECTED_ARCH=x64 \ + LIBOPUS_EXPECTED_LIBC=glibc \ + node scripts/verify-packed-package.mjs artifacts/package + publish: - needs: [quality, build, build_musl, build_openbsd, verify_release_artifact] + needs: + - quality + - build + - build_musl + - build_openbsd + - package_release_candidate + - verify_release_artifact + - verify_release_artifact_musl + - verify_release_artifact_openbsd if: github.event_name == 'push' && github.ref == 'refs/heads/main' uses: ./.github/workflows/publish.yml permissions: diff --git a/README.md b/README.md index 0c3a36c..38827ca 100644 --- a/README.md +++ b/README.md @@ -310,7 +310,7 @@ Prebuilt binaries are provided for: | Linux (glibc) | x64, arm64 | | Linux (musl) | x64, arm64 | | macOS | x64, arm64 | -| Windows | x64 | +| Windows | x64, arm64 | | OpenBSD | x64 | If a prebuilt binary is not available for your platform, the package cannot be used on that platform. diff --git a/libopus/config/win/arm64/config.h b/libopus/config/win/arm64/config.h new file mode 100644 index 0000000..4db84bd --- /dev/null +++ b/libopus/config/win/arm64/config.h @@ -0,0 +1,45 @@ +/*********************************************************************** +Copyright (c) 2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H + +#define USE_ALLOCA 1 + +/* Comment out the next line for floating-point code */ +/* #define FIXED_POINT 1 */ + +/* AArch64 requires NEON and MSVC supplies the corresponding intrinsics. */ +#define OPUS_ARM_MAY_HAVE_NEON_INTR 1 +#define OPUS_ARM_PRESUME_AARCH64_NEON_INTR 1 +#define OPUS_ARM_PRESUME_NEON_INTR 1 + +#define OPUS_BUILD 1 + +#define PACKAGE_VERSION "1.3.1" + +#endif /* CONFIG_H */ diff --git a/scripts/verify-packed-package.mjs b/scripts/verify-packed-package.mjs new file mode 100644 index 0000000..7e816a2 --- /dev/null +++ b/scripts/verify-packed-package.mjs @@ -0,0 +1,98 @@ +import assert from "node:assert"; +import { spawnSync } from "node:child_process"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { createRequire } from "node:module"; + +const artifactDirectory = process.argv[2]; +const expectedPlatform = process.env.LIBOPUS_EXPECTED_PLATFORM; +const expectedArchitecture = process.env.LIBOPUS_EXPECTED_ARCH; +const expectedLibc = process.env.LIBOPUS_EXPECTED_LIBC; + +assert(artifactDirectory, "Usage: node scripts/verify-packed-package.mjs "); +assert(expectedPlatform, "LIBOPUS_EXPECTED_PLATFORM must be set"); +assert(expectedArchitecture, "LIBOPUS_EXPECTED_ARCH must be set"); +assert(expectedLibc, "LIBOPUS_EXPECTED_LIBC must be set"); +assert.strictEqual( + process.platform, + expectedPlatform, + "Verification must run on the expected platform", +); +assert.strictEqual( + process.arch, + expectedArchitecture, + "Verification must run on the expected architecture", +); + +const tarballs = fs + .readdirSync(artifactDirectory) + .filter((file) => file.endsWith(".tgz")) + .map((file) => path.resolve(artifactDirectory, file)); +assert.strictEqual(tarballs.length, 1, "Expected exactly one packed release candidate"); + +const consumerDirectory = fs.mkdtempSync(path.join(os.tmpdir(), "libopus-node-consumer-")); +const npm = process.platform === "win32" ? "npm.cmd" : "npm"; + +run(npm, ["init", "--yes"], { cwd: consumerDirectory }); +run(npm, ["install", "--foreground-scripts", "--ignore-scripts", tarballs[0]], { + cwd: consumerDirectory, +}); + +const packageName = JSON.parse(fs.readFileSync("package.json", "utf8")).name; +const packageRoot = path.join(consumerDirectory, "node_modules", packageName); +const packageRequire = createRequire(path.join(packageRoot, "package.json")); +const selected = packageRequire("node-gyp-build").resolve(packageRoot); +const expectedPrebuildDirectory = path.join( + packageRoot, + "prebuilds", + `${expectedPlatform}-${expectedArchitecture}`, +); + +assert.strictEqual( + path.dirname(selected), + expectedPrebuildDirectory, + "Selected an unexpected prebuild directory", +); +assert.match(path.basename(selected), new RegExp(`\\.${expectedLibc}\\.node$`)); + +for (const excludedPath of ["binding.gyp", "build", "libopus", "src"]) { + assert( + !fs.existsSync(path.join(packageRoot, excludedPath)), + `Packed package contains ${excludedPath}`, + ); +} + +run( + process.execPath, + ["--input-type=module", "--eval", `await import(${JSON.stringify(packageName)})`], + { + cwd: consumerDirectory, + env: { + ...process.env, + PREBUILDS_ONLY: "1", + }, + }, +); + +run(process.execPath, [path.resolve("src/tests/test.js")], { + env: { + ...process.env, + LIBOPUS_TEST_PACKAGE_ROOT: packageRoot, + PREBUILDS_ONLY: "1", + }, +}); + +console.log( + `Verified ${expectedPlatform}-${expectedArchitecture} ${expectedLibc} prebuild: ${selected}`, +); + +function run(command, args, options = {}) { + const result = spawnSync(command, args, { + stdio: "inherit", + ...options, + }); + + if (result.error) throw result.error; + assert.strictEqual(result.status, 0, `${command} exited with ${result.status}`); +} diff --git a/src/tests/test.js b/src/tests/test.js index 0a9d0d5..ccb0d42 100644 --- a/src/tests/test.js +++ b/src/tests/test.js @@ -1,13 +1,19 @@ import assert from "node:assert"; import fs from "node:fs"; import path from "node:path"; -import nodeGypBuild from "node-gyp-build"; +import { pathToFileURL } from "node:url"; -const { OpusEncoder } = - process.env.LIBOPUS_TEST_NATIVE === "1" - ? nodeGypBuild(path.resolve(import.meta.dirname, "../..")) +const packageRoot = process.env.LIBOPUS_TEST_PACKAGE_ROOT; +const { OpusEncoder } = packageRoot + ? await loadPackage(packageRoot) + : process.env.LIBOPUS_TEST_NATIVE === "1" + ? (await import("node-gyp-build")).default(path.resolve(import.meta.dirname, "../..")) : await import("../../dist/index.js"); +async function loadPackage(root) { + return import(pathToFileURL(path.join(root, "dist/index.js")).href); +} + const sampleRate = 16_000; const channels = 1; const frameSize = 320; From b48a1b97b37842462f118cf2c94f2df19f022bfa Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 13:52:41 -0700 Subject: [PATCH 2/9] Fix Windows ARM64 MSVC build --- libopus/config/win/arm64/config.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libopus/config/win/arm64/config.h b/libopus/config/win/arm64/config.h index 4db84bd..0609491 100644 --- a/libopus/config/win/arm64/config.h +++ b/libopus/config/win/arm64/config.h @@ -33,9 +33,10 @@ POSSIBILITY OF SUCH DAMAGE. /* Comment out the next line for floating-point code */ /* #define FIXED_POINT 1 */ -/* AArch64 requires NEON and MSVC supplies the corresponding intrinsics. */ +/* AArch64 requires NEON and MSVC supplies the corresponding intrinsics. + * Keep the generic saturation macros: libopus's AArch64 macro overrides use + * NEON intrinsics in constant initializers, which MSVC does not accept. */ #define OPUS_ARM_MAY_HAVE_NEON_INTR 1 -#define OPUS_ARM_PRESUME_AARCH64_NEON_INTR 1 #define OPUS_ARM_PRESUME_NEON_INTR 1 #define OPUS_BUILD 1 From 9bca50fd7b0e0d6f3ad15f8c706e9aa5ec4b92af Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 14:01:36 -0700 Subject: [PATCH 3/9] Fix MSVC ARM64 table compilation --- libopus/binding.gyp | 16 ++++++++++++++++ libopus/config/win/arm64/config.h | 5 ++--- libopus/win/arm64/tables_NLSF_CB_NB_MB.cc | 4 ++++ libopus/win/arm64/tables_NLSF_CB_WB.cc | 6 ++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 libopus/win/arm64/tables_NLSF_CB_NB_MB.cc create mode 100644 libopus/win/arm64/tables_NLSF_CB_WB.cc diff --git a/libopus/binding.gyp b/libopus/binding.gyp index ac124e4..97c41f7 100644 --- a/libopus/binding.gyp +++ b/libopus/binding.gyp @@ -227,6 +227,22 @@ ], } ], + [ + "OS==\"win\" and target_arch==\"arm64\"", + { + # MSVC's C compiler cannot fold the floating-point + # constants in these upstream tables on ARM64 (C2099). + # Compile the two table translation units as C++ instead. + "sources!": [ + "opus/silk/tables_NLSF_CB_WB.c", + "opus/silk/tables_NLSF_CB_NB_MB.c", + ], + "sources": [ + "win/arm64/tables_NLSF_CB_WB.cc", + "win/arm64/tables_NLSF_CB_NB_MB.cc", + ], + } + ], ], }, ], diff --git a/libopus/config/win/arm64/config.h b/libopus/config/win/arm64/config.h index 0609491..4db84bd 100644 --- a/libopus/config/win/arm64/config.h +++ b/libopus/config/win/arm64/config.h @@ -33,10 +33,9 @@ POSSIBILITY OF SUCH DAMAGE. /* Comment out the next line for floating-point code */ /* #define FIXED_POINT 1 */ -/* AArch64 requires NEON and MSVC supplies the corresponding intrinsics. - * Keep the generic saturation macros: libopus's AArch64 macro overrides use - * NEON intrinsics in constant initializers, which MSVC does not accept. */ +/* AArch64 requires NEON and MSVC supplies the corresponding intrinsics. */ #define OPUS_ARM_MAY_HAVE_NEON_INTR 1 +#define OPUS_ARM_PRESUME_AARCH64_NEON_INTR 1 #define OPUS_ARM_PRESUME_NEON_INTR 1 #define OPUS_BUILD 1 diff --git a/libopus/win/arm64/tables_NLSF_CB_NB_MB.cc b/libopus/win/arm64/tables_NLSF_CB_NB_MB.cc new file mode 100644 index 0000000..0879acf --- /dev/null +++ b/libopus/win/arm64/tables_NLSF_CB_NB_MB.cc @@ -0,0 +1,4 @@ +/* + * See tables_NLSF_CB_WB.cc for why this upstream table is compiled as C++. + */ +#include "../../opus/silk/tables_NLSF_CB_NB_MB.c" diff --git a/libopus/win/arm64/tables_NLSF_CB_WB.cc b/libopus/win/arm64/tables_NLSF_CB_WB.cc new file mode 100644 index 0000000..d54f6e1 --- /dev/null +++ b/libopus/win/arm64/tables_NLSF_CB_WB.cc @@ -0,0 +1,6 @@ +/* + * MSVC's ARM64 C frontend reports C2099 for floating-point static initializers + * in this upstream table. Compiling the original translation unit as C++ + * preserves the table contents while allowing those initializers. + */ +#include "../../opus/silk/tables_NLSF_CB_WB.c" From 2d928f7c4104622050051c4d4d35bd58915a17f7 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 14:06:03 -0700 Subject: [PATCH 4/9] Handle remaining MSVC ARM64 C initializer --- libopus/binding.gyp | 2 ++ libopus/win/arm64/quant_bands.cc | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 libopus/win/arm64/quant_bands.cc diff --git a/libopus/binding.gyp b/libopus/binding.gyp index 97c41f7..7692f51 100644 --- a/libopus/binding.gyp +++ b/libopus/binding.gyp @@ -234,10 +234,12 @@ # constants in these upstream tables on ARM64 (C2099). # Compile the two table translation units as C++ instead. "sources!": [ + "opus/celt/quant_bands.c", "opus/silk/tables_NLSF_CB_WB.c", "opus/silk/tables_NLSF_CB_NB_MB.c", ], "sources": [ + "win/arm64/quant_bands.cc", "win/arm64/tables_NLSF_CB_WB.cc", "win/arm64/tables_NLSF_CB_NB_MB.cc", ], diff --git a/libopus/win/arm64/quant_bands.cc b/libopus/win/arm64/quant_bands.cc new file mode 100644 index 0000000..9ff2c7d --- /dev/null +++ b/libopus/win/arm64/quant_bands.cc @@ -0,0 +1,6 @@ +/* + * MSVC's ARM64 C frontend reports C2099 for floating-point static initializers + * in this upstream table. Compiling the original translation unit as C++ + * preserves the table contents while allowing those initializers. + */ +#include "../../opus/celt/quant_bands.c" From 99709a44c3eccf7ea7e96552a42b4c0e70d47245 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 15:04:31 -0700 Subject: [PATCH 5/9] Preserve C linkage in ARM64 quant bands --- libopus/win/arm64/quant_bands.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libopus/win/arm64/quant_bands.cc b/libopus/win/arm64/quant_bands.cc index 9ff2c7d..a918fc0 100644 --- a/libopus/win/arm64/quant_bands.cc +++ b/libopus/win/arm64/quant_bands.cc @@ -3,4 +3,6 @@ * in this upstream table. Compiling the original translation unit as C++ * preserves the table contents while allowing those initializers. */ +extern "C" { #include "../../opus/celt/quant_bands.c" +} From 1770df6ee6a12d5261ec8cced7ec59ba4790cc48 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 15:11:59 -0700 Subject: [PATCH 6/9] Set up pnpm in package verification jobs --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7e0841..adb95e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -313,6 +313,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 + - name: Setup pnpm + uses: pnpm/action-setup@v6 + - name: Setup Node.js uses: actions/setup-node@v5 with: @@ -366,6 +369,8 @@ jobs: node:24-alpine \ sh -lc ' set -euo pipefail + npm install --global corepack@0.35.0 + corepack enable node scripts/verify-packed-package.mjs artifacts/package ' @@ -395,6 +400,8 @@ jobs: run: | set -euo pipefail sudo pkg_add node npm + sudo npm install --global corepack@0.35.0 + sudo corepack enable LIBOPUS_EXPECTED_PLATFORM=openbsd \ LIBOPUS_EXPECTED_ARCH=x64 \ LIBOPUS_EXPECTED_LIBC=glibc \ From 075d4d364ae5cd102bd82c40a921c805ca0dff0e Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 15:21:14 -0700 Subject: [PATCH 7/9] Run package verifier commands through Windows shell --- scripts/verify-packed-package.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/verify-packed-package.mjs b/scripts/verify-packed-package.mjs index 7e816a2..be5a3f7 100644 --- a/scripts/verify-packed-package.mjs +++ b/scripts/verify-packed-package.mjs @@ -90,6 +90,8 @@ console.log( function run(command, args, options = {}) { const result = spawnSync(command, args, { stdio: "inherit", + // Windows command shims such as npm.cmd require a shell to launch. + shell: process.platform === "win32", ...options, }); From f89e167a34362036a4ff49dd7471af73463d8c1d Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 15:29:37 -0700 Subject: [PATCH 8/9] Preserve Node arguments in Windows package checks --- scripts/verify-packed-package.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify-packed-package.mjs b/scripts/verify-packed-package.mjs index be5a3f7..03cc683 100644 --- a/scripts/verify-packed-package.mjs +++ b/scripts/verify-packed-package.mjs @@ -91,7 +91,7 @@ function run(command, args, options = {}) { const result = spawnSync(command, args, { stdio: "inherit", // Windows command shims such as npm.cmd require a shell to launch. - shell: process.platform === "win32", + shell: process.platform === "win32" && command.endsWith(".cmd"), ...options, }); From eae41acba52e29cda7a5a9eb125f55ff6f410f83 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Mon, 10 Aug 2026 15:42:37 -0700 Subject: [PATCH 9/9] Bump version to 1.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 61f4b17..db062dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libopus-node", - "version": "1.3.0", + "version": "1.3.1", "description": "libopus bindings for Node", "keywords": [ "binary",