release-firefox.ts

4.5 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.5253const sourceZip = `peach-source-${version}.zip`;54run(55  [56    "zip -r",57    sourceZip,58    "src",59    "scripts",60    "public",61    "manifest.json",62    "manifest.firefox.json",63    "package.json",64    "bun.lock",65    "tsconfig.json",66    "vite.config.ts",67    "vite.config.firefox.ts",68    "vite.config.chrome.ts",69    "vite.config.mobile.ts",70    "--exclude 'node_modules/*'",71    "--exclude 'dist-*/*'",72    "--exclude '*.zip'",73    "--exclude '.DS_Store'",74    "--exclude '__MACOSX/*'",75  ].join(" "),76  "Packaging source archive for AMO"77);7879// ── Ensure artifacts dir ──────────────────────────────────────────────────────8081if (!existsSync(join(ROOT, "artifacts"))) {82  mkdirSync(join(ROOT, "artifacts"));83}8485// ── Sign and submit ───────────────────────────────────────────────────────────8687run(88  [89    "npx web-ext sign",90    "--source-dir dist-firefox",91    "--artifacts-dir artifacts",92    "--channel=listed",93  ].join(" "),94  "Signing and submitting to AMO",95  // web-ext reads WEB_EXT_API_KEY/WEB_EXT_API_SECRET from env — pass via96  // child env so the JWT credentials are not visible in the process table.97  {98    WEB_EXT_API_KEY: process.env.AMO_JWT_ISSUER!,99    WEB_EXT_API_SECRET: process.env.AMO_JWT_SECRET!,100  }101);102103// ── Cleanup zip ───────────────────────────────────────────────────────────────104105run(`trash ${sourceZip}`, "Cleaning up source zip");106107// ── Done ──────────────────────────────────────────────────────────────────────108109console.log(`\n✓ Peach Firefox v${version} submitted to AMO.`);110console.log("  Existing users will receive the update automatically.");111console.log("  Check AMO developer hub for review status.");112console.log("");