@@ -136,32 +136,28 @@ jobs:
136136
137137 - name : Build Release Archive
138138 run : |
139- # Archive with Automatic signing + allowProvisioningUpdates.
140- # The API key lets Xcode auto-create/download the Mac Development
141- # provisioning profile for iCloud/App Groups entitlements.
142- # CODE_SIGN_IDENTITY is NOT overridden here — that conflicts with
143- # Automatic style. The export + re-sign steps apply Developer ID.
139+ # Manual signing with Developer ID identity + our Developer ID
140+ # provisioning profile. Xcode reconciles app entitlements with the
141+ # profile's authorized entitlements at sign time — no re-sign step
142+ # is needed (and re-sign was the root cause of AMFI rejections in
143+ # v2.4.0–v2.4.2: codesign --entitlements embedded a verbatim plist
144+ # whose format/values did not match the embedded profile).
144145 xcodebuild \
145146 -project DoomCoder.xcodeproj \
146147 -scheme DoomCoder \
147148 -configuration Release \
148149 -archivePath build/DoomCoder.xcarchive \
149- -allowProvisioningUpdates \
150- -authenticationKeyPath "${{ steps.write-asc-key.outputs.key_path }}" \
151- -authenticationKeyID "${{ steps.write-asc-key.outputs.key_id }}" \
152- -authenticationKeyIssuerID "${{ steps.write-asc-key.outputs.issuer_id }}" \
153150 archive \
154- CODE_SIGN_STYLE=Automatic \
151+ CODE_SIGN_STYLE=Manual \
152+ CODE_SIGN_IDENTITY="Developer ID Application" \
153+ PROVISIONING_PROFILE_SPECIFIER="DoomCoder Mac DevID" \
155154 DEVELOPMENT_TEAM="${{ secrets.APPLE_TEAM_ID }}" \
156155 MARKETING_VERSION="${{ env.VERSION }}" \
157- CURRENT_PROJECT_VERSION="${{ env.BUILD }}"
156+ CURRENT_PROJECT_VERSION="${{ env.BUILD }}" \
157+ OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime"
158158
159- - name : Extract app from archive
159+ - name : Extract signed app from archive
160160 run : |
161- # Skip xcodebuild -exportArchive — it requires downloading a
162- # Developer ID provisioning profile via cloud signing (needs Admin
163- # role). The archive already contains the built .app; we extract it
164- # directly and the re-sign step will apply the correct Developer ID.
165161 mkdir -p build/export
166162 APP_IN_ARCHIVE="build/DoomCoder.xcarchive/Products/Applications/DoomCoder.app"
167163 if [ ! -d "$APP_IN_ARCHIVE" ]; then
@@ -170,84 +166,24 @@ jobs:
170166 exit 1
171167 fi
172168 cp -R "$APP_IN_ARCHIVE" build/export/DoomCoder.app
173- echo "✅ Extracted DoomCoder.app from archive"
174- echo " Size: $(du -sh build/export/DoomCoder.app | cut -f1)"
175-
176- - name : Embed Developer ID provisioning profile
177- run : |
178169 APP="build/export/DoomCoder.app"
179- # Replace the auto-generated Mac Development profile (from the
180- # archive's Automatic signing) with our Developer ID profile.
181- # Gatekeeper verifies signing identity is listed in this profile.
182- cp "${MAC_PROFILE_PATH}" "${APP}/Contents/embedded.provisionprofile"
183- echo "✅ Embedded Developer ID profile"
184- security cms -D -i "${APP}/Contents/embedded.provisionprofile" \
170+ echo "✅ Extracted DoomCoder.app from archive"
171+ echo " Size: $(du -sh "$APP" | cut -f1)"
172+ echo ""
173+ echo "=== Embedded provisioning profile ==="
174+ security cms -D -i "$APP/Contents/embedded.provisionprofile" \
185175 | plutil -extract Name xml1 -o - - | grep '<string>'
186-
187- - name : Re-sign all embedded code (inside-out)
188- run : |
189- APP="build/export/DoomCoder.app"
190- IDENTITY="Developer ID Application"
191- ENTS="DoomCoder/DoomCoder.Release.entitlements"
192-
193- # Fail loudly if the app wasn't exported where we expect
194- if [ ! -d "$APP" ]; then
195- echo "::error::Exported app not found at $APP — contents of build/export/:"
196- ls -laR build/export/ || true
197- exit 1
198- fi
199-
200- sign_file() {
201- echo " → $(basename "$1")"
202- codesign --force --sign "$IDENTITY" --timestamp --options runtime "$1"
203- }
204-
205- # ── Pass 1: every Mach-O binary (deepest path first) ──────────────
206- # Use process substitution (<) so the while loop runs in the CURRENT
207- # shell — pipe-to-while runs in a subshell where errors are swallowed.
208- echo "=== Pass 1: Mach-O binaries ==="
209- FAIL=0
210- while IFS= read -r f; do
211- if file "$f" 2>/dev/null | grep -qE "Mach-O|shared library"; then
212- sign_file "$f" || FAIL=1
213- fi
214- done < <(find "$APP" -type f \
215- | awk '{ printf "%d\t%s\n", gsub("/","/"), $0 }' \
216- | sort -rn | cut -f2-)
217- [ "$FAIL" -eq 0 ] || { echo "::error::One or more Mach-O binaries failed to sign"; exit 1; }
218-
219- # ── Pass 2: XPC service bundles ────────────────────────────────────
220- echo "=== Pass 2: XPC service bundles ==="
221- while IFS= read -r xpc; do
222- sign_file "$xpc"
223- done < <(find "$APP" -type d -name "*.xpc" \
224- | awk '{ printf "%d\t%s\n", gsub("/","/"), $0 }' \
225- | sort -rn | cut -f2-)
226-
227- # ── Pass 3: nested .app bundles (e.g. Sparkle's Updater.app) ──────
228- echo "=== Pass 3: nested .app bundles ==="
229- while IFS= read -r nested; do
230- sign_file "$nested"
231- done < <(find "$APP" -mindepth 2 -type d -name "*.app" \
232- | awk '{ printf "%d\t%s\n", gsub("/","/"), $0 }' \
233- | sort -rn | cut -f2-)
234-
235- # ── Pass 4: frameworks ─────────────────────────────────────────────
236- echo "=== Pass 4: frameworks ==="
237- while IFS= read -r fw; do
238- sign_file "$fw"
239- done < <(find "$APP" -type d -name "*.framework" \
240- | awk '{ printf "%d\t%s\n", gsub("/","/"), $0 }' \
241- | sort -rn | cut -f2-)
242-
243- # ── Pass 5: main app bundle (with entitlements, always last) ───────
244- echo "=== Pass 5: main app ==="
245- codesign --force --sign "$IDENTITY" --timestamp --options runtime \
246- --entitlements "$ENTS" "$APP"
247-
248- echo "=== Verify bundle ==="
176+ echo ""
177+ echo "=== Signing identity ==="
178+ codesign -dv "$APP" 2>&1 | grep -E "Authority|TeamIdentifier|Identifier="
179+ echo ""
180+ echo "=== Bundled entitlements ==="
181+ codesign -d --entitlements - --xml "$APP" 2>/dev/null \
182+ | plutil -convert xml1 -o - -
183+ echo ""
184+ echo "=== Deep verify ==="
249185 codesign --verify --deep --strict --verbose=2 "$APP"
250- echo "✅ Re-sign complete "
186+ echo "✅ Archive signing verified "
251187
252188 - name : Audit all binary signatures
253189 run : |
0 commit comments