release.ts

5.1 KB · raw

1#!/usr/bin/env bun2// scripts/release.ts3// One command to release Peach to both Chrome Web Store and Firefox AMO.4// Usage: npm run release5//        npm run release:chrome   (Chrome only — skips AMO)6//7// Required environment variables (set from your secret store, then export8// in the release shell — PB-26-013: never written to a shell profile):9//   CWS_CLIENT_ID, CWS_CLIENT_SECRET, CWS_REFRESH_TOKEN, CWS_EXTENSION_ID,10//   PUBLISHER_ID11//   AMO_JWT_ISSUER, AMO_JWT_SECRET  (not needed for --chrome-only)12//13// PB-26-211: all tools are resolved from node_modules/.bin — run14// `bun install --frozen-lockfile` before invoking release.1516import {17  preflight,18  readVersion,19  runCommand,20  safeEnv,21  uploadChrome,22  packageSourceArchive,23  signFirefox,24} from "./release-lib";2526const CHROME_ONLY = process.argv.includes("--chrome-only");2728const BOLD = "\x1b[1m";29const DIM = "\x1b[2m";30const ACCENT = "\x1b[38;5;208m";31const GREEN = "\x1b[32m";32const RESET = "\x1b[0m";3334function success(msg: string) {35  console.log(`${GREEN}✓ ${msg}${RESET}`);36}3738// ─── Header ──────────────────────────────────────────────────────────────────3940console.clear();41console.log("");42console.log(`${ACCENT}${BOLD}  ░░  peach release  ░░${RESET}`);43console.log("");4445// ─── Preflight ───────────────────────────────────────────────────────────────4647preflight();48const version = readVersion("manifest.json");49const targets = CHROME_ONLY ? "Chrome" : "Chrome + Firefox";50console.log(`${BOLD}Releasing Peach v${version} to ${targets}${RESET}`);51console.log(`${DIM}Stores update automatically for existing users.${RESET}`);5253// ─── CI gate ──────────────────────────────────────────────────────────────────54// PB-26-211: CI runs with a minimal safe environment — no store credentials.5556runCommand("npm", ["run", "ci"], {57  label: "Running CI gate",58  env: safeEnv(),59});60success("All tests pass");6162// ─── Build ────────────────────────────────────────────────────────────────────63// PB-26-211: build children receive no store credentials.6465if (CHROME_ONLY) {66  runCommand("npm", ["run", "build:chrome"], {67    label: "Building Chrome target",68    env: safeEnv(),69  });70} else {71  runCommand("npm", ["run", "build"], {72    label: "Building all targets (Chrome + Firefox)",73    env: safeEnv(),74  });75}76success("Build complete");7778// ─── Chrome release ───────────────────────────────────────────────────────────79// PB-26-211: CWS credentials are read and validated here, immediately before80// upload. They are passed only to the Chrome upload child, never to build or81// CI children.8283console.log(`\n${ACCENT}${BOLD}Chrome Web Store${RESET}`);84uploadChrome(version);85success(`Chrome v${version} submitted — review typically takes minutes to hours`);8687// ─── Firefox release ──────────────────────────────────────────────────────────88// PB-26-211: AMO credentials are read and validated here, immediately before89// signing. They are passed only to the web-ext child, never to Chrome tooling90// or build children.9192if (!CHROME_ONLY) {93  console.log(`\n${ACCENT}${BOLD}Firefox Add-ons (AMO)${RESET}`);94  const sourceZip = packageSourceArchive(version);95  signFirefox(sourceZip);96  success(`Firefox v${version} submitted with source archive retained in artifacts/`);97}9899// ─── Done ─────────────────────────────────────────────────────────────────────100101console.log("");102console.log(`${ACCENT}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);103console.log(`${ACCENT}${BOLD}  Peach v${version} released to ${targets}.${RESET}`);104console.log(`${ACCENT}${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);105console.log("");106107if (!CHROME_ONLY) {108  console.log(`  Chrome:  under review — existing users update automatically`);109  console.log(`  Firefox: under review — existing users update automatically`);110} else {111  console.log(`  Chrome: under review — existing users update automatically`);112}113114console.log("");115console.log(`${DIM}Check status:${RESET}`);116console.log(`  Chrome:  https://chrome.google.com/webstore/devconsole`);117if (!CHROME_ONLY) {118  console.log(`  Firefox: https://addons.mozilla.org/developers/`);119}120console.log("");