From e57fa7e058036a2ed6e75f7024d6b493f5575f05 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sun, 10 May 2026 11:01:30 -0700 Subject: [PATCH] RU-T51 Build fixes --- .gitignore | 1 + app.config.ts | 8 +++- plugins/withCheckInLiveActivity.js | 59 +++++++++++++++++++++--------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 11e51f4..b4bbade 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ expo-env.d.ts # @end expo-cli .dual-graph/ .mcp.json +opencode.json diff --git a/app.config.ts b/app.config.ts index 2f06199..ab2a305 100644 --- a/app.config.ts +++ b/app.config.ts @@ -224,7 +224,13 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ './plugins/withForegroundNotifications.js', './plugins/withNotificationSounds.js', './plugins/withMediaButtonModule.js', - './plugins/withCheckInLiveActivity.js', + [ + './plugins/withCheckInLiveActivity.js', + { + teamId: 'QKQVAJMTCN', + enableLiveActivityEntitlement: Env.APP_ENV === 'production' || Env.APP_ENV === 'internal', + }, + ], './plugins/withInCallAudioModule.js', ['app-icon-badge', appIconBadgeConfig], ], diff --git a/plugins/withCheckInLiveActivity.js b/plugins/withCheckInLiveActivity.js index edaea70..387f625 100644 --- a/plugins/withCheckInLiveActivity.js +++ b/plugins/withCheckInLiveActivity.js @@ -298,18 +298,22 @@ const WIDGET_INFO_PLIST = ` `; -const withCheckInLiveActivity = (config) => { +const withCheckInLiveActivity = (config, props = {}) => { + const { teamId, enableLiveActivityEntitlement = true } = props; + // Step 1: Add NSSupportsLiveActivities to Info.plist config = withInfoPlist(config, (config) => { config.modResults.NSSupportsLiveActivities = true; return config; }); - // Step 2: Add live activity entitlement - config = withEntitlementsPlist(config, (config) => { - config.modResults['com.apple.developer.live-activity'] = true; - return config; - }); + // Step 2: Add live activity entitlement (only if the provisioning profile supports it) + if (enableLiveActivityEntitlement) { + config = withEntitlementsPlist(config, (config) => { + config.modResults['com.apple.developer.live-activity'] = true; + return config; + }); + } // Step 3: Write Swift Widget Extension files and native bridge config = withDangerousMod(config, [ @@ -328,6 +332,17 @@ const withCheckInLiveActivity = (config) => { fs.writeFileSync(path.join(widgetDir, 'CheckInTimerWidgetBundle.swift'), WIDGET_BUNDLE_SWIFT); fs.writeFileSync(path.join(widgetDir, 'Info.plist'), WIDGET_INFO_PLIST); + // Write an entitlements file for the widget extension. + // Required for signing; the entitlements can be empty but the file must exist + // so Xcode doesn't fall back to the main target's entitlements. + const widgetEntitlements = ` + + + + +`; + fs.writeFileSync(path.join(widgetDir, 'CheckInTimerWidget.entitlements'), widgetEntitlements); + // Write native bridge files to the main app directory. // resolveIosAppName throws explicitly if the target cannot be determined, // preventing files from being written to a wrong/hardcoded path. @@ -444,21 +459,28 @@ const withCheckInLiveActivity = (config) => { const resolvedCurrentProjectVersion = hostCurrentProjectVersion || (config.ios?.buildNumber ?? '1'); - // Resolve DEVELOPMENT_TEAM from the host target so the widget extension - // can be signed. EAS sets this on the main target during credential - // application; copying it here ensures the widget inherits it. - let hostDevelopmentTeam = null; - const hostBuildConfigListId = targetSection[hostTarget.uuid].buildConfigurationList; - const hostBuildConfigList = project.pbxXCConfigurationList()[hostBuildConfigListId]; - if (hostBuildConfigList) { - const firstHostConfigUuid = hostBuildConfigList.buildConfigurations[0]?.value; - if (firstHostConfigUuid) { - const firstHostConfig = project.pbxXCBuildConfigurationSection()[firstHostConfigUuid]; - if (firstHostConfig?.buildSettings) { - hostDevelopmentTeam = firstHostConfig.buildSettings.DEVELOPMENT_TEAM || null; + // Resolve DEVELOPMENT_TEAM for the widget extension. + // Priority: plugin config param > host target build settings > env var. + // Note: EAS applies credentials *after* prebuild, so reading from the + // host target at this point will usually return null. Pass teamId via + // the plugin config in app.config.ts for reliable widget signing. + let hostDevelopmentTeam = teamId || null; + if (!hostDevelopmentTeam) { + const hostBuildConfigListId = targetSection[hostTarget.uuid].buildConfigurationList; + const hostBuildConfigList = project.pbxXCConfigurationList()[hostBuildConfigListId]; + if (hostBuildConfigList) { + const firstHostConfigUuid = hostBuildConfigList.buildConfigurations[0]?.value; + if (firstHostConfigUuid) { + const firstHostConfig = project.pbxXCBuildConfigurationSection()[firstHostConfigUuid]; + if (firstHostConfig?.buildSettings) { + hostDevelopmentTeam = firstHostConfig.buildSettings.DEVELOPMENT_TEAM || null; + } } } } + if (!hostDevelopmentTeam) { + hostDevelopmentTeam = process.env.EXPO_APPLE_TEAM_ID || null; + } const buildConfigListId = targetSection[widgetTarget.uuid].buildConfigurationList; const buildConfigList = project.pbxXCConfigurationList()[buildConfigListId]; @@ -469,6 +491,7 @@ const withCheckInLiveActivity = (config) => { Object.assign(buildConfig.buildSettings, { // Override the default addTarget placeholder (TargetName-Info.plist) INFOPLIST_FILE: `"${WIDGET_NAME}/Info.plist"`, + CODE_SIGN_ENTITLEMENTS: `"${WIDGET_NAME}/CheckInTimerWidget.entitlements"`, SWIFT_VERSION: '"5.0"', TARGETED_DEVICE_FAMILY: '"1,2"', // ActivityKit requires iOS 16.1 or later