apps folders add adds the folder (template note, refusals with reasons); MCP: .mcp.json never spawns a missing plugin path (sh fallback to PATH, npx), mcp/serve skip the self-update, spawned handshake test; store build minimums in one dated table: Play target API 36 and App Store Xcode 26 / SDK 26 blocked in scan, validate, play upload/release, apple upload; pitfalls 81-83

This commit is contained in:
CRTkafa 2026-10-20 12:15:00 +07:00
parent 9805582278
commit 9ab64bcbdf
16 changed files with 323 additions and 14 deletions

View file

@ -14,6 +14,7 @@
// with `apple testflight wait` (waitForBuild) until processingState is VALID (exit 0), INVALID / FAILED (exit 1) or the
// timeout (exit 7).
// An upload is a write: --dry shows the plan; a real run asks first (--yes in scripts).
import { appleSdkProblem } from '../lib/store-minimums';
import { closeSync, existsSync, openSync, readdirSync, readSync, statSync } from 'node:fs';
import { basename, join, relative } from 'node:path';
import { ascKeyFile } from '../lib/credentials';
@ -230,6 +231,9 @@ export async function run(ctx: Ctx): Promise<void> {
const info = ipaInfo(ipa);
if (want && info.build !== want) throw new Error(`${relative(root, ipa)} is build ${info.build}, not ${want} (--build): did the last apple build fail?`);
if (info.bundleId !== bundleId) throw new Error(`${relative(root, ipa)} is ${info.bundleId}, the config says ${bundleId}`);
// App Store Connect refuses IPAs from an Xcode / SDK older than its current minimum (cli/lib/store-minimums.ts)
const sdkWhy = appleSdkProblem(info);
if (sdkWhy) throw new Error(`${relative(root, ipa)}: not uploaded, ${sdkWhy}`);
// every PrivacyInfo.xcprivacy in the app (root, Frameworks, bundles): Apple refuses the build minutes after the
// upload when NSPrivacyTracking and NSPrivacyTrackingDomains disagree (ITMS-91064), so stop before any network call
const privacy = bundleTrackingIssues(ipaManifests(ipa));