release acceptance matrix: tools/acceptance.ts runs every user-facing command from the packed npm tarball (npx --package=<tgz> on Node 20 / 22, bun x --bun after bun add <tgz>) in fresh temp folders with a fresh HOME, real piped stdin (n, EOF) and per-cell fake stores over HTTP (STOREBOUND_STORE_MOCK, loopback only); a cell passes only with the expected exit code and no crash text; report -> markdown matrix. Prompts go through stdinIsTTY (STOREBOUND_ASSUME_TTY drives them with piped stdin), STOREBOUND_DESKTOP_APP=none for the install prompt on a machine with the app. release.yml: required acceptance job matrix (Linux + Windows x node20/node22/bun) and report, the matrix attached to the release; ci.yml: the quick subset on Linux and Windows. Scan fixtures for React Native and Expo
This commit is contained in:
parent
ae681e3ecd
commit
f58e192001
26 changed files with 926 additions and 15 deletions
|
|
@ -30,6 +30,7 @@ import {
|
|||
import { pages } from '../prices';
|
||||
import { createOnce, findOrCreate, getById } from '../lib/upsert';
|
||||
import { type Asc, ascClient, md5, type J } from './asc';
|
||||
import { stdinIsTTY } from '../lib/tty';
|
||||
|
||||
const TAG = 'apple';
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
const yes = ctx.args.has('yes');
|
||||
// price changes of existing subscriptions: known per subscription, decided at the first one (lib/price-gate.ts)
|
||||
let liveOk: boolean | undefined;
|
||||
if (process.stdin.isTTY && !yes && process.env.STOREBOUND_SERVE !== '1') {
|
||||
if (stdinIsTTY() && !yes && process.env.STOREBOUND_SERVE !== '1') {
|
||||
if (!(await confirm(ctx, 'Create / update these subscriptions on App Store Connect? Nothing is public before App Review, but price changes of existing subscriptions apply to new subscribers right away.'))) return;
|
||||
liveOk = true;
|
||||
} else if (!yes) log(TAG, 'not a terminal: creating what is new; price changes of existing subscriptions wait for the owner');
|
||||
|
|
@ -220,7 +221,7 @@ export async function run(ctx: Ctx): Promise<void> {
|
|||
* the code can redeem it). Existing codes (same customCode) are left alone. */
|
||||
async function customCodes(c: Asc, ctx: Ctx, subId: string, s: Subscription, oc: OfferCodeDef, ocId: string | undefined): Promise<void> {
|
||||
if (!ctx.args.has('codes')) { log(TAG, ` ${oc.customCodes!.length} custom code(s) of "${oc.name}" not created (pass --codes from a terminal)`); return; }
|
||||
if (!process.stdin.isTTY) { warn(TAG, ` custom codes of "${oc.name}" need a terminal confirmation`); return; }
|
||||
if (!stdinIsTTY()) { warn(TAG, ` custom codes of "${oc.name}" need a terminal confirmation`); return; }
|
||||
const id = ocId ?? (await c.all(`/v1/subscriptions/${subId}/offerCodes?limit=200`)).find((x: J) => x.attributes.name === oc.name)?.id;
|
||||
if (!id) throw new Error(`${s.id}: offer code campaign "${oc.name}" not found`);
|
||||
const have = new Set((await c.all(`/v1/subscriptionOfferCodes/${id}/customCodes?limit=200`)).map((x: J) => x.attributes.customCode));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue