diff --git a/CHANGELOG.md b/CHANGELOG.md index ac553e3..d222a34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Windows: no false "entitlements not referenced by CODE_SIGN_ENTITLEMENTS" warning (paths compared with forward slashes). Pitfall 103. + - **`storebound apps relink`** after a machine move: every "folder not found" entry of the app folder list is pointed at the same app on this machine (by its path or its app name), ids kept so the desktop keeps its accounts and settings; `apps folders` says so when entries are missing. `apps add` names an app after its config's app name. diff --git a/cli/apple/signing.ts b/cli/apple/signing.ts index 724e56c..30ce943 100644 --- a/cli/apple/signing.ts +++ b/cli/apple/signing.ts @@ -14,7 +14,7 @@ import { ensureGcSwitch, gcSwitchPlan, readGcSwitch } from './game-center'; import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs'; import { homedir, tmpdir } from 'node:os'; -import { basename, dirname, join, relative, resolve as resolvePath } from 'node:path'; +import { basename, dirname, join, relative, resolve as resolvePath, sep } from 'node:path'; import type { Ctx } from '../lib/ctx'; import { confirm, need } from '../lib/ctx'; import { buildCsr, csrContent, newSigningKey, spkiOfKey } from '../lib/csr'; @@ -83,9 +83,11 @@ export function readProjectEntitlements(root: string): ProjectEntitlements[] | n for (const n of names) { const f = join(dir, n); if (n.endsWith('.entitlements')) { - const rel = relative(root, f); + // forward slashes on every OS: the pbxproj writes App/App.entitlements, Windows paths use backslashes + const rel = relative(root, f).split(sep).join('/'); + const fwd = f.split(sep).join('/'); if (isBuildCopyPath(rel) || out.some(o => o.file === rel)) continue; - out.push(projectEntitlements(rel, readFileSync(f, 'utf8'), pbx ? refs.some(r => f.endsWith('/' + r)) : null)); + out.push(projectEntitlements(rel, readFileSync(f, 'utf8'), pbx ? refs.some(r => fwd.endsWith('/' + r.replace(/\\/g, '/'))) : null)); } else if (d > 0 && !n.startsWith('.') && !['node_modules', 'Pods', 'build', 'DerivedData'].includes(n) && !n.endsWith('.xcodeproj')) { try { if (statSync(f).isDirectory()) walk(f, d - 1); } catch { /* unreadable */ } } diff --git a/skills/store-pitfalls/SKILL.md b/skills/store-pitfalls/SKILL.md index ec8c872..6f89dc2 100644 --- a/skills/store-pitfalls/SKILL.md +++ b/skills/store-pitfalls/SKILL.md @@ -1243,3 +1243,11 @@ that fails without the fix (see CONTRIBUTING.md). language in the same edit. Then run `play images` for the screenshots. - **Guard:** `firstGraphics` in `cli/play/images.ts`, used by `cli/play/listing.ts` for languages Play does not have yet; it stops with the fix when the 512x512 icon is missing. + +## 103. "App.entitlements is not referenced by CODE_SIGN_ENTITLEMENTS" on Windows although it is +- **Symptom:** on Windows, `apple status` / `apple signing` warned that `ios\App\App\App.entitlements` is not + referenced, while project.pbxproj sets `CODE_SIGN_ENTITLEMENTS = App/App.entitlements` for both configurations. +- **Cause:** the check compared the Windows path (backslashes) with the pbxproj's forward-slash path. +- **Do:** update storebound; the warning was false. +- **Guard:** `readProjectEntitlements` in `cli/apple/signing.ts` compares forward-slash paths on every OS + (`tests/entitlements-ref.test.ts`). diff --git a/tests/entitlements-ref.test.ts b/tests/entitlements-ref.test.ts new file mode 100644 index 0000000..8d1c56c --- /dev/null +++ b/tests/entitlements-ref.test.ts @@ -0,0 +1,18 @@ +// The entitlements file the pbxproj names is "referenced" on every OS (Windows paths use backslashes; pitfall 103). +import { expect, test } from 'bun:test'; +import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { readProjectEntitlements } from '../cli/apple/signing'; + +test('CODE_SIGN_ENTITLEMENTS = App/App.entitlements matches ios/App/App/App.entitlements', () => { + const root = mkdtempSync(join(tmpdir(), 'sb-ent-')); + mkdirSync(join(root, 'ios/App/App.xcodeproj'), { recursive: true }); + mkdirSync(join(root, 'ios/App/App'), { recursive: true }); + writeFileSync(join(root, 'ios/App/App.xcodeproj/project.pbxproj'), 'buildSettings = { CODE_SIGN_ENTITLEMENTS = App/App.entitlements; };\n'); + writeFileSync(join(root, 'ios/App/App/App.entitlements'), 'com.apple.developer.game-center'); + const r = readProjectEntitlements(root)!; + expect(r).toHaveLength(1); + expect(r[0]!.file).toBe('ios/App/App/App.entitlements'); + expect(r[0]!.referenced).toBe(true); +});