@@ -12,6 +12,9 @@ if [[ "${OS_NAME}" == "osx" ]]; then
1212 if [[ " ${CI_BUILD} " == " no" ]]; then
1313 RUNNER_TEMP=" ${TMPDIR} "
1414 fi
15+ # Identity-based code-signing + Apple notarization path.
16+ # Active when CERTIFICATE_OSX_P12_DATA is present (paid Apple Developer
17+ # Program membership available). Produces Gatekeeper-clean builds.
1518
1619 CERTIFICATE_P12=" ${APP_NAME} .p12"
1720 KEYCHAIN=" ${RUNNER_TEMP} /buildagent.keychain"
@@ -203,6 +206,61 @@ if [[ "${OS_NAME}" == "osx" ]]; then
203206
204207 rm " ${ZIP_FILE} "
205208
209+ cd ..
210+ else
211+ # Ad-hoc signing fallback.
212+ # Active when CERTIFICATE_OSX_P12_DATA is absent (no paid Apple Developer
213+ # Program membership). Signs the bundle with the ad-hoc identity ("-") so
214+ # the .app is structurally valid (nested Helpers verify, dyld accepts
215+ # hardened binaries on Apple Silicon) without requiring a Developer ID
216+ # cert or paying Apple's notarization fee. Notarization and stapling are
217+ # skipped — users will see a Gatekeeper "unverified developer" prompt on
218+ # first launch and need to right-click → Open (or run xattr -cr on the
219+ # .app). This matches what VSCodium, MacVim, and most open-source macOS
220+ # apps ship.
221+ echo " + APPLE_ID not set — using ad-hoc signing, skipping notarization. Users will need to bypass Gatekeeper on first launch."
222+
223+ cd " VSCode-darwin-${VSCODE_ARCH} "
224+
225+ APP_BUNDLE=$( find . -maxdepth 1 -name " *.app" -type d | head -n 1 )
226+ if [[ -z " ${APP_BUNDLE} " ]]; then
227+ echo " Error: No .app bundle found in VSCode-darwin-${VSCODE_ARCH} "
228+ ls -la
229+ exit 1
230+ fi
231+ APP_BUNDLE=" ${APP_BUNDLE# ./ } "
232+
233+ # Sign every nested Mach-O first (helpers, frameworks, dylibs, language
234+ # binaries), then sign the outer .app bundle. `--deep` on the outer call
235+ # is not sufficient on its own because some nested signables (e.g. the
236+ # Electron Framework helpers, embedded node binaries) need to be signed
237+ # bottom-up to satisfy the runtime loader on Apple Silicon.
238+ echo " + ad-hoc signing nested binaries"
239+ find " ${APP_BUNDLE} " \
240+ \( -name ' *.dylib' -o -name ' *.framework' -o -name ' *.node' \
241+ -o -name ' *.app' \) \
242+ -print0 |
243+ while IFS= read -r -d ' ' nested; do
244+ # Skip the outer .app itself; we sign it last.
245+ if [[ " ${nested} " == " ${APP_BUNDLE} " ]]; then
246+ continue
247+ fi
248+ codesign --force --sign - --timestamp=none " ${nested} " || {
249+ echo " Warning: ad-hoc sign failed for ${nested} "
250+ }
251+ done
252+
253+ echo " + ad-hoc signing app bundle (deep)"
254+ codesign --force --deep --sign - --timestamp=none " ${APP_BUNDLE} "
255+
256+ echo " + verifying ad-hoc signature"
257+ if ! codesign --verify --deep --strict --verbose=2 " ${APP_BUNDLE} " 2>&1 ; then
258+ echo " Error: Ad-hoc signature verification failed"
259+ codesign -dv --verbose=4 " ${APP_BUNDLE} " 2>&1
260+ exit 1
261+ fi
262+ echo " ✓ Ad-hoc signature is valid (Gatekeeper will still prompt users on first launch)"
263+
206264 cd ..
207265 fi
208266
0 commit comments