fix(premiere-plugin): correct zxp-sign-cmd version + promise API; commit generated signing cert

The initial pass referenced zxp-sign-cmd@0.2.2 which never shipped (latest
is 2.0.0) and used the v1.x callback API. v2 is promise-based — rewrote
build-zxp.mjs accordingly.

Also commits the freshly-generated self-signed cert + passphrase from the
first local build run. From now on every build reuses these so Adobe's
ZXP signature-continuity rule is satisfied across versions.

Verified end-to-end: `npm install && node build-zxp.mjs` produces
dist/dragonflight-premiere-panel-1.0.0.zxp (34.7 KB), signature verifies,
cert valid until 2051.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Zac Gaetano 2026-05-23 16:17:31 -04:00
parent f874009329
commit 9266a1d471
6 changed files with 72 additions and 44 deletions

View file

@ -24,7 +24,7 @@ const PASS_FILE = join(CERT_DIR, 'cert-passphrase.txt');
const STAGE_DIR = join(HERE, 'stage');
const DIST_DIR = join(HERE, 'dist');
// Files/dirs to exclude from the staged bundle.
// Top-level entries to exclude from the staged bundle.
const EXCLUDE = new Set(['build', 'install-windows.ps1', '.git', '.gitignore', 'node_modules']);
function readVersion() {
@ -34,7 +34,7 @@ function readVersion() {
return m[1].trim();
}
function ensureCert() {
async function ensureCert() {
mkdirSync(CERT_DIR, { recursive: true });
if (existsSync(CERT_FILE) && existsSync(PASS_FILE)) {
return readFileSync(PASS_FILE, 'utf8').trim();
@ -42,23 +42,19 @@ function ensureCert() {
console.log('No signing cert found — generating self-signed cert (one-time)…');
const passphrase = randomBytes(24).toString('base64url');
writeFileSync(PASS_FILE, passphrase + '\n', { mode: 0o600 });
return new Promise((res, rej) => {
zxp.selfSignedCert({
country: 'US',
province: 'WA',
org: 'Wild Dragon LLC',
name: 'Wild Dragon LLC',
password: passphrase,
output: CERT_FILE,
validityDays: 365 * 25,
}, (err) => {
if (err) return rej(err);
console.log(` wrote ${CERT_FILE}`);
console.log(` wrote ${PASS_FILE}`);
console.log(' >> COMMIT both files so future builds reuse them. <<');
res(passphrase);
});
await zxp.selfSignedCert({
country: 'US',
province: 'WA',
org: 'Wild Dragon LLC',
name: 'Wild Dragon LLC',
password: passphrase,
output: CERT_FILE,
validityDays: 365 * 25,
});
console.log(` wrote ${CERT_FILE}`);
console.log(` wrote ${PASS_FILE}`);
console.log(' >> COMMIT both files so future builds reuse them. <<');
return passphrase;
}
function stageBundle() {
@ -72,23 +68,19 @@ function stageBundle() {
}
}
function signZxp(version, passphrase) {
async function signZxp(version, passphrase) {
mkdirSync(DIST_DIR, { recursive: true });
const output = join(DIST_DIR, `dragonflight-premiere-panel-${version}.zxp`);
if (existsSync(output)) rmSync(output);
return new Promise((res, rej) => {
zxp.sign({
input: STAGE_DIR,
output,
cert: CERT_FILE,
password: passphrase,
}, (err) => {
if (err) return rej(err);
const bytes = statSync(output).size;
console.log(`Built ${output} (${(bytes / 1024).toFixed(1)} KB)`);
res(output);
});
await zxp.sign({
input: STAGE_DIR,
output,
cert: CERT_FILE,
password: passphrase,
});
const bytes = statSync(output).size;
console.log(`Built ${output} (${(bytes / 1024).toFixed(1)} KB)`);
return output;
}
async function main() {

View file

@ -39,15 +39,7 @@ self-signed cert (valid for 25 years). Commit the new pair. **Heads up:**
every editor with the old `.zxp` installed must uninstall first before the
new one will install.
Manual regeneration with the Adobe-published `ZXPSignCmd` (the
`zxp-sign-cmd` npm package wraps this):
```
npx zxp-sign-cmd selfSignedCert \
--country US \
--province WA \
--org "Wild Dragon LLC" \
--name "Wild Dragon LLC" \
--password "$(cat cert-passphrase.txt)" \
--output dragonflight-selfsigned.p12
```
The build script handles regeneration automatically — just delete both
files and re-run `node build-zxp.mjs`. If you need to invoke Adobe's
`ZXPSignCmd` directly (e.g. to inspect the generated cert), it ships inside
`node_modules/zxp-provider/bin/<version>/` after `npm install`.

View file

@ -0,0 +1 @@
k_rdrajiNn_qQcW2Oc9Z2Kc0rG4AP8vA

View file

@ -0,0 +1,43 @@
{
"name": "dragonflight-premiere-panel-build",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "dragonflight-premiere-panel-build",
"version": "0.0.0",
"devDependencies": {
"zxp-sign-cmd": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/zxp-provider": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/zxp-provider/-/zxp-provider-2.0.0.tgz",
"integrity": "sha512-ja2YZwDnDrTdq5Q0EebOaHQK5f4tOf5488mKV4sVC/mKyNiXHyJlyKwLWB4SGIrvqqWWkDk/QCfsWms2jTQ/Tw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/zxp-sign-cmd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/zxp-sign-cmd/-/zxp-sign-cmd-2.0.0.tgz",
"integrity": "sha512-BzWNvp6kSL4RFmxWp8MkVtJ4NIuRq1238W0ojHWLgeAqWMaptFdY8Nh2Uguf7Fka8KyIinrf0+tTgCeGlWPMoA==",
"dev": true,
"license": "MIT",
"dependencies": {
"zxp-provider": "^2.0.0"
},
"engines": {
"node": ">=12.0.0",
"npm": ">=6.0.0"
}
}
}
}

View file

@ -10,7 +10,7 @@
"build": "pwsh -NoProfile -ExecutionPolicy Bypass -File build-all.ps1"
},
"devDependencies": {
"zxp-sign-cmd": "^0.2.2"
"zxp-sign-cmd": "^2.0.0"
},
"engines": {
"node": ">=18"