mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 14:55:55 +00:00
fix(release): sign CEF inner dylibs so macOS notarization passes (#951)
This commit is contained in:
@@ -464,7 +464,7 @@ jobs:
|
||||
CORE_MANIFEST: ${{ steps.core-paths.outputs.core_manifest }}
|
||||
CORE_BIN_NAME: ${{ steps.core-paths.outputs.core_bin_name }}
|
||||
OPENHUMAN_APP_ENV: ${{ inputs.build_target == 'staging' && 'staging' || 'production' }}
|
||||
OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_SENTRY_DSN }}
|
||||
OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN }}
|
||||
# Sentry release tracking (#405): `option_env!("OPENHUMAN_BUILD_SHA")`
|
||||
# in src/main.rs bakes the short SHA into the release tag
|
||||
# (`openhuman@<version>+<sha>`) so core events match the frontend.
|
||||
@@ -511,7 +511,7 @@ jobs:
|
||||
# (`vite build`) bakes Sentry + debug flags into the final bundle.
|
||||
# Vite is invoked via tauri.conf.json's beforeBuildCommand during
|
||||
# `cargo tauri build`, so these env vars must be present here.
|
||||
VITE_SENTRY_DSN: ${{ vars.VITE_SENTRY_DSN }}
|
||||
VITE_SENTRY_DSN: ${{ vars.OPENHUMAN_REACT_SENTRY_DSN }}
|
||||
VITE_DEBUG: ${{ vars.VITE_DEBUG }}
|
||||
# Sentry release tracking (#405) — must match the Vite build triggered
|
||||
# by Tauri so source maps uploaded there resolve correctly against the
|
||||
@@ -804,24 +804,6 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# TODO: Uncomment this when we have a staging tag
|
||||
# - name: Build and push staging tag
|
||||
# uses: docker/build-push-action@v6
|
||||
# with:
|
||||
# context: .
|
||||
# file: Dockerfile
|
||||
# push: true
|
||||
# tags: |
|
||||
# ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging-${{ needs.prepare-release.outputs.tag }}
|
||||
# cache-from: type=gha
|
||||
# cache-to: type=gha,mode=max
|
||||
# labels: |
|
||||
# org.opencontainers.image.title=openhuman-core
|
||||
# org.opencontainers.image.description=OpenHuman core JSON-RPC server
|
||||
# org.opencontainers.image.version=${{ needs.prepare-release.outputs.version }}
|
||||
# org.opencontainers.image.source=https://github.com/tinyhumansai/openhuman
|
||||
# org.opencontainers.image.revision=${{ needs.prepare-release.outputs.sha }}
|
||||
|
||||
# =========================================================================
|
||||
# Phase 3c: Generate and upload latest.json for the Tauri auto-updater.
|
||||
# Runs after every platform has uploaded its updater artifact (.sig files
|
||||
|
||||
@@ -33,6 +33,12 @@ prompt-dumps/
|
||||
scripts/ci-secrets.json
|
||||
scripts/ci-secrets.local.json
|
||||
|
||||
# act (local GitHub Actions runner)
|
||||
.secrets
|
||||
.vars
|
||||
.actrc
|
||||
.github/act-event.json
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
@@ -80,11 +80,34 @@ rm -f "$DMG_RW"
|
||||
DMG_RW=""
|
||||
|
||||
echo "[dmg] Notarizing DMG..."
|
||||
DMG_SUBMIT_OUT="$(mktemp /tmp/notarize-dmg-XXXXXX.json)"
|
||||
set +e
|
||||
xcrun notarytool submit "$DMG_PATH" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" \
|
||||
--wait
|
||||
--output-format json \
|
||||
--wait > "$DMG_SUBMIT_OUT"
|
||||
DMG_SUBMIT_RC=$?
|
||||
set -e
|
||||
cat "$DMG_SUBMIT_OUT"
|
||||
|
||||
DMG_SUBMISSION_ID="$(/usr/bin/python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("id",""))' "$DMG_SUBMIT_OUT" 2>/dev/null || true)"
|
||||
DMG_SUBMISSION_STATUS="$(/usr/bin/python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get("status",""))' "$DMG_SUBMIT_OUT" 2>/dev/null || true)"
|
||||
rm -f "$DMG_SUBMIT_OUT"
|
||||
|
||||
if [ -n "$DMG_SUBMISSION_ID" ]; then
|
||||
echo "[dmg] Fetching notarytool developer log for $DMG_SUBMISSION_ID:"
|
||||
xcrun notarytool log "$DMG_SUBMISSION_ID" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" || true
|
||||
fi
|
||||
|
||||
if [ "$DMG_SUBMISSION_STATUS" != "Accepted" ] || [ "$DMG_SUBMIT_RC" -ne 0 ]; then
|
||||
echo "[dmg] ERROR: DMG notarization did not succeed (status=$DMG_SUBMISSION_STATUS, rc=$DMG_SUBMIT_RC)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
xcrun stapler staple "$DMG_PATH"
|
||||
echo "[dmg] DMG notarization complete: $DMG_PATH"
|
||||
|
||||
@@ -78,8 +78,23 @@ codesign_framework() {
|
||||
# ── Nested Frameworks/ (CEF + Helper apps) ──────────────────────────────────
|
||||
# Must be signed from the inside out, before the outer .app bundle.
|
||||
if [ -d "$APP_PATH/Contents/Frameworks" ]; then
|
||||
# 1. Sign each *.framework as a single bundle.
|
||||
# 1. For each *.framework: pre-sign loose dylibs/.so files inside it
|
||||
# (CEF puts libEGL, libGLESv2, libvk_swiftshader, libcef_sandbox in
|
||||
# `Libraries/` next to the main binary, NOT under Versions/A/, so the
|
||||
# bundle signature doesn't reach them and notarization rejects them as
|
||||
# ad-hoc signed without a secure timestamp). Then seal the framework
|
||||
# bundle so its CodeResources covers the freshly-signed dylibs.
|
||||
while IFS= read -r -d '' fw; do
|
||||
FW_NAME="$(basename "$fw" .framework)"
|
||||
echo "[sign] Pre-signing inner Mach-O files in: $(basename "$fw")"
|
||||
while IFS= read -r -d '' inner; do
|
||||
# Skip the framework's main binary (sealed by the bundle pass below).
|
||||
case "$inner" in
|
||||
"$fw/$FW_NAME"|"$fw/Versions/"*"/$FW_NAME") continue ;;
|
||||
esac
|
||||
echo "[sign] $(basename "$inner")"
|
||||
codesign_framework "$inner"
|
||||
done < <(find "$fw" \( -name '*.dylib' -o -name '*.so' \) -type f -print0)
|
||||
echo "[sign] Signing framework bundle: $(basename "$fw")"
|
||||
codesign_framework "$fw"
|
||||
done < <(find "$APP_PATH/Contents/Frameworks" -maxdepth 1 -type d -name '*.framework' -print0)
|
||||
@@ -121,16 +136,44 @@ echo "[sign] Notarizing..."
|
||||
NOTARIZE_ZIP="$(mktemp /tmp/OpenHuman-notarize-XXXXXX.zip)"
|
||||
ditto -c -k --keepParent "$APP_PATH" "$NOTARIZE_ZIP"
|
||||
|
||||
SUBMIT_OUT="$(mktemp /tmp/notarize-submit-XXXXXX.json)"
|
||||
set +e
|
||||
xcrun notarytool submit "$NOTARIZE_ZIP" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" \
|
||||
--wait
|
||||
--output-format json \
|
||||
--wait > "$SUBMIT_OUT"
|
||||
SUBMIT_RC=$?
|
||||
set -e
|
||||
|
||||
cat "$SUBMIT_OUT"
|
||||
rm -f "$NOTARIZE_ZIP"
|
||||
|
||||
SUBMISSION_ID="$(/usr/bin/plutil -convert json -o - "$SUBMIT_OUT" 2>/dev/null \
|
||||
| /usr/bin/python3 -c 'import json,sys; print(json.load(sys.stdin).get("id",""))' 2>/dev/null || true)"
|
||||
SUBMISSION_STATUS="$(/usr/bin/plutil -convert json -o - "$SUBMIT_OUT" 2>/dev/null \
|
||||
| /usr/bin/python3 -c 'import json,sys; print(json.load(sys.stdin).get("status",""))' 2>/dev/null || true)"
|
||||
rm -f "$SUBMIT_OUT"
|
||||
|
||||
echo "[sign] notarytool exit=$SUBMIT_RC id=$SUBMISSION_ID status=$SUBMISSION_STATUS"
|
||||
|
||||
if [ -n "$SUBMISSION_ID" ]; then
|
||||
echo "[sign] Fetching notarytool developer log for $SUBMISSION_ID:"
|
||||
xcrun notarytool log "$SUBMISSION_ID" \
|
||||
--apple-id "$APPLE_ID" \
|
||||
--password "$APPLE_PASSWORD" \
|
||||
--team-id "$APPLE_TEAM_ID" || true
|
||||
fi
|
||||
|
||||
if [ "$SUBMISSION_STATUS" != "Accepted" ] || [ "$SUBMIT_RC" -ne 0 ]; then
|
||||
echo "[sign] ERROR: notarization did not succeed (status=$SUBMISSION_STATUS, rc=$SUBMIT_RC)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Staple ───────────────────────────────────────────────────────────────────
|
||||
echo "[sign] Stapling..."
|
||||
xcrun stapler staple "$APP_PATH"
|
||||
|
||||
echo "[sign] Notarization complete"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user