apple signing: App Group association fails early under automatic signing too (API capability + newest profile, steps and deep link, exit before the archive); console plan/verify apple-app-group

This commit is contained in:
CRTkafa 2026-10-25 22:34:14 +07:00
parent d978bb7a8b
commit 304407e523
20 changed files with 590 additions and 60 deletions

View file

@ -12,6 +12,7 @@ import { type Answer, type AnswerValue, consoleAnswers, type FormId, formMeta, i
import { APP_CONTENT_CAPTURE, APP_CONTENT_CARDS, appContentStart, PLAY_FULL_ACCESS_BOX, PLAY_MATERIAL_FACT, playAppPage, playOnlyPart, SAVE_EACH_PAGE, SEND_FOR_REVIEW, SEND_FOR_REVIEW_WHERE, startLabel } from './console-play-plans';
import { FORM_BUTTONS, formDef, type Name, NEVER_PRESS, PLAY_NEVER_PRESS, playAppList, playCreateApp, setUpTexts, typeLabels } from './console-forms';
import { PLAY_CREATE_CAPTURE } from './console-verify';
import { appleAppGroupPlan } from './console-apple-group-plan';
import { APPLE_PURPOSES, IARC_DIGITAL_GOODS, IARC_DIGITAL_PURCHASES } from './console-answers';
export type PlanStatus = 'certain' | 'ask-owner' | 'owner-check' | 'agreement';
@ -87,6 +88,8 @@ export interface ConsolePlan {
allowed: { button: string; class: string; where: string }[];
/** The rule in one line. */
rule: string;
/** true: the final button is the agent's own (a portal capability edit such as Save on an App ID, not a store submission or a public change). */
finalByAgent?: boolean;
};
/** Known UI facts of this form (verified ones say so). */
uiFacts: string[];
@ -110,6 +113,8 @@ export interface PlanIds {
signals?: ProjectSignals;
/** play-publish-changes: the production releases ready to publish per the API (null/undefined: not read). */
readyChanges?: { track: string; version: string | null; build: string | null; rollout: string }[] | null;
/** apple-app-group: the targets whose entitlements list App Groups (their bundle id, groups and, with --lookup, the App Store Connect resource id for the portal deep link). */
appGroupTargets?: { bundleId: string; name?: string; groups: string[]; resourceId?: string | null; source?: string }[];
}
const ASC = 'https://appstoreconnect.apple.com';
@ -538,6 +543,7 @@ export interface PlanOpts { all?: boolean }
export function consolePlan(form: PlanFormId, config: ShipConfig, p: PlanIds = {}, o: PlanOpts = {}): ConsolePlan {
const cfg = p.appleAppId && config.apple && !config.apple.appId ? { ...config, apple: { ...config.apple, appId: p.appleAppId } } : config;
if (form === 'play-app-content') return appContentPlan(cfg, p, o.all);
if (form === 'apple-app-group') return appleAppGroupPlan(p);
if (isPlanOnly(form)) {
const part = playOnlyPart(form, cfg, p);
return {
@ -583,7 +589,7 @@ export function planText(pl: ConsolePlan): string {
L.push(` ${tag} ${a.question}: ${a.text}${a.label ? ` -> ${a.action ?? ''} "${a.label}"${a.curlyQuotes ? ' (curly quotes)' : ''}` : ''}${a.where ? ` @ ${a.where}` : ''}`);
if (a.status !== 'certain' && a.note) L.push(` ${a.note}`);
}
L.push('', `Never press: ${pl.buttons.neverPress.map(b => `"${b}"`).join(', ')}`, `Final button (the owner's): ${pl.buttons.final}`, `Rule: ${pl.buttons.rule}`, '', 'UI facts:', ...pl.uiFacts.map(f => ` - ${f}`), '', 'Driving:', ...pl.driving.map(d => ` - ${d}`),
L.push('', `Never press: ${pl.buttons.neverPress.map(b => `"${b}"`).join(', ')}`, `Final button (${pl.buttons.finalByAgent ? "the agent's own, not a store submission" : "the owner's"}): ${pl.buttons.final}`, `Rule: ${pl.buttons.rule}`, '', 'UI facts:', ...pl.uiFacts.map(f => ` - ${f}`), '', 'Driving:', ...pl.driving.map(d => ` - ${d}`),
'', 'In-page helper (plan.inPageLoop: paste it once per page in one short call, then window.__sb.run([...]) and poll window.__log):', ...pl.inPageLoop.split('\n').map(l => ` ${l}`),
'', `Verify: ${pl.verify.command}`, ...pl.verify.expect.map(e => ` - ${e}`));
if (pl.askOwner.length) L.push('', 'Ask the owner first:', ...pl.askOwner.map(a => ` - ${a}`));