Console pages as absolute deep links: cli/lib/console-links.ts builds the URL of every App Store Connect / Play Console page from apple.appId, play.developerId and play.appId (app list / developer chooser when unknown); every plain 'App Store Connect > ...' / 'Play Console > ...' direction in cli/ and templates/ now carries it, validate / scan / declarations / release plan JSON carry url, the desktop shows an Open button; tests/console-links.test.ts guards it; AGENTS rule 11, pitfall 71
This commit is contained in:
parent
f898d642d0
commit
e500e88e40
50 changed files with 381 additions and 92 deletions
|
|
@ -4,6 +4,7 @@
|
|||
// run, only plain `key("value")` lines are taken, everything else is reported as "set by hand".
|
||||
// Secrets and personal data never enter the plan's files: key files are named as references to move into .storebound/,
|
||||
// App Review contact and demo account files are reported (the owner copies them), team / app ids become placeholders.
|
||||
import { consoleLink } from './console-links';
|
||||
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
||||
import { basename, dirname, extname, join, relative, resolve, sep } from 'node:path';
|
||||
import { imageInfo } from '../shots/spec';
|
||||
|
|
@ -426,7 +427,7 @@ export function planImport(scan: FastlaneScan, o: PlanOptions): ImportPlan {
|
|||
else notMapped.push({ what: `${f}: "${raw}"`, where: 'apple.info.categories in storebound.config.ts (App Store Connect ids such as GAMES, PRODUCTIVITY, GAMES_PUZZLE)' });
|
||||
}
|
||||
for (const f of ['secondary_first_sub_category', 'secondary_second_sub_category'])
|
||||
if (scan.deliver.root[f]) notMapped.push({ what: `${f}.txt`, where: 'set in App Store Connect > App Information (storebound sets primary sub-categories only)' });
|
||||
if (scan.deliver.root[f]) notMapped.push({ what: `${f}.txt`, where: `set in ${consoleLink('asc.app-info')} (storebound sets primary sub-categories only)` });
|
||||
const profile: AppProfile = o.profile ?? (cats.primary === 'GAMES' ? 'game' : 'app');
|
||||
const style: 'game' | 'app' = profile === 'game' ? 'game' : 'app';
|
||||
|
||||
|
|
@ -440,7 +441,7 @@ export function planImport(scan: FastlaneScan, o: PlanOptions): ImportPlan {
|
|||
if (demo.length) secrets.push({ what: `review_information/${demo.join(', ')} (App Review demo account)`, where: 'not copied: the owner puts it in .storebound/credentials.json "reviewDemoAccount": { username, password } (review-access skill); reviewAccess.signInRequired was set to true' });
|
||||
const signIn = demo.includes('demo_user.txt');
|
||||
if (scan.deliver.metadata && isDir(join(scan.deliver.metadata, 'trade_representative_contact_information')))
|
||||
notMapped.push({ what: 'trade_representative_contact_information/ (Korea)', where: 'App Store Connect > App Information (personal data, not imported)' });
|
||||
notMapped.push({ what: 'trade_representative_contact_information/ (Korea)', where: `${consoleLink('asc.app-info')} (personal data, not imported)` });
|
||||
|
||||
// --- App Store listing
|
||||
const appleSections: string[] = [];
|
||||
|
|
@ -535,8 +536,8 @@ ${secs.join('\n\n')}
|
|||
const id = idOfPlay(l.code)!;
|
||||
const fg = l.images.featureGraphic;
|
||||
if (fg) { const p = `store/renders/${id}/feature/1024x500${extname(fg).toLowerCase().replace('.jpeg', '.jpg')}`; files.push({ path: p, from: fg, src: rel(fg), kind: 'feature' }); mapped.push({ from: rel(fg), to: p }); }
|
||||
for (const k of ['promoGraphic', 'tvBanner']) if (l.images[k]) notMapped.push({ what: rel(l.images[k]!), where: 'Play Console > Store listing (storebound uploads icon, feature graphic and phone / tablet screenshots)' });
|
||||
for (const k of ['tv', 'wear'] as const) if (l.shots[k].length) notMapped.push({ what: `metadata/android/${l.folder}/images/${k}Screenshots (${l.shots[k].length})`, where: `Play Console > Store listing (${k === 'tv' ? 'Android TV' : 'Wear OS'} screenshots)` });
|
||||
for (const k of ['promoGraphic', 'tvBanner']) if (l.images[k]) notMapped.push({ what: rel(l.images[k]!), where: `${consoleLink('play.store-listing')} (storebound uploads icon, feature graphic and phone / tablet screenshots)` });
|
||||
for (const k of ['tv', 'wear'] as const) if (l.shots[k].length) notMapped.push({ what: `metadata/android/${l.folder}/images/${k}Screenshots (${l.shots[k].length})`, where: `${consoleLink('play.store-listing')} (${k === 'tv' ? 'Android TV' : 'Wear OS'} screenshots)` });
|
||||
}
|
||||
|
||||
// screenshots -> frames: <frames>/<lang id>/<phone|tablet>/NN.png; iOS shots win over Play shots for the same language
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue