diff --git a/.github/releasers/macos/Info.plist b/.github/releasers/macos/Info.plist index 30fb8745a..812fd4ab6 100644 --- a/.github/releasers/macos/Info.plist +++ b/.github/releasers/macos/Info.plist @@ -5,7 +5,7 @@ CFBundlePackageType APPL CFBundleIdentifier - com.github.pactus-project.pactus.pactus-gui + org.pactus.pacgui CFBundleExecutable pactus-gui CFBundleName diff --git a/.github/releasers/releaser_gui_macos.sh b/.github/releasers/releaser_gui_macos.sh index 2b953f048..29dbe289b 100644 --- a/.github/releasers/releaser_gui_macos.sh +++ b/.github/releasers/releaser_gui_macos.sh @@ -77,17 +77,113 @@ ${BUNDLER} ${GUI_BUNDLE}/gui.bundle # Removing Cellar as workaround rm -rf ${ROOT_DIR}/pactus-gui.app/Contents/Resources/Cellar + +# After gtk-mac-bundler and your fix-install-names script... + +if [ ! -z "${MACOS_CERT_IDENTITY}" ]; then + echo "=== Signing all Mach-O files inside the app bundle (dylibs, .so, executables, etc.)..." + + # Create a temporary file to list all Mach-O binaries + find ${ROOT_DIR}/pactus-gui.app/Contents -type f -exec file {} \; | grep "Mach-O" | cut -d: -f1 > /tmp/macho_files.txt + + # First, sign only the .dylib and .so files (if any) + grep -E '\.(dylib|so)$' /tmp/macho_files.txt | while read binary; do + echo "Signing library: $binary" + codesign --force --timestamp --verbose --sign "${MACOS_CERT_IDENTITY}" "$binary" + if [ $? -ne 0 ]; then exit 1; fi + done + + # Then sign all other Mach-O binaries (executables, helpers, etc.) + grep -v -E '\.(dylib|so)$' /tmp/macho_files.txt | while read binary; do + echo "Signing binary: $binary" + codesign --force --timestamp --verbose --sign "${MACOS_CERT_IDENTITY}" "$binary" + if [ $? -ne 0 ]; then exit 1; fi + done + + # Sign standalone binaries outside the app (if any) + for bin in pactus-daemon pactus-wallet pactus-shell pactus-gui; do + if [ -f "${BUILD_DIR}/${bin}" ]; then + echo "Signing standalone binary: ${BUILD_DIR}/${bin}" + codesign --force --timestamp --verbose --sign "${MACOS_CERT_IDENTITY}" "${BUILD_DIR}/${bin}" + fi + done + + echo "=== Signing the whole app bundle (top-level)..." + codesign --force --timestamp --verbose --sign "${MACOS_CERT_IDENTITY}" ${ROOT_DIR}/pactus-gui.app + + echo "=== Verification: checking the final app bundle..." + codesign --verify --verbose --deep --strict ${ROOT_DIR}/pactus-gui.app + if [ $? -ne 0 ]; then + echo "ERROR: App bundle verification failed!" + exit 1 + fi +fi + +# if [ ! -z "${MACOS_CERT_IDENTITY}" ]; then +# echo "=== Signing artifacts..." +# codesign --force --timestamp --sign "${MACOS_CERT_IDENTITY}" ${BUILD_DIR}/pactus-daemon +# codesign --force --timestamp --sign "${MACOS_CERT_IDENTITY}" ${BUILD_DIR}/pactus-wallet +# codesign --force --timestamp --sign "${MACOS_CERT_IDENTITY}" ${BUILD_DIR}/pactus-shell +# codesign --force --timestamp --sign "${MACOS_CERT_IDENTITY}" ${BUILD_DIR}/pactus-gui + +# echo "=== Signing app bundle..." +# codesign --force --timestamp --sign "${MACOS_CERT_IDENTITY}" ${ROOT_DIR}/pactus-gui.app +# fi + echo "Creating dmg" # https://github.com/create-dmg/create-dmg - create-dmg --version - create-dmg --skip-jenkins \ --volname "Pactus GUI" \ "${FILE_NAME}.dmg" \ "${ROOT_DIR}/pactus-gui.app" -echo "Creating archive" + + +if [ ! -z "${APPLE_ID}" ]; then + echo "=== Submitting for notarization..." + + # Capture submission ID and check final status + SUBMISSION_ID=$(xcrun notarytool submit "${FILE_NAME}.dmg" \ + --apple-id "${APPLE_ID}" \ + --password "${APPLE_PASSWORD}" \ + --team-id "${APPLE_TEAM_ID}" \ + --wait --output-format json | jq -r '.id') + + STATUS=$(xcrun notarytool info "$SUBMISSION_ID" \ + --apple-id "${APPLE_ID}" \ + --password "${APPLE_PASSWORD}" \ + --team-id "${APPLE_TEAM_ID}" \ + --output-format json | jq -r '.status') + + if [ "$STATUS" != "Accepted" ]; then + echo "Notarization failed with status: $STATUS" + xcrun notarytool log "$SUBMISSION_ID" \ + --apple-id "${APPLE_ID}" \ + --password "${APPLE_PASSWORD}" \ + --team-id "${APPLE_TEAM_ID}" \ + notarization.log + cat notarization.log + exit 1 + fi + + + + # xcrun notarytool submit "${FILE_NAME}.dmg" \ + # --apple-id "${APPLE_ID}" \ + # --password "${APPLE_PASSWORD}" \ + # --team-id "${APPLE_TEAM_ID}" \ + # --wait + + # echo "Stapling DMG only (the app inside gets the ticket automatically)..." + # # ✅ FIX: Only staple the DMG – the .app was not notarized separately, so stapling it would cause error 65. + # xcrun stapler staple "${FILE_NAME}.dmg" + + # # ❌ REMOVED: Stapling the standalone .app + # # xcrun stapler staple "${ROOT_DIR}/pactus-gui.app" +fi + +echo "Creating tar.gz archive" cp ${BUILD_DIR}/pactus-daemon ${PACKAGE_DIR} cp ${BUILD_DIR}/pactus-wallet ${PACKAGE_DIR} cp ${BUILD_DIR}/pactus-shell ${PACKAGE_DIR} diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml index de1a87fd9..1d85ea6c2 100644 --- a/.github/workflows/releaser.yml +++ b/.github/workflows/releaser.yml @@ -121,8 +121,22 @@ jobs: with: go-version: "1.26.2" + - name: Import macOS Certificates + uses: apple-actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} + p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} + + - name: List Identities + run: security find-identity -v -p codesigning + - name: Create release files run: bash ./.github/releasers/releaser_gui_macos.sh + env: + MACOS_CERT_IDENTITY: ${{ secrets.MACOS_CERT_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - name: Calculate sha256sum run: sha256sum pactus-*.dmg pactus-*.tar.gz > checksum-${{ matrix.name }}.txt diff --git a/.github/workflows/test-macos-signing.yml b/.github/workflows/test-macos-signing.yml new file mode 100644 index 000000000..6f6789c56 --- /dev/null +++ b/.github/workflows/test-macos-signing.yml @@ -0,0 +1,60 @@ +name: Test macOS Signing + +on: + pull_request: + workflow_dispatch: + +jobs: + test-gui-macos: + runs-on: ${{ matrix.runner }} + strategy: + matrix: + name: [macos-amd64, macos-arm64] + include: + - name: macos-amd64 + runner: macos-15-intel + lib_home: /usr/local + - name: macos-arm64 + runner: macos-15 + lib_home: /opt/homebrew + + env: + LIB_HOME: ${{ matrix.lib_home }} + + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 # Required for git describe + + - name: Install Dependencies + run: brew install gtk+3 librsvg create-dmg coreutils gdk-pixbuf glib-networking pkg-config + + - name: Install Go + uses: actions/setup-go@v6 + with: + go-version: "1.26.2" + + - name: Import macOS Certificates + uses: apple-actions/import-codesign-certs@v6 + with: + p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} + p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} + + - name: List Identities + run: security find-identity -v -p codesigning + + - name: Create release files + run: bash ./.github/releasers/releaser_gui_macos.sh + env: + MACOS_CERT_IDENTITY: ${{ secrets.MACOS_CERT_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + + - name: Upload Artifacts + uses: actions/upload-artifact@v6 + with: + name: pactus-gui-test-${{ matrix.name }} + path: | + pactus-*.dmg + pactus-*.tar.gz