Build and Sign DMG #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Sign DMG | ||
| on: | ||
| push: | ||
| tags: | ||
| - 'v*' | ||
| branches: | ||
| - 'copilot/fix-1' # Enable testing on current working branch | ||
| release: | ||
| types: [published] | ||
| workflow_dispatch: | ||
| inputs: | ||
| create_release: | ||
| description: 'Create a GitHub release' | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
| env: | ||
| APP_NAME: TrackWeight | ||
| SCHEME: TrackWeight | ||
| CONFIGURATION: Release | ||
| jobs: | ||
| build-and-sign: | ||
| runs-on: macos-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| submodules: recursive | ||
| - name: Setup Xcode | ||
| uses: maxim-lobanov/setup-xcode@v1 | ||
| with: | ||
| xcode-version: latest-stable | ||
| - name: Import Code-Signing Certificates | ||
| if: ${{ secrets.BUILD_CERTIFICATE_BASE64 != '' }} | ||
|
Check failure on line 40 in .github/workflows/build-and-sign-dmg.yml
|
||
| uses: Apple-Actions/import-codesign-certs@v2 | ||
| with: | ||
| p12-file-base64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} | ||
| p12-password: ${{ secrets.P12_PASSWORD }} | ||
| - name: Install provisioning profile | ||
| if: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 != '' }} | ||
| env: | ||
| BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }} | ||
| run: | | ||
| PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision | ||
| echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH | ||
| mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles | ||
| cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles | ||
| - name: Build and Archive App | ||
| run: | | ||
| xcodebuild \ | ||
| -project TrackWeight.xcodeproj \ | ||
| -scheme ${{ env.SCHEME }} \ | ||
| -configuration ${{ env.CONFIGURATION }} \ | ||
| -archivePath "$RUNNER_TEMP/${{ env.APP_NAME }}.xcarchive" \ | ||
| archive | ||
| - name: Export App | ||
| run: | | ||
| # Use development export method if no signing certificates are available | ||
| if [ -z "${{ secrets.BUILD_CERTIFICATE_BASE64 }}" ]; then | ||
| # Create export options for unsigned build | ||
| cat > "$RUNNER_TEMP/ExportOptions.plist" << EOF | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>method</key> | ||
| <string>debugging</string> | ||
| <key>signingStyle</key> | ||
| <string>manual</string> | ||
| <key>stripSwiftSymbols</key> | ||
| <true/> | ||
| <key>destination</key> | ||
| <string>export</string> | ||
| <key>signingCertificate</key> | ||
| <string>-</string> | ||
| <key>teamID</key> | ||
| <string>-</string> | ||
| <key>uploadBitcode</key> | ||
| <false/> | ||
| <key>uploadSymbols</key> | ||
| <false/> | ||
| </dict> | ||
| </plist> | ||
| EOF | ||
| else | ||
| # Use the existing ExportOptions.plist for signed builds | ||
| cp ExportOptions.plist "$RUNNER_TEMP/ExportOptions.plist" | ||
| fi | ||
| xcodebuild \ | ||
| -archivePath "$RUNNER_TEMP/${{ env.APP_NAME }}.xcarchive" \ | ||
| -exportPath "$RUNNER_TEMP/export" \ | ||
| -exportOptionsPlist "$RUNNER_TEMP/ExportOptions.plist" \ | ||
| -exportArchive | ||
| - name: Re-sign App Components | ||
| if: ${{ secrets.BUILD_CERTIFICATE_BASE64 != '' }} | ||
| env: | ||
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | ||
| run: | | ||
| echo "π Re-signing framework with Developer ID certificate..." | ||
| FRAMEWORK_PATH="$RUNNER_TEMP/export/${{ env.APP_NAME }}.app/Contents/Frameworks/OpenMultitouchSupportXCF.framework" | ||
| if [[ -d "$FRAMEWORK_PATH" ]]; then | ||
| codesign --force --sign "Developer ID Application" \ | ||
| --options runtime \ | ||
| --timestamp \ | ||
| "$FRAMEWORK_PATH/Versions/A/OpenMultitouchSupportXCF" | ||
| codesign --force --sign "Developer ID Application" \ | ||
| --options runtime \ | ||
| --timestamp \ | ||
| "$FRAMEWORK_PATH" | ||
| echo "β Framework re-signed successfully" | ||
| fi | ||
| # Re-sign the main app to ensure everything is consistent | ||
| echo "π Re-signing main application..." | ||
| codesign --force --sign "Developer ID Application" \ | ||
| --options runtime \ | ||
| --entitlements "TrackWeight/TrackWeight.entitlements" \ | ||
| --timestamp \ | ||
| --deep \ | ||
| --strict \ | ||
| "$RUNNER_TEMP/export/${{ env.APP_NAME }}.app" | ||
| echo "β Application re-signed successfully" | ||
| - name: Verify Code Signatures | ||
| if: ${{ secrets.BUILD_CERTIFICATE_BASE64 != '' }} | ||
| run: | | ||
| echo "π Verifying main application signature..." | ||
| codesign --verify --verbose "$RUNNER_TEMP/export/${{ env.APP_NAME }}.app" | ||
| echo "π Verifying framework signature..." | ||
| FRAMEWORK_PATH="$RUNNER_TEMP/export/${{ env.APP_NAME }}.app/Contents/Frameworks/OpenMultitouchSupportXCF.framework" | ||
| if [[ -d "$FRAMEWORK_PATH" ]]; then | ||
| codesign --verify --verbose "$FRAMEWORK_PATH" | ||
| fi | ||
| echo "π Deep verification with online validation..." | ||
| codesign --verify --deep --strict --verbose=2 "$RUNNER_TEMP/export/${{ env.APP_NAME }}.app" | ||
| echo "β All signature verifications passed" | ||
| - name: Notarize App | ||
| if: ${{ secrets.BUILD_CERTIFICATE_BASE64 != '' && secrets.APPLE_ID != '' }} | ||
| env: | ||
| APPLE_ID: ${{ secrets.APPLE_ID }} | ||
| APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} | ||
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | ||
| run: | | ||
| echo "π Starting notarization process..." | ||
| # Create a zip file for notarization (notarytool prefers zip over raw .app) | ||
| cd "$RUNNER_TEMP/export" | ||
| # Use ditto for creating zip compatible with Apple's notarization service | ||
| ditto -c -k --keepParent "${{ env.APP_NAME }}.app" "${{ env.APP_NAME }}.zip" | ||
| # Submit for notarization | ||
| echo "π€ Submitting app for notarization..." | ||
| xcrun notarytool submit "${{ env.APP_NAME }}.zip" \ | ||
| --apple-id "$APPLE_ID" \ | ||
| --password "$APPLE_ID_PASSWORD" \ | ||
| --team-id "$APPLE_TEAM_ID" \ | ||
| --wait \ | ||
| --timeout 20m | ||
| # Staple the notarization ticket to the app | ||
| echo "π Stapling notarization ticket..." | ||
| xcrun stapler staple "${{ env.APP_NAME }}.app" | ||
| # Verify the stapling worked | ||
| echo "β Verifying notarization..." | ||
| xcrun stapler validate "${{ env.APP_NAME }}.app" | ||
| echo "π Notarization complete!" | ||
| - name: Install create-dmg | ||
| run: | | ||
| brew install create-dmg | ||
| - name: Create DMG | ||
| run: | | ||
| # Create a clean directory with only the app for DMG creation | ||
| echo "π Preparing clean DMG contents..." | ||
| DMG_STAGING="$RUNNER_TEMP/dmg_staging" | ||
| rm -rf "$DMG_STAGING" | ||
| mkdir -p "$DMG_STAGING" | ||
| # Copy only the app to staging directory | ||
| cp -R "$RUNNER_TEMP/export/${{ env.APP_NAME }}.app" "$DMG_STAGING/" | ||
| # Create clean professional DMG | ||
| create-dmg \ | ||
| --volname "${{ env.APP_NAME }}" \ | ||
| --volicon "$DMG_STAGING/${{ env.APP_NAME }}.app/Contents/Resources/AppIcon.icns" \ | ||
| --window-pos 200 120 \ | ||
| --window-size 600 300 \ | ||
| --icon-size 100 \ | ||
| --icon "${{ env.APP_NAME }}.app" 175 120 \ | ||
| --hide-extension "${{ env.APP_NAME }}.app" \ | ||
| --app-drop-link 425 120 \ | ||
| --hdiutil-quiet \ | ||
| "$RUNNER_TEMP/${{ env.APP_NAME }}.dmg" \ | ||
| "$DMG_STAGING/" | ||
| - name: Get version info | ||
| id: version_info | ||
| run: | | ||
| if [[ "${{ github.ref }}" == refs/tags/* ]]; then | ||
| VERSION=${GITHUB_REF#refs/tags/} | ||
| else | ||
| VERSION=$(date +%Y%m%d-%H%M%S) | ||
| fi | ||
| echo "version=$VERSION" >> $GITHUB_OUTPUT | ||
| echo "dmg_name=${{ env.APP_NAME }}-$VERSION.dmg" >> $GITHUB_OUTPUT | ||
| - name: Rename DMG with version | ||
| run: | | ||
| mv "$RUNNER_TEMP/${{ env.APP_NAME }}.dmg" "$RUNNER_TEMP/${{ steps.version_info.outputs.dmg_name }}" | ||
| - name: Upload DMG as artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: ${{ steps.version_info.outputs.dmg_name }} | ||
| path: ${{ runner.temp }}/${{ steps.version_info.outputs.dmg_name }} | ||
| retention-days: 30 | ||
| - name: Create Release | ||
| if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true') | ||
| uses: softprops/action-gh-release@v1 | ||
| with: | ||
| tag_name: ${{ steps.version_info.outputs.version }} | ||
| name: ${{ env.APP_NAME }} ${{ steps.version_info.outputs.version }} | ||
| body: | | ||
| # TrackWeight ${{ steps.version_info.outputs.version }} | ||
| Transform your MacBook's trackpad into a precise digital weighing scale! | ||
| ## Credits | ||
| **Original repository:** https://github.com/KrishKrosh/TrackWeight | ||
| **Created by:** Krish Shah (@KrishKrosh) | ||
| This build is from the fork at https://github.com/Rohithzr/TrackWeight | ||
| ## Installation | ||
| 1. Download the DMG file below | ||
| 2. Open the DMG and drag TrackWeight.app to your Applications folder | ||
| 3. Run the app and follow the setup instructions | ||
| ## Requirements | ||
| - macOS 13.0 or later | ||
| - MacBook with Force Touch trackpad (2015 or newer MacBook Pro, 2016 or newer MacBook) | ||
| ## Usage | ||
| 1. Open the scale | ||
| 2. Rest your finger on the trackpad | ||
| 3. While maintaining finger contact, put your object on the trackpad | ||
| 4. Apply minimal pressure while maintaining contact to get the weight | ||
| For more information, visit the [original repository](https://github.com/KrishKrosh/TrackWeight). | ||
| files: | | ||
| ${{ runner.temp }}/${{ steps.version_info.outputs.dmg_name }} | ||
| draft: false | ||
| prerelease: false | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Summary | ||
| run: | | ||
| echo "## Build Summary" >> $GITHUB_STEP_SUMMARY | ||
| echo "β Successfully built and packaged TrackWeight DMG" >> $GITHUB_STEP_SUMMARY | ||
| echo "π¦ DMG file: ${{ steps.version_info.outputs.dmg_name }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "π Original repository: https://github.com/KrishKrosh/TrackWeight" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "The DMG includes:" >> $GITHUB_STEP_SUMMARY | ||
| echo "- TrackWeight.app (signed and notarized if certificates provided)" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Clean professional DMG with just the app and Applications link" >> $GITHUB_STEP_SUMMARY | ||
| echo "- Proper code signing with hardened runtime enabled" >> $GITHUB_STEP_SUMMARY | ||