#!/usr/bin/env node
const { spawnSync } = require("child_process");
const workspaceRoot = __dirname;
const actions = [
{
id: "all",
label: "All",
description: "Developer build and App Store build",
scripts: [
"release:build:developer",
"release:build:appstore",
],
},
{
id: "all-interactive",
label: "All interactive",
description: "All build steps with interactive prompts when needed",
scripts: [
"release:build:developer:interactive",
"release:build:appstore:interactive",
],
},
{
id: "developer-build",
label: "Developer build",
description: "Run development/preview builds plus TestFlight store submissions",
scripts: ["release:build:developer"],
},
{
id: "appstore-build",
label: "App Store build",
description: "Run production store builds and auto-submit",
scripts: ["release:build:appstore"],
},
{
id: "ota-preview",
label: "OTA (preview)",
description: "Publish an update to the preview channel",
scripts: ["release:ota:preview"],
},
{
id: "ota-release",
label: "OTA (release)",
description: "Publish an update to the production channel",
scripts: ["release:ota:release"],
},
];
const actionAliases = {
all: "all",
interactive: "all-interactive",
"all-interactive": "all-interactive",
"all interactive": "all-interactive",
developer: "developer-build",
dev: "developer-build",
"developer-build": "developer-build",
appstore: "appstore-build",
store: "appstore-build",
"appstore-build": "appstore-build",
"ota-preview": "ota-preview",
"ota:preview": "ota-preview",
preview: "ota-preview",
"ota-release": "ota-release",
"ota:release": "ota-release",
production: "ota-release",
};
function findAction(input) {
const normalized = String(input || "").trim().toLowerCase();
const actionId = actionAliases[normalized] || normalized;
return actions.find((action) => action.id === actionId);
}
function printAvailableOptions() {
console.error("Available happy-app release options:");
for (const action of actions) {
console.error(`- ${action.id}: ${action.description}`);
}
}
function runScript(scriptName) {
console.log(`> pnpm run ${scriptName}`);
const result = spawnSync("pnpm", ["run", scriptName], {
cwd: workspaceRoot,
stdio: "inherit",
env: process.env,
});
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
async function promptForAction() {
if (!process.stdin.isTTY || !process.stdout.isTTY) {
console.error("Interactive happy-app release selection requires a TTY.");
printAvailableOptions();
console.error("Run `pnpm release --