From bd8d90396a7c5f02c8db2679ad2d9836dd3cde0a Mon Sep 17 00:00:00 2001 From: webzherd Date: Mon, 4 May 2026 10:01:57 +0200 Subject: [PATCH 01/12] Add CI workflow that packs standalone tarballs Builds standalone tarballs (linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64) via `oclif pack tarballs` on workflow_dispatch and on `v*` tag pushes, and uploads them as a workflow artifact. Tarballs bundle Node so users without Node installed can run the CLI. Publishing to GitHub Releases / npm is intentionally deferred to a follow-up so we can verify the artifact build first. Also guards the `prepare` script: `oclif pack` runs an internal `npm install --production` that triggered the previous unconditional `tsc -b` even though TypeScript is a devDependency. The new guard runs the build only when tsc is present, preserving the install-from-git build path while letting the production install inside oclif pack succeed. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 30 ++++++++++++++++++++++++++++++ CHANGELOG.md | 4 ++++ package.json | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pack.yml diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml new file mode 100644 index 0000000..903458e --- /dev/null +++ b/.github/workflows/pack.yml @@ -0,0 +1,30 @@ +name: Pack tarballs + +on: + workflow_dispatch: + push: + tags: ['v*'] + +jobs: + pack: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: npm + - run: npm ci + - run: npm run build + - run: npx oclif manifest + - name: Pack tarballs + run: npx oclif pack tarballs --targets=linux-x64,linux-arm64,darwin-x64,darwin-arm64,win32-x64 + - name: Upload tarballs as workflow artifact + uses: actions/upload-artifact@v4 + with: + name: bitmovin-cli-tarballs + path: | + dist/*.tar.gz + dist/*.tar.xz + if-no-files-found: error + retention-days: 30 diff --git a/CHANGELOG.md b/CHANGELOG.md index cd22af5..cca1667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- CI workflow that builds standalone tarballs (macOS, Linux, Windows) via `oclif pack` and uploads them as workflow artifacts. Publishing to GitHub Releases and npm will follow in a subsequent change. + ### Changed - **BREAKING:** `bitmovin account info --json` now masks API key values and other secrets by default. Consumers that need plaintext secrets must opt in with `--show-secrets`. diff --git a/package.json b/package.json index f730b11..7383c7e 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "dist" ], "scripts": { - "prepare": "tsc -b", + "prepare": "if [ -x ./node_modules/.bin/tsc ]; then tsc -b; fi", "build": "tsc -b", "dev": "tsc -b --watch", "test": "vitest run", From 7c54bf0e1ce30bf36457293bd9b2f920b625e539 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 11:20:39 +0200 Subject: [PATCH 02/12] Pack macOS .pkg and Windows .exe installers in addition to tarballs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Installs nsis (Windows installer) and bomutils + xar (macOS package tooling) on the runner, then runs `oclif pack macos` and `oclif pack win` after the existing tarball pack. Uploads everything under a single `bitmovin-cli-installers` artifact. The installers are unsigned for now — they build and run, but macOS Gatekeeper and Windows SmartScreen will warn users until we add Apple Developer ID notarization and Authenticode signing. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 16 +++++++++++++--- CHANGELOG.md | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 903458e..4a78741 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -1,4 +1,4 @@ -name: Pack tarballs +name: Pack installers on: workflow_dispatch: @@ -14,17 +14,27 @@ jobs: with: node-version: '20' cache: npm + - name: Install pack tooling (nsis for .exe, bomutils + xar for .pkg) + run: | + sudo apt-get update + sudo apt-get install -y nsis bomutils xar - run: npm ci - run: npm run build - run: npx oclif manifest - name: Pack tarballs run: npx oclif pack tarballs --targets=linux-x64,linux-arm64,darwin-x64,darwin-arm64,win32-x64 - - name: Upload tarballs as workflow artifact + - name: Pack macOS .pkg (darwin-x64, darwin-arm64) + run: npx oclif pack macos + - name: Pack Windows .exe (win32-x64) + run: npx oclif pack win + - name: Upload installers as workflow artifact uses: actions/upload-artifact@v4 with: - name: bitmovin-cli-tarballs + name: bitmovin-cli-installers path: | dist/*.tar.gz dist/*.tar.xz + dist/macos/*.pkg + dist/win32/*.exe if-no-files-found: error retention-days: 30 diff --git a/CHANGELOG.md b/CHANGELOG.md index cca1667..58a7f91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- CI workflow that builds standalone tarballs (macOS, Linux, Windows) via `oclif pack` and uploads them as workflow artifacts. Publishing to GitHub Releases and npm will follow in a subsequent change. +- CI workflow that builds standalone tarballs (macOS, Linux, Windows) plus macOS `.pkg` and Windows `.exe` installers via `oclif pack` and uploads them as workflow artifacts. Installers are unsigned for now — Apple Developer ID notarization and Authenticode signing will follow. Publishing to GitHub Releases and npm will follow in a subsequent change. ### Changed From 22d7dc7e8cd173e1622e257ee690cab760fd3b20 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 11:23:09 +0200 Subject: [PATCH 03/12] Split pack.yml into Linux + macOS jobs for native .pkg Ubuntu 24.04 dropped both `xar` and `bomutils` from its package repos, so building a `.pkg` on a Linux runner without source-building those tools is no longer feasible. Move the macOS package build to a `macos-latest` runner that has native `pkgbuild` / `productbuild`, and keep tarballs + Windows `.exe` (NSIS) on the Linux runner. Outputs split across two artifacts: `bitmovin-cli-tarballs-and-windows` and `bitmovin-cli-macos`. Public repo, so macOS runner minutes are free. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 42 +++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 4a78741..643fc4f 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -6,7 +6,7 @@ on: tags: ['v*'] jobs: - pack: + pack-tarballs-and-windows: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -14,27 +14,45 @@ jobs: with: node-version: '20' cache: npm - - name: Install pack tooling (nsis for .exe, bomutils + xar for .pkg) - run: | - sudo apt-get update - sudo apt-get install -y nsis bomutils xar + - name: Install NSIS for Windows .exe + run: sudo apt-get update && sudo apt-get install -y nsis - run: npm ci - run: npm run build - run: npx oclif manifest - - name: Pack tarballs + - name: Pack tarballs (all targets) run: npx oclif pack tarballs --targets=linux-x64,linux-arm64,darwin-x64,darwin-arm64,win32-x64 - - name: Pack macOS .pkg (darwin-x64, darwin-arm64) - run: npx oclif pack macos - - name: Pack Windows .exe (win32-x64) + - name: Pack Windows .exe run: npx oclif pack win - - name: Upload installers as workflow artifact + - name: Upload tarballs + Windows installer uses: actions/upload-artifact@v4 with: - name: bitmovin-cli-installers + name: bitmovin-cli-tarballs-and-windows path: | dist/*.tar.gz dist/*.tar.xz - dist/macos/*.pkg dist/win32/*.exe if-no-files-found: error retention-days: 30 + + pack-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: npm + - run: npm ci + - run: npm run build + - run: npx oclif manifest + - name: Pack tarballs (darwin targets, needed by pack:macos) + run: npx oclif pack tarballs --targets=darwin-x64,darwin-arm64 + - name: Pack macOS .pkg + run: npx oclif pack macos + - name: Upload macOS .pkg installers + uses: actions/upload-artifact@v4 + with: + name: bitmovin-cli-macos + path: dist/macos/*.pkg + if-no-files-found: error + retention-days: 30 From 45606fff9644c0bf674d58801645fb55c7fef364 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 11:32:10 +0200 Subject: [PATCH 04/12] Add oclif.macos.identifier so 'oclif pack macos' can produce a .pkg `oclif pack macos` requires `oclif.macos.identifier` in package.json to set the macOS package identifier. Use the reverse-DNS form `com.bitmovin.cli`. Co-Authored-By: Claude Opus 4.7 (1M context) --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 7383c7e..28aba83 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,9 @@ "oclif": { "bin": "bitmovin", "dirname": "bitmovin", + "macos": { + "identifier": "com.bitmovin.cli" + }, "plugins": [ "@oclif/plugin-autocomplete" ], From 348a632576fa4e768999a821e510ddb28e6f369d Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 11:45:37 +0200 Subject: [PATCH 05/12] Limit pack:win to win32-x64 to avoid bloated artifact MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `oclif pack win` defaults to building x64, x86 and arm64 .exe installers in parallel — each ~200 MB — which pushed the Linux artifact bundle to 1.2 GB. Restrict to win32-x64 to match the tarball target list and bring the artifact back under ~500 MB. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 643fc4f..3494e63 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -21,8 +21,8 @@ jobs: - run: npx oclif manifest - name: Pack tarballs (all targets) run: npx oclif pack tarballs --targets=linux-x64,linux-arm64,darwin-x64,darwin-arm64,win32-x64 - - name: Pack Windows .exe - run: npx oclif pack win + - name: Pack Windows .exe (win32-x64 only) + run: npx oclif pack win --targets=win32-x64 - name: Upload tarballs + Windows installer uses: actions/upload-artifact@v4 with: From 7b2e7cb7fa910bbd3ec55156f640733a24ab5d71 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 11:53:23 +0200 Subject: [PATCH 06/12] Create draft GitHub Release with individual installer assets on tag push Workflow artifacts are always zip-wrapped by GitHub, which makes .pkg/.exe download-and-run unfriendly. Add a third job that runs after both pack jobs, downloads their artifacts, and creates a draft GitHub Release with each installer file (tarballs, .exe, .pkg) as its own asset. Draft releases are invisible to anyone without write access. After verifying the assets, a maintainer publishes via the Releases UI ("Publish release" button); the tag stays the same, only the visibility flips. Workflow artifacts are kept too for shorter-term inspection (auto-expire in 30 days). The release job is gated on tag pushes (`startsWith(github.ref, 'refs/tags/v')`), so workflow_dispatch runs still produce artifacts without trying to create a release object. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 3494e63..e470620 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -5,6 +5,9 @@ on: push: tags: ['v*'] +permissions: + contents: write + jobs: pack-tarballs-and-windows: runs-on: ubuntu-latest @@ -56,3 +59,26 @@ jobs: path: dist/macos/*.pkg if-no-files-found: error retention-days: 30 + + draft-release: + needs: [pack-tarballs-and-windows, pack-macos] + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + steps: + - name: Download all build artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + - name: List downloaded files + run: find artifacts -type f -exec ls -lh {} \; + - name: Create draft release with installers as individual assets + uses: softprops/action-gh-release@v2 + with: + draft: true + generate_release_notes: true + fail_on_unmatched_files: true + files: | + artifacts/bitmovin-cli-tarballs-and-windows/*.tar.gz + artifacts/bitmovin-cli-tarballs-and-windows/*.tar.xz + artifacts/bitmovin-cli-tarballs-and-windows/*.exe + artifacts/bitmovin-cli-macos/*.pkg From 8ddca075982cece0fa583348e33c100912337844 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 12:00:54 +0200 Subject: [PATCH 07/12] =?UTF-8?q?Fix=20.exe=20glob=20=E2=80=94=20upload-ar?= =?UTF-8?q?tifact=20preserves=20dist/win32/=20subdir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When upload-artifact gets multiple `path:` entries with a common prefix (`dist/`), it preserves any path components below that prefix. So `dist/*.tar.gz` lands at the artifact root but `dist/win32/*.exe` lands under `win32/` inside the artifact. Update the release glob to match the actual download layout. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index e470620..5efe498 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -80,5 +80,5 @@ jobs: files: | artifacts/bitmovin-cli-tarballs-and-windows/*.tar.gz artifacts/bitmovin-cli-tarballs-and-windows/*.tar.xz - artifacts/bitmovin-cli-tarballs-and-windows/*.exe + artifacts/bitmovin-cli-tarballs-and-windows/win32/*.exe artifacts/bitmovin-cli-macos/*.pkg From 9dea72325e87167266d93a62b70926f2c6ba7eaf Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 13:43:57 +0200 Subject: [PATCH 08/12] Address review: revert release job, fix prepare to fail loud MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes in response to PR feedback: 1. Revert the draft-release job. Restore the original PR scope of "build artifacts only, defer publishing." Tarballs, .pkg, and .exe continue to upload as workflow artifacts (zip-wrapped, internal testing only). GitHub Release publishing will land in a follow-up that also addresses code signing — shipping unsigned installers through a Release surfaces Gatekeeper / SmartScreen warnings that undercut the "no Node required" promise. 2. Make `prepare` fail loud when build is actually needed. The previous shim `if [ -x ./node_modules/.bin/tsc ]; then tsc -b; fi` silently no-op'd whenever tsc was missing, hiding broken-state installs. New form `[ -d dist ] || tsc -b` only skips when dist already exists (oclif pack's tmp workspace, npm install from a shipped tarball) and otherwise runs `tsc -b` — which fails loud if tsc isn't available. The three install paths still work: - `npm install `: dist absent, devDeps present → builds - `npm install` from npm tarball: dist already shipped → skip - `oclif pack` tmp `npm install --production`: dist copied → skip Considered Lukas's suggestion of skipping lifecycle scripts at the oclif invocation level instead — oclif v4 doesn't expose a knob for this in `pack`, so the dist-presence guard remains the cleanest available fix. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 26 -------------------------- CHANGELOG.md | 2 +- package.json | 2 +- 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 5efe498..3494e63 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -5,9 +5,6 @@ on: push: tags: ['v*'] -permissions: - contents: write - jobs: pack-tarballs-and-windows: runs-on: ubuntu-latest @@ -59,26 +56,3 @@ jobs: path: dist/macos/*.pkg if-no-files-found: error retention-days: 30 - - draft-release: - needs: [pack-tarballs-and-windows, pack-macos] - if: startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-latest - steps: - - name: Download all build artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - name: List downloaded files - run: find artifacts -type f -exec ls -lh {} \; - - name: Create draft release with installers as individual assets - uses: softprops/action-gh-release@v2 - with: - draft: true - generate_release_notes: true - fail_on_unmatched_files: true - files: | - artifacts/bitmovin-cli-tarballs-and-windows/*.tar.gz - artifacts/bitmovin-cli-tarballs-and-windows/*.tar.xz - artifacts/bitmovin-cli-tarballs-and-windows/win32/*.exe - artifacts/bitmovin-cli-macos/*.pkg diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a7f91..b46b7f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- CI workflow that builds standalone tarballs (macOS, Linux, Windows) plus macOS `.pkg` and Windows `.exe` installers via `oclif pack` and uploads them as workflow artifacts. Installers are unsigned for now — Apple Developer ID notarization and Authenticode signing will follow. Publishing to GitHub Releases and npm will follow in a subsequent change. +- CI workflow that builds standalone tarballs (macOS, Linux, Windows) plus macOS `.pkg` and Windows `.exe` installers via `oclif pack` and uploads them as workflow artifacts for internal testing. Installers are unsigned. Code signing, GitHub Release publishing, and npm publishing will follow in subsequent changes. ### Changed diff --git a/package.json b/package.json index 28aba83..189a4f1 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "dist" ], "scripts": { - "prepare": "if [ -x ./node_modules/.bin/tsc ]; then tsc -b; fi", + "prepare": "[ -d dist ] || tsc -b", "build": "tsc -b", "dev": "tsc -b --watch", "test": "vitest run", From 60efda50d5aeda4ff8693238493166ea9077b579 Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 15:32:31 +0200 Subject: [PATCH 09/12] Sign macOS .pkg with Developer ID Installer cert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an "Import Developer ID Installer cert into temp keychain" step to the pack-macos job that decodes a P12 from the APPLE_INSTALLER_CERT_P12_BASE64 / APPLE_INSTALLER_CERT_PASSWORD secrets, imports it into a per-job temp keychain (random unlock password, 6h timeout), and authorizes productsign / productbuild against the imported identity. oclif.macos.sign in package.json is set to the cert's full Common Name; oclif's pack:macos invokes productsign with that identity at the end of pkg build. Resulting .pkg passes pkgutil --check-signature and Gatekeeper installer trust. Notarization is not wired yet — that needs a Developer ID Application codesign of bundled Mach-O binaries plus xcrun notarytool against an App Store Connect API key. Without notarization, Gatekeeper still shows the standard "from an identified developer" allow flow on first install. Notarization will follow. The workflow will fail at the import step until both APPLE_INSTALLER_CERT_* secrets are configured on the repo. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 19 ++++++++++++++++++- package.json | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 3494e63..10e5f4f 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -45,9 +45,26 @@ jobs: - run: npm ci - run: npm run build - run: npx oclif manifest + - name: Import Developer ID Installer cert into temp keychain + env: + INSTALLER_CERT_P12_BASE64: ${{ secrets.APPLE_INSTALLER_CERT_P12_BASE64 }} + INSTALLER_CERT_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERT_PASSWORD }} + run: | + KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain" + KEYCHAIN_PASSWORD=$(openssl rand -base64 24) + P12_PATH="$RUNNER_TEMP/installer.p12" + echo "$INSTALLER_CERT_P12_BASE64" | base64 --decode > "$P12_PATH" + security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" + security import "$P12_PATH" -k "$KEYCHAIN_PATH" -P "$INSTALLER_CERT_PASSWORD" -T /usr/bin/productsign -T /usr/bin/productbuild + security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" >/dev/null + security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"') + rm -f "$P12_PATH" + security find-identity -v -p basic "$KEYCHAIN_PATH" - name: Pack tarballs (darwin targets, needed by pack:macos) run: npx oclif pack tarballs --targets=darwin-x64,darwin-arm64 - - name: Pack macOS .pkg + - name: Pack macOS .pkg (signed with Developer ID Installer) run: npx oclif pack macos - name: Upload macOS .pkg installers uses: actions/upload-artifact@v4 diff --git a/package.json b/package.json index 189a4f1..5ee5c6b 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,8 @@ "bin": "bitmovin", "dirname": "bitmovin", "macos": { - "identifier": "com.bitmovin.cli" + "identifier": "com.bitmovin.cli", + "sign": "Developer ID Installer: bitmovin GmbH (7UXPEM3WRB)" }, "plugins": [ "@oclif/plugin-autocomplete" From 0dde3a0ae0885a0cdba3f6cda381413b7a6f86ae Mon Sep 17 00:00:00 2001 From: webzherd Date: Tue, 5 May 2026 16:03:08 +0200 Subject: [PATCH 10/12] Use Installer cert SHA1 fingerprint instead of CN in oclif.macos.sign MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit oclif passes the sign string straight to a /bin/sh -c invocation without quoting, so any shell-special characters break it. The common name has spaces, a colon, and the team-id parens — pkgbuild on the runner died with `syntax error near unexpected token '('`. pkgbuild --sign accepts either the CN or the certificate's SHA-1 hash (per `man pkgbuild`). Switching to the hex-only SHA-1 sidesteps oclif's quoting bug entirely. Co-Authored-By: Claude Opus 4.7 (1M context) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ee5c6b..6123dec 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "dirname": "bitmovin", "macos": { "identifier": "com.bitmovin.cli", - "sign": "Developer ID Installer: bitmovin GmbH (7UXPEM3WRB)" + "sign": "687757AC438BFBA10137B2912CBC03F8641BB388" }, "plugins": [ "@oclif/plugin-autocomplete" From 30c20ead2ddf94d1ccb0e61d8454d76d772a3aa6 Mon Sep 17 00:00:00 2001 From: webzherd Date: Wed, 6 May 2026 08:51:39 +0200 Subject: [PATCH 11/12] Trust pkgbuild and codesign on the imported signing key pkgbuild was hanging for 10+ minutes in pack-macos with no diagnostic output, and a `gh run cancel` finally produced `Terminate orphan process: pid (12617) (pkgbuild)`. Root cause: the key was imported with -T productsign/productbuild only, so pkgbuild itself wasn't on the trust list and was blocking on a non-existent auth dialog when reaching for the signing key. Adding -T /usr/bin/pkgbuild and -T /usr/bin/codesign closes the gap. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 10e5f4f..2d73345 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -57,7 +57,7 @@ jobs: security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security import "$P12_PATH" -k "$KEYCHAIN_PATH" -P "$INSTALLER_CERT_PASSWORD" -T /usr/bin/productsign -T /usr/bin/productbuild + security import "$P12_PATH" -k "$KEYCHAIN_PATH" -P "$INSTALLER_CERT_PASSWORD" -T /usr/bin/productsign -T /usr/bin/productbuild -T /usr/bin/pkgbuild -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" >/dev/null security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"') rm -f "$P12_PATH" From 8a4b2a1dd7aebe47a189155b47fab835faf4ee0c Mon Sep 17 00:00:00 2001 From: webzherd Date: Wed, 6 May 2026 09:54:12 +0200 Subject: [PATCH 12/12] Verify .pkg signatures in CI with pkgutil --check-signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit oclif's pack:macos calls productsign but doesn't fail loud if the signature ends up unverifiable — we'd discover that only when a user tries to install. Run pkgutil --check-signature on each produced .pkg in the macOS job; non-zero exit fails the job. Catches missing or corrupt signatures, untrusted cert chains, and other signature defects before the artifact ships. spctl --assess deliberately not added here — without notarization it would fail on every signed-but-unnotarized .pkg. Will land together with the notarization step. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/pack.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/pack.yml b/.github/workflows/pack.yml index 2d73345..f59b66d 100644 --- a/.github/workflows/pack.yml +++ b/.github/workflows/pack.yml @@ -66,6 +66,14 @@ jobs: run: npx oclif pack tarballs --targets=darwin-x64,darwin-arm64 - name: Pack macOS .pkg (signed with Developer ID Installer) run: npx oclif pack macos + - name: Verify .pkg signatures + run: | + set -e + for pkg in dist/macos/*.pkg; do + echo "=== $pkg ===" + pkgutil --check-signature "$pkg" + echo + done - name: Upload macOS .pkg installers uses: actions/upload-artifact@v4 with: