From fba1af513cc4cfcdffd389d38e254d7ffbd3c67f Mon Sep 17 00:00:00 2001 From: Ozgur Ersoy Date: Wed, 16 Apr 2025 00:46:48 +0200 Subject: [PATCH] fix(actions): update macOS notarization workflow to improve DMG packaging and enhance installation instructions --- .gitea/actions/macos-notarize/action.yml | 89 ++++++++++++++++-------- .gitea/workflows/test-macos-build.yml | 52 +------------- 2 files changed, 64 insertions(+), 77 deletions(-) diff --git a/.gitea/actions/macos-notarize/action.yml b/.gitea/actions/macos-notarize/action.yml index 33cf0dce..98a58f9a 100644 --- a/.gitea/actions/macos-notarize/action.yml +++ b/.gitea/actions/macos-notarize/action.yml @@ -669,10 +669,10 @@ runs: echo "Creating distribution package with signed app..." fi - # Create zip package + # Create zip package (necessary for notarization process only) ZIP_FILE="${APP_NAME}-${PACKAGE_SUFFIX}.zip" ditto -c -k --keepParent "${{ inputs.app-path }}" "$ZIP_FILE" - echo "โœ… Created ZIP package: $ZIP_FILE" + echo "โœ… Created temporary ZIP package for notarization: $ZIP_FILE" # Verify stapling on the app before packaging echo "๐Ÿ” Verifying app notarization and stapling..." @@ -689,29 +689,57 @@ runs: DMG_TMP_DIR=$(mktemp -d) cp -R "${{ inputs.app-path }}" "$DMG_TMP_DIR/" - # Optional: Add README or instructions - echo "# Installation Instructions\n\nDrag the application to your Applications folder to install." > "$DMG_TMP_DIR/README.txt" - - # Create a helper script to remove quarantine attribute - echo "Creating helper script to remove quarantine attribute..." - mkdir -p "$DMG_TMP_DIR/scripts" - cat > "$DMG_TMP_DIR/scripts/remove_quarantine.sh" << 'EOF' -#!/bin/bash -APP_PATH="/Applications/$(basename "$0" | sed 's/remove_quarantine_//')" -if [ -d "$APP_PATH" ]; then - echo "Removing quarantine attribute from $APP_PATH" - xattr -dr com.apple.quarantine "$APP_PATH" - echo "โœ… Quarantine attribute removed" - osascript -e "display notification \"Quarantine attribute removed from $APP_PATH\" with title \"Installation Complete\"" -else - echo "โŒ Application not found at $APP_PATH" - osascript -e "display notification \"Application not found at $APP_PATH\" with title \"Installation Failed\"" -fi + # Add README with fancy formatting + cat > "$DMG_TMP_DIR/README.txt" << 'EOF' +# LuckyWorld Installation Instructions + +1. Drag the LuckyWorld application to your Applications folder +2. Double-click the "Install Helper" icon (optional - removes security warnings) +3. Enjoy! + +For technical support, contact: support@luckyrobots.com EOF - # Make the script executable and name it based on the app - chmod +x "$DMG_TMP_DIR/scripts/remove_quarantine.sh" - cp "$DMG_TMP_DIR/scripts/remove_quarantine.sh" "$DMG_TMP_DIR/scripts/remove_quarantine_$(basename "${{ inputs.app-path }}")" + # Create a better helper script to remove quarantine attribute + echo "Creating helper script to remove quarantine attribute..." + mkdir -p "$DMG_TMP_DIR/scripts" + cat > "$DMG_TMP_DIR/scripts/InstallHelper.command" << 'EOF' +#!/bin/bash + +# Get the application name from the DMG +APP_NAME="LuckyWorld-Mac-Shipping.app" +APP_PATH="/Applications/$APP_NAME" + +echo "============================================" +echo "๐Ÿ” LuckyWorld Security Helper" +echo "============================================" + +if [ -d "$APP_PATH" ]; then + echo "โœ… Found $APP_NAME in Applications folder" + echo "๐Ÿงน Removing security attributes..." + xattr -dr com.apple.quarantine "$APP_PATH" + echo "โœ… Security attributes removed successfully!" + echo "๐Ÿš€ You can now launch the application normally" + osascript -e "display notification \"$APP_NAME is ready to use\" with title \"LuckyWorld Installation Complete\" subtitle \"Security attributes removed\"" +else + echo "โŒ $APP_NAME not found in Applications folder" + echo "โš ๏ธ Please drag the application to your Applications folder first" + osascript -e "display notification \"Please drag LuckyWorld to Applications folder first\" with title \"Installation Incomplete\" subtitle \"Application not found\"" + exit 1 +fi + +echo "============================================" +echo "Press any key to exit..." +read -n 1 +EOF + + # Make the script executable + chmod +x "$DMG_TMP_DIR/scripts/InstallHelper.command" + + # Create visually appealing backgrounds and icons + if [ -d "$DMG_TMP_DIR/scripts" ]; then + touch "$DMG_TMP_DIR/scripts/.keep" + fi # Try to use create-dmg if available, otherwise fall back to hdiutil if command -v create-dmg &> /dev/null; then @@ -727,18 +755,23 @@ EOF fi create-dmg \ - --volname "${APP_NAME}" \ + --volname "LuckyWorld Installer" \ --codesign-identity "$IDENTITY_HASH" \ - --app-drop-link 450 200 \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --text-size 12 \ + --app-drop-link 600 170 \ --hide-extension "$(basename "${{ inputs.app-path }}")" \ - --add-file "README.txt" 200 200 \ - --add-file "scripts" 200 300 \ + --add-file "README.txt" 200 170 \ + --add-file "scripts/InstallHelper.command" 400 170 \ + --hide-extension "InstallHelper.command" \ --no-internet-enable \ "$DMG_FILE" \ "$DMG_TMP_DIR" else # Fall back to hdiutil - hdiutil create -volname "${APP_NAME}" -srcfolder "$DMG_TMP_DIR" -ov -format UDZO "$DMG_FILE" + hdiutil create -volname "LuckyWorld Installer" -srcfolder "$DMG_TMP_DIR" -ov -format UDZO "$DMG_FILE" fi if [ -f "$DMG_FILE" ]; then diff --git a/.gitea/workflows/test-macos-build.yml b/.gitea/workflows/test-macos-build.yml index 3146c53b..65af91e1 100644 --- a/.gitea/workflows/test-macos-build.yml +++ b/.gitea/workflows/test-macos-build.yml @@ -162,61 +162,15 @@ jobs: bundle-id: ${{ env.BUNDLE_ID }} fallback-to-adhoc: 'false' - # Upload stapled app directly (this is the most reliable approach) - - name: Upload Stapled App Bundle + # Upload only the DMG file as main distribution artifact + - name: Upload Mac Distribution DMG uses: actions/upload-artifact@v3 if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' with: - name: LuckyWorld-macOS-Stapled-App-Bundle - path: ${{ env.APP_PATH }} - retention-days: 30 - - # Create a properly archived ZIP of the stapled app (preserves stapling) - - name: Create Stapled App Archive (ZIP) - if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' && steps.sign-and-notarize.outputs.zip-package-path != '' - run: | - # The ZIP is now created by the macos-notarize action - echo "Using ZIP created by the macos-notarize action" - echo "ZIP file location: ${{ steps.sign-and-notarize.outputs.zip-package-path }}" - echo "STAPLED_APP_ZIP=${{ steps.sign-and-notarize.outputs.zip-package-path }}" >> "$GITHUB_ENV" - shell: bash - - # Upload the ZIP archive from the macos-notarize action - - name: Upload Stapled App ZIP Archive - uses: actions/upload-artifact@v3 - if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' && steps.sign-and-notarize.outputs.zip-package-path != '' - with: - name: LuckyWorld-macOS-Stapled-ZIP - path: ${{ steps.sign-and-notarize.outputs.zip-package-path }} - retention-days: 30 - - # Upload the DMG file from the macos-notarize action - - name: Upload Stapled App DMG - uses: actions/upload-artifact@v3 - if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' - with: - name: LuckyWorld-macOS-Stapled-DMG + name: LuckyWorld-Mac-Distribution path: ${{ steps.sign-and-notarize.outputs.package-path }} retention-days: 30 - # Upload signed app (might be DMG or other package format) - - name: Upload Signed App Package - uses: actions/upload-artifact@v3 - if: steps.sign-and-notarize.outputs.signed != 'none' - with: - name: ${{ steps.sign-and-notarize.outputs.notarized == 'true' && 'LuckyWorld-macOS-Signed-Notarized-Package' || 'LuckyWorld-macOS-Signed-Package' }} - path: ${{ steps.sign-and-notarize.outputs.package-path }} - retention-days: 30 - - # Upload ZIP package if DMG was created (as a backup) - - name: Upload ZIP Package - uses: actions/upload-artifact@v3 - if: steps.sign-and-notarize.outputs.signed != 'none' && steps.sign-and-notarize.outputs.zip-package-path != '' - with: - name: ${{ steps.sign-and-notarize.outputs.notarized == 'true' && 'LuckyWorld-macOS-Signed-Notarized-ZIP' || 'LuckyWorld-macOS-Signed-ZIP' }} - path: ${{ steps.sign-and-notarize.outputs.zip-package-path }} - retention-days: 30 - # Report results - name: Report Results run: |