release-firefox.ts

4.7 KB · raw

1#!/usr/bin/env bun2// scripts/release-firefox.ts3// One-command Firefox AMO release.4// Usage: bun run scripts/release-firefox.ts56import { execSync } from "child_process";7import { readFileSync, existsSync, mkdirSync } from "fs";8import { join } from "path";910const ROOT = process.cwd();1112function run(cmd: string, label?: string, env?: Record<string, string>) {13  const display = label ?? cmd;14  console.log(`\n▶ ${display}`);15  execSync(cmd, { stdio: "inherit", cwd: ROOT, env: { ...process.env, ...env } });16}1718function fail(msg: string): never {19  console.error(`\n✗ ${msg}`);20  process.exit(1);21}2223// ── Verify environment ────────────────────────────────────────────────────────2425if (!process.env.AMO_JWT_ISSUER) {26  fail("AMO_JWT_ISSUER not set. Add it to your shell profile and reload.");27}28if (!process.env.AMO_JWT_SECRET) {29  fail("AMO_JWT_SECRET not set. Add it to your shell profile and reload.");30}3132// ── Read version ──────────────────────────────────────────────────────────────3334const manifest = JSON.parse(35  readFileSync(join(ROOT, "manifest.firefox.json"), "utf8")36);37const version = manifest.version;38if (!version) fail("Could not read version from manifest.firefox.json");39console.log(`\n🍑 Peach Firefox — releasing v${version}`);4041// ── CI gate ───────────────────────────────────────────────────────────────────4243run("npm run ci", "Running CI gate");4445// ── Build ─────────────────────────────────────────────────────────────────────4647run("npm run build:firefox", `Building Firefox extension v${version}`);4849// ── Package source archive ────────────────────────────────────────────────────50// AMO requires source for any extension with minified/transpiled code.51// This zips everything a reviewer needs to build Peach from source.5253// Keep the reviewer archive beside the signed artifact for traceability.54if (!existsSync(join(ROOT, "artifacts"))) {55  mkdirSync(join(ROOT, "artifacts"));56}57const sourceZip = join(ROOT, "artifacts", `peach-source-${version}.zip`);58run(59  [60    "zip -r",61    sourceZip,62    "src",63    "scripts",64    "public",65    // PB-26-004: the shipped .wasm is transpiled from crypto-core/src/lib.rs —66    // AMO reviewers must be able to inspect and rebuild it (npm run67    // build:noise-core). Build cache and generated output are excluded.68    "crypto-core",69    "manifest.json",70    "manifest.firefox.json",71    "package.json",72    "bun.lock",73    "tsconfig.json",74    "vite.config.ts",75    "--exclude 'node_modules/*'",76    "--exclude 'dist-*/*'",77    "--exclude 'crypto-core/target/*'",78    "--exclude 'crypto-core/generated/*'",79    "--exclude '*.zip'",80    "--exclude '.DS_Store'",81    "--exclude '__MACOSX/*'",82  ].join(" "),83  "Packaging source archive for AMO"84);8586// ── Ensure artifacts dir ──────────────────────────────────────────────────────8788if (!existsSync(join(ROOT, "artifacts"))) {89  mkdirSync(join(ROOT, "artifacts"));90}9192// ── Sign and submit ───────────────────────────────────────────────────────────9394run(95  [96    "npx web-ext sign",97    "--source-dir dist-firefox",98    "--artifacts-dir artifacts",99    "--channel=listed",100    "--upload-source-code",101    sourceZip,102  ].join(" "),103  "Signing and submitting to AMO",104  // web-ext reads WEB_EXT_API_KEY/WEB_EXT_API_SECRET from env — pass via105  // child env so the JWT credentials are not visible in the process table.106  {107    WEB_EXT_API_KEY: process.env.AMO_JWT_ISSUER!,108    WEB_EXT_API_SECRET: process.env.AMO_JWT_SECRET!,109  }110);111112// ── Done ──────────────────────────────────────────────────────────────────────113114console.log(`\n✓ Peach Firefox v${version} submitted to AMO.`);115console.log(`  Source archive retained at ${sourceZip}.`);116console.log("  Existing users will receive the update automatically.");117console.log("  Check AMO developer hub for review status.");118console.log("");