From 469c875706c5e9e29ad19d561c9d8fc2c0db3ac7 Mon Sep 17 00:00:00 2001 From: Derek Bourgeois Date: Wed, 25 Mar 2026 02:24:40 -0400 Subject: [PATCH 1/2] fix: untangle macos release notarization --- .github/workflows/tagged-release.yml | 44 ++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml index e92cc7c..7eec1c2 100644 --- a/.github/workflows/tagged-release.yml +++ b/.github/workflows/tagged-release.yml @@ -148,6 +148,7 @@ jobs: NATIVEPHP_UPDATER_ENABLED: false SURREAL_VERSION: v3.0.4 CSC_IDENTITY_AUTO_DISCOVERY: 'true' + KATRA_SKIP_NATIVEPHP_AFTERSIGN_NOTARIZE: 'true' NATIVEPHP_APPLE_ID: ${{ secrets.MACOS_NOTARY_APPLE_ID }} NATIVEPHP_APPLE_ID_PASS: ${{ secrets.MACOS_NOTARY_APP_SPECIFIC_PASSWORD }} NATIVEPHP_APPLE_TEAM_ID: ${{ secrets.MACOS_NOTARY_TEAM_ID }} @@ -263,16 +264,21 @@ jobs: const path = 'vendor/nativephp/desktop/resources/electron/build/notarize.js'; const current = readFileSync(path, 'utf8'); const normalized = current.replace(/\r\n/g, '\n'); - const pattern = /(\s+console\.error\(error\)\n)(\s+\})/; + const marker = " console.log('aftersign hook triggered, start to notarize app.')\n"; + const snippet = " if (process.env.KATRA_SKIP_NATIVEPHP_AFTERSIGN_NOTARIZE === 'true') {\n console.log('skipping NativePHP afterSign notarization because the workflow notarizes artifacts explicitly.')\n return\n }\n\n"; - if (! pattern.test(normalized)) { - throw new Error('Unable to locate the NativePHP notarization error handler.'); + if (normalized.includes('KATRA_SKIP_NATIVEPHP_AFTERSIGN_NOTARIZE')) { + process.exit(0); } - const updated = normalized.replace(pattern, "$1 throw error\n$2"); + if (! normalized.includes(marker)) { + throw new Error('Unable to locate the NativePHP afterSign hook marker.'); + } + + const updated = normalized.replace(marker, marker + snippet); if (updated === normalized) { - throw new Error('Unable to harden the NativePHP notarization hook.'); + throw new Error('Unable to patch the NativePHP afterSign notarization hook.'); } writeFileSync(path, updated); @@ -349,7 +355,12 @@ jobs: fi dmg_path="$candidate" - done < <(find nativephp/electron/dist -maxdepth 1 -type f -name '*.dmg' | sort) + done < <(find nativephp/electron/dist -maxdepth 2 -type f -name '*.dmg' | sort) + + if [[ -z "$app_bundle_path" || -z "$dmg_path" ]]; then + echo "Discovered files under nativephp/electron/dist:" >&2 + find nativephp/electron/dist -maxdepth 3 -print | sort >&2 + fi if [[ -z "$app_bundle_path" ]]; then echo "No macOS .app bundle was generated." >&2 @@ -369,6 +380,27 @@ jobs: codesign --verify --deep --strict --verbose=2 "$KATRA_MACOS_APP_BUNDLE_PATH" codesign --display --verbose=4 "$KATRA_MACOS_APP_BUNDLE_PATH" + - name: Create app notarization archive + run: | + set -euo pipefail + + app_archive_path="$RUNNER_TEMP/$(basename "$KATRA_MACOS_APP_BUNDLE_PATH").zip" + rm -f "$app_archive_path" + + ditto -c -k --sequesterRsrc --keepParent \ + "$KATRA_MACOS_APP_BUNDLE_PATH" \ + "$app_archive_path" + + echo "KATRA_MACOS_APP_ARCHIVE_PATH=$app_archive_path" >> "$GITHUB_ENV" + + - name: Notarize app bundle + run: | + xcrun notarytool submit "$KATRA_MACOS_APP_ARCHIVE_PATH" \ + --apple-id "$NATIVEPHP_APPLE_ID" \ + --password "$NATIVEPHP_APPLE_ID_PASS" \ + --team-id "$NATIVEPHP_APPLE_TEAM_ID" \ + --wait + - name: Staple notarized app bundle run: | xcrun stapler staple "$KATRA_MACOS_APP_BUNDLE_PATH" From 73edf8923052e1881ea896c7003286716c89ef74 Mon Sep 17 00:00:00 2001 From: Derek Bourgeois Date: Wed, 25 Mar 2026 09:12:28 -0400 Subject: [PATCH 2/2] fix: harden macos release workflow patching --- .github/workflows/tagged-release.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml index 7eec1c2..8f7f344 100644 --- a/.github/workflows/tagged-release.yml +++ b/.github/workflows/tagged-release.yml @@ -264,18 +264,18 @@ jobs: const path = 'vendor/nativephp/desktop/resources/electron/build/notarize.js'; const current = readFileSync(path, 'utf8'); const normalized = current.replace(/\r\n/g, '\n'); - const marker = " console.log('aftersign hook triggered, start to notarize app.')\n"; + const marker = /(\s+console\.log\(['"]aftersign hook triggered, start to notarize app\.['"]\)\s*\n)/; const snippet = " if (process.env.KATRA_SKIP_NATIVEPHP_AFTERSIGN_NOTARIZE === 'true') {\n console.log('skipping NativePHP afterSign notarization because the workflow notarizes artifacts explicitly.')\n return\n }\n\n"; if (normalized.includes('KATRA_SKIP_NATIVEPHP_AFTERSIGN_NOTARIZE')) { process.exit(0); } - if (! normalized.includes(marker)) { + if (! marker.test(normalized)) { throw new Error('Unable to locate the NativePHP afterSign hook marker.'); } - const updated = normalized.replace(marker, marker + snippet); + const updated = normalized.replace(marker, `$1${snippet}`); if (updated === normalized) { throw new Error('Unable to patch the NativePHP afterSign notarization hook.'); @@ -358,8 +358,12 @@ jobs: done < <(find nativephp/electron/dist -maxdepth 2 -type f -name '*.dmg' | sort) if [[ -z "$app_bundle_path" || -z "$dmg_path" ]]; then - echo "Discovered files under nativephp/electron/dist:" >&2 - find nativephp/electron/dist -maxdepth 3 -print | sort >&2 + if [[ -d nativephp/electron/dist ]]; then + echo "Discovered files under nativephp/electron/dist:" >&2 + find nativephp/electron/dist -maxdepth 3 -print | sort >&2 || true + else + echo "Directory nativephp/electron/dist does not exist." >&2 + fi fi if [[ -z "$app_bundle_path" ]]; then