chore: standardize quote styles and add new scripts for macOS app handling

- Updated quote styles in package-and-publish.yml for consistency by converting single quotes to double quotes.
- Introduced new scripts: recreate-dmg-macos.sh for DMG recreation after TDLib bundling and resign-macos.sh for re-signing the macOS app bundle, ensuring proper code signing after modifications.
This commit is contained in:
Steven Enamakel
2026-02-05 14:36:58 +05:30
parent f1bf78aafc
commit 8ba6636341
3 changed files with 226 additions and 129 deletions
+32 -129
View File
@@ -14,7 +14,7 @@ on:
branches:
- develop
workflow_run:
workflows: ['Version Bump']
workflows: ["Version Bump"]
types:
- completed
branches:
@@ -169,15 +169,15 @@ jobs:
fail-fast: false
matrix:
settings:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
target: 'aarch64-apple-darwin'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
target: 'x86_64-apple-darwin'
- platform: 'ubuntu-22.04'
args: ''
target: ''
- platform: "macos-latest"
args: "--target aarch64-apple-darwin"
target: "aarch64-apple-darwin"
- platform: "macos-latest"
args: "--target x86_64-apple-darwin"
target: "x86_64-apple-darwin"
- platform: "ubuntu-22.04"
args: ""
target: ""
runs-on: ${{ matrix.settings.platform }}
steps:
- name: Checkout
@@ -197,7 +197,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 24.x
cache: 'yarn'
cache: "yarn"
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -318,7 +318,7 @@ jobs:
# macOS 10.15+ required for std::filesystem used by llama.cpp
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.settings.platform == 'macos-latest' && '10.15' || '' }}
with:
args: '-c ${{ steps.config-overrides.outputs.json }} ${{ matrix.settings.args }}'
args: "-c ${{ steps.config-overrides.outputs.json }} ${{ matrix.settings.args }}"
includeDebug: ${{ needs.get-version.outputs.should-publish == '' && inputs.forceRelease != 'true' }}
includeRelease: ${{ needs.get-version.outputs.should-publish != '' || inputs.forceRelease == 'true' }}
# Don't let tauri-action upload for macOS - we need to bundle TDLib first and recreate the DMG
@@ -327,125 +327,28 @@ jobs:
owner: alphahumanxyz
repo: alphahuman
# Bundle TDLib dylib into macOS app (fixes "Library not loaded" crash)
- name: Bundle TDLib for macOS
if: matrix.settings.platform == 'macos-latest'
run: |
TARGET="${{ matrix.settings.target }}"
echo "Bundling TDLib for target: $TARGET"
chmod +x ./src-tauri/scripts/bundle-tdlib-macos.sh
./src-tauri/scripts/bundle-tdlib-macos.sh release "$TARGET"
# # Bundle TDLib dylib into macOS app (fixes "Library not loaded" crash)
# - name: Bundle TDLib for macOS
# if: matrix.settings.platform == 'macos-latest'
# run: |
# TARGET="${{ matrix.settings.target }}"
# echo "Bundling TDLib for target: $TARGET"
# chmod +x ./src-tauri/scripts/bundle-tdlib-macos.sh
# ./src-tauri/scripts/bundle-tdlib-macos.sh release "$TARGET"
# Re-sign the app after modifying the bundle (required for notarization)
- name: Re-sign macOS app after TDLib bundling
if: matrix.settings.platform == 'macos-latest'
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
run: |
TARGET="${{ matrix.settings.target }}"
echo "Re-signing for target: $TARGET"
# # Re-sign the app after modifying the bundle (required for notarization)
# - name: Re-sign macOS app after TDLib bundling
# if: matrix.settings.platform == 'macos-latest'
# env:
# APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
# APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
# APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
# run: bash ./src-tauri/scripts/resign-macos.sh release "${{ matrix.settings.target }}"
if [ -z "$APPLE_SIGNING_IDENTITY" ] || [ -z "$APPLE_CERTIFICATE" ]; then
echo "No signing identity or certificate provided, skipping re-sign"
exit 0
fi
# Import certificate into a temporary keychain (same approach as tauri-action)
KEYCHAIN_PATH="$RUNNER_TEMP/tdlib-signing.keychain-db"
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
# Create and configure keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Import certificate
CERT_PATH="$RUNNER_TEMP/certificate.p12"
echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH"
security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
rm "$CERT_PATH"
# Add keychain to search list
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Find app bundle in target-specific or default location
if [ -n "$TARGET" ]; then
APP_BUNDLE=$(find "src-tauri/target/$TARGET/release/bundle/macos" -name "*.app" -type d 2>/dev/null | head -1)
fi
if [ -z "$APP_BUNDLE" ]; then
APP_BUNDLE=$(find "src-tauri/target/release/bundle/macos" -name "*.app" -type d 2>/dev/null | head -1)
fi
if [ -n "$APP_BUNDLE" ]; then
echo "Re-signing app bundle: $APP_BUNDLE"
# Sign the bundled dylibs first
for dylib in "$APP_BUNDLE/Contents/Frameworks/"*.dylib; do
if [ -f "$dylib" ]; then
echo "Signing: $dylib"
codesign --force --options runtime --sign "$APPLE_SIGNING_IDENTITY" "$dylib"
fi
done
# Re-sign the entire app bundle
codesign --force --deep --options runtime --sign "$APPLE_SIGNING_IDENTITY" "$APP_BUNDLE"
echo "App re-signed successfully"
# Verify signature
codesign --verify --verbose=2 "$APP_BUNDLE" || echo "Warning: Signature verification had issues"
else
echo "Warning: No app bundle found to re-sign"
fi
# Cleanup keychain
security delete-keychain "$KEYCHAIN_PATH" || true
# Re-create DMG after TDLib bundling (the original DMG was created before bundling)
- name: Recreate DMG with bundled TDLib
if: matrix.settings.platform == 'macos-latest'
run: |
TARGET="${{ matrix.settings.target }}"
echo "Recreating DMG for target: $TARGET"
# Tauri v2 puts .app in bundle/macos/ and .dmg in bundle/dmg/
if [ -n "$TARGET" ]; then
BASE_BUNDLE_DIR="src-tauri/target/$TARGET/release/bundle"
else
BASE_BUNDLE_DIR="src-tauri/target/release/bundle"
fi
MACOS_DIR="$BASE_BUNDLE_DIR/macos"
DMG_DIR="$BASE_BUNDLE_DIR/dmg"
APP_BUNDLE=$(find "$MACOS_DIR" -name "*.app" -type d 2>/dev/null | head -1)
if [ -z "$APP_BUNDLE" ]; then
echo "Error: No app bundle found in $MACOS_DIR"
exit 1
fi
APP_NAME=$(basename "$APP_BUNDLE" .app)
# Find the original DMG in bundle/dmg/ (NOT bundle/macos/)
ORIGINAL_DMG=$(find "$DMG_DIR" -name "*.dmg" -type f 2>/dev/null | head -1)
if [ -z "$ORIGINAL_DMG" ]; then
echo "Warning: No original DMG found in $DMG_DIR, skipping DMG recreation"
exit 0
fi
echo "Recreating DMG with bundled TDLib..."
echo "App bundle: $APP_BUNDLE"
echo "Original DMG: $ORIGINAL_DMG"
# Remove the old DMG
rm -f "$ORIGINAL_DMG"
# Create new DMG with the updated app bundle
DMG_NAME=$(basename "$ORIGINAL_DMG")
hdiutil create -volname "$APP_NAME" -srcfolder "$APP_BUNDLE" -ov -format UDZO "$DMG_DIR/$DMG_NAME"
echo "DMG recreated successfully: $DMG_DIR/$DMG_NAME"
ls -la "$DMG_DIR/$DMG_NAME"
# # Re-create DMG after TDLib bundling (the original DMG was created before bundling)
# - name: Recreate DMG with bundled TDLib
# if: matrix.settings.platform == 'macos-latest'
# run: bash ./src-tauri/scripts/recreate-dmg-macos.sh release "${{ matrix.settings.target }}"
- name: Get file info
id: file-info
+81
View File
@@ -0,0 +1,81 @@
#!/bin/bash
# Recreate macOS DMG after TDLib bundling
# The original DMG is created by tauri-action BEFORE we bundle TDLib,
# so we need to recreate it with the updated .app bundle.
#
# Usage:
# ./recreate-dmg-macos.sh <build_type> [target]
#
# Arguments:
# build_type - "release" or "debug" (default: release)
# target - Optional cross-compilation target (e.g., aarch64-apple-darwin)
#
# Examples:
# ./recreate-dmg-macos.sh release
# ./recreate-dmg-macos.sh release aarch64-apple-darwin
set -e
BUILD_TYPE="${1:-release}"
TARGET="${2:-}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TAURI_DIR="$(dirname "$SCRIPT_DIR")"
echo "=== macOS DMG Recreation ==="
echo "Build type: ${BUILD_TYPE}"
echo "Target: ${TARGET:-default}"
# --- Determine bundle directories ---
# Tauri v2 puts .app in bundle/macos/ and .dmg in bundle/dmg/
BASE_BUNDLE_DIR=""
for search_dir in \
"${TAURI_DIR}/target/${TARGET}/${BUILD_TYPE}/bundle" \
"${TAURI_DIR}/target/${BUILD_TYPE}/bundle" \
"${TAURI_DIR}/target/release/bundle" \
"${TAURI_DIR}/target/debug/bundle"; do
if [ -d "$search_dir/macos" ]; then
BASE_BUNDLE_DIR="$search_dir"
break
fi
done
if [ -z "$BASE_BUNDLE_DIR" ]; then
echo "Warning: No bundle directory found"
exit 0
fi
MACOS_DIR="$BASE_BUNDLE_DIR/macos"
DMG_DIR="$BASE_BUNDLE_DIR/dmg"
echo "Bundle base: $BASE_BUNDLE_DIR"
# --- Find the app bundle ---
APP_BUNDLE=$(find "$MACOS_DIR" -name "*.app" -type d 2>/dev/null | head -1)
if [ -z "$APP_BUNDLE" ]; then
echo "Error: No .app bundle found in $MACOS_DIR"
exit 1
fi
APP_NAME=$(basename "$APP_BUNDLE" .app)
echo "App bundle: $APP_BUNDLE"
# --- Find the original DMG ---
ORIGINAL_DMG=$(find "$DMG_DIR" -name "*.dmg" -type f 2>/dev/null | head -1)
if [ -z "$ORIGINAL_DMG" ]; then
echo "Warning: No original DMG found in $DMG_DIR, skipping"
exit 0
fi
DMG_NAME=$(basename "$ORIGINAL_DMG")
echo "Original DMG: $ORIGINAL_DMG"
# --- Remove old DMG and create new one ---
echo ""
echo "Creating new DMG..."
rm -f "$ORIGINAL_DMG"
hdiutil create -volname "$APP_NAME" -srcfolder "$APP_BUNDLE" -ov -format UDZO "$DMG_DIR/$DMG_NAME"
echo ""
echo "=== DMG recreation complete ==="
ls -lh "$DMG_DIR/$DMG_NAME"
+113
View File
@@ -0,0 +1,113 @@
#!/bin/bash
# Re-sign macOS app bundle after TDLib bundling
# Required because modifying the bundle invalidates the original code signature.
#
# Usage:
# ./resign-macos.sh <build_type> [target]
#
# Arguments:
# build_type - "release" or "debug" (default: release)
# target - Optional cross-compilation target (e.g., aarch64-apple-darwin)
#
# Environment variables:
# APPLE_SIGNING_IDENTITY - Signing identity (e.g., "Developer ID Application: ...")
# If unset, uses ad-hoc signing ("-") for local testing.
# APPLE_CERTIFICATE - Base64-encoded .p12 certificate (CI only)
# APPLE_CERTIFICATE_PASSWORD - Password for the .p12 certificate (CI only)
#
# Examples:
# # Local testing (ad-hoc signing)
# ./resign-macos.sh release
#
# # CI with identity
# APPLE_SIGNING_IDENTITY="Developer ID Application: ..." ./resign-macos.sh release aarch64-apple-darwin
set -e
BUILD_TYPE="${1:-release}"
TARGET="${2:-}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TAURI_DIR="$(dirname "$SCRIPT_DIR")"
SIGNING_IDENTITY="${APPLE_SIGNING_IDENTITY:--}"
echo "=== macOS App Re-signing ==="
echo "Build type: ${BUILD_TYPE}"
echo "Target: ${TARGET:-default}"
echo "Signing identity: ${SIGNING_IDENTITY}"
# --- CI keychain setup (only when APPLE_CERTIFICATE is provided) ---
KEYCHAIN_PATH=""
if [ -n "$APPLE_CERTIFICATE" ] && [ -n "$APPLE_CERTIFICATE_PASSWORD" ]; then
echo ""
echo "Importing certificate into temporary keychain..."
TEMP_DIR="${RUNNER_TEMP:-/tmp}"
KEYCHAIN_PATH="$TEMP_DIR/tdlib-signing.keychain-db"
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
CERT_PATH="$TEMP_DIR/certificate.p12"
echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH"
security import "$CERT_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
rm "$CERT_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "Certificate imported"
fi
# --- Find the app bundle ---
APP_BUNDLE=""
for search_dir in \
"${TAURI_DIR}/target/${TARGET}/${BUILD_TYPE}/bundle/macos" \
"${TAURI_DIR}/target/${BUILD_TYPE}/bundle/macos" \
"${TAURI_DIR}/target/release/bundle/macos" \
"${TAURI_DIR}/target/debug/bundle/macos"; do
if [ -d "$search_dir" ]; then
found=$(find "$search_dir" -name "*.app" -type d 2>/dev/null | head -1)
if [ -n "$found" ]; then
APP_BUNDLE="$found"
break
fi
fi
done
if [ -z "$APP_BUNDLE" ]; then
echo "Warning: No .app bundle found, nothing to sign"
exit 0
fi
echo ""
echo "Signing app bundle: $APP_BUNDLE"
# --- Sign bundled dylibs first (inner-to-outer signing order) ---
FRAMEWORKS_DIR="$APP_BUNDLE/Contents/Frameworks"
if [ -d "$FRAMEWORKS_DIR" ]; then
for dylib in "$FRAMEWORKS_DIR"/*.dylib; do
if [ -f "$dylib" ]; then
echo " Signing: $(basename "$dylib")"
codesign --force --options runtime --sign "$SIGNING_IDENTITY" "$dylib"
fi
done
fi
# --- Sign the app bundle ---
echo " Signing: $(basename "$APP_BUNDLE")"
codesign --force --deep --options runtime --sign "$SIGNING_IDENTITY" "$APP_BUNDLE"
# --- Verify ---
echo ""
echo "Verifying signature..."
codesign --verify --verbose=2 "$APP_BUNDLE" 2>&1 || echo "Warning: Signature verification had issues"
# --- Cleanup CI keychain ---
if [ -n "$KEYCHAIN_PATH" ]; then
security delete-keychain "$KEYCHAIN_PATH" || true
fi
echo ""
echo "=== Re-signing complete ==="