From 47d39ebcc3a45b9c2f29957c63550516c1e8dd1d Mon Sep 17 00:00:00 2001 From: Max Heidinger Date: Tue, 21 Oct 2025 15:54:21 +0200 Subject: [PATCH] chore: use dedicated build shell script --- PReek.xcodeproj/project.pbxproj | 10 +- .../xcshareddata/xcschemes/PReek.xcscheme | 20 +-- build-dmg.sh | 148 ++++++++++++++++++ 3 files changed, 156 insertions(+), 22 deletions(-) create mode 100755 build-dmg.sh diff --git a/PReek.xcodeproj/project.pbxproj b/PReek.xcodeproj/project.pbxproj index fc64275..8238e2b 100644 --- a/PReek.xcodeproj/project.pbxproj +++ b/PReek.xcodeproj/project.pbxproj @@ -43,8 +43,6 @@ 6C1CB6FD2C92344200305288 /* RevealSecureField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1CB6FC2C92342F00305288 /* RevealSecureField.swift */; }; 6C1F49B82CB5BB9B00C30677 /* SafeArrayIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1F49B72CB5BB9300C30677 /* SafeArrayIndex.swift */; }; 6C1F49B92CB5BB9B00C30677 /* SafeArrayIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1F49B72CB5BB9300C30677 /* SafeArrayIndex.swift */; }; - E300212E25D94E51B33AB453 /* PullRequestUnreadCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */; }; - AB76BF5A49F34BF6B75F6415 /* PullRequestUnreadCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */; }; 6C232DE72C08C51D00C003B1 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 6C232DE62C08C51D00C003B1 /* KeychainAccess */; }; 6C232DEB2C08C95E00C003B1 /* ConfigViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C232DEA2C08C95E00C003B1 /* ConfigViewModel.swift */; }; 6C232DED2C08CB9600C003B1 /* KeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C232DEC2C08CB9600C003B1 /* KeychainStorage.swift */; }; @@ -121,8 +119,11 @@ 6CE564162C011BAE008E9A4B /* toPullRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CE564152C011BAE008E9A4B /* toPullRequests.swift */; }; 6CE5641A2C013529008E9A4B /* PullRequestsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CE564192C013529008E9A4B /* PullRequestsViewModel.swift */; }; 6CF15A542C03909900A7CE3E /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF15A532C03909900A7CE3E /* SettingsScreen.swift */; }; + 6CFBFDBD2EA7A58400DAD857 /* build-dmg.sh in Resources */ = {isa = PBXBuildFile; fileRef = 6CFBFDBC2EA7A57800DAD857 /* build-dmg.sh */; }; 6CFE0C732D86FD5C00985A1C /* CodeScanner in Frameworks */ = {isa = PBXBuildFile; platformFilter = ios; productRef = 6CFE0C722D86FD5C00985A1C /* CodeScanner */; }; 6CFE0C752D87217E00985A1C /* ImportSheetModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFE0C742D87217800985A1C /* ImportSheetModifier.swift */; }; + AB76BF5A49F34BF6B75F6415 /* PullRequestUnreadCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */; }; + E300212E25D94E51B33AB453 /* PullRequestUnreadCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -145,7 +146,6 @@ 6C1CB6F62C921CCF00305288 /* IfView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IfView.swift; sourceTree = ""; }; 6C1CB6FC2C92342F00305288 /* RevealSecureField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevealSecureField.swift; sourceTree = ""; }; 6C1F49B72CB5BB9300C30677 /* SafeArrayIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeArrayIndex.swift; sourceTree = ""; }; - E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullRequestUnreadCalculator.swift; sourceTree = ""; }; 6C232DEA2C08C95E00C003B1 /* ConfigViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigViewModel.swift; sourceTree = ""; }; 6C232DEC2C08CB9600C003B1 /* KeychainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorage.swift; sourceTree = ""; }; 6C232DEE2C08F6C600C003B1 /* ConfigService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigService.swift; sourceTree = ""; }; @@ -214,7 +214,9 @@ 6CE564152C011BAE008E9A4B /* toPullRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = toPullRequests.swift; sourceTree = ""; }; 6CE564192C013529008E9A4B /* PullRequestsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullRequestsViewModel.swift; sourceTree = ""; }; 6CF15A532C03909900A7CE3E /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = ""; }; + 6CFBFDBC2EA7A57800DAD857 /* build-dmg.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-dmg.sh"; sourceTree = ""; }; 6CFE0C742D87217800985A1C /* ImportSheetModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportSheetModifier.swift; sourceTree = ""; }; + E300212F25D94E51B33AB454 /* PullRequestUnreadCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullRequestUnreadCalculator.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ @@ -338,6 +340,7 @@ 6C043E4F2C68DE6D00DEBF35 /* README.md */, 6C19E97B2C68AE130035845C /* Localizable.xcstrings */, 6CB720452C725FA70067CA1D /* ExportOptions.plist */, + 6CFBFDBC2EA7A57800DAD857 /* build-dmg.sh */, 6CB027232BFF817E00C4C3B1 /* Products */, ); sourceTree = ""; @@ -565,6 +568,7 @@ 6CDC9FAD2C75C8C5005FAFFD /* .gitignore in Resources */, 6C043E522C68DE9C00DEBF35 /* .github in Resources */, 6CDC9FAE2C75C8C5005FAFFD /* .swift-version in Resources */, + 6CFBFDBD2EA7A58400DAD857 /* build-dmg.sh in Resources */, 6CDC9FB12C75C8FB005FAFFD /* .swiftformat in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/PReek.xcodeproj/xcshareddata/xcschemes/PReek.xcscheme b/PReek.xcodeproj/xcshareddata/xcschemes/PReek.xcscheme index 0e058f3..fdf1389 100644 --- a/PReek.xcodeproj/xcshareddata/xcschemes/PReek.xcscheme +++ b/PReek.xcodeproj/xcshareddata/xcschemes/PReek.xcscheme @@ -86,24 +86,6 @@ - - - - - - - - - - + revealArchiveInOrganizer = "NO"> diff --git a/build-dmg.sh b/build-dmg.sh new file mode 100755 index 0000000..a486561 --- /dev/null +++ b/build-dmg.sh @@ -0,0 +1,148 @@ +#!/bin/bash + +# Exit on error +set -e + +# Configuration +SCHEME_NAME="PReek" +PROJECT_PATH="PReek.xcodeproj" +EXPORT_OPTIONS_PLIST="./ExportOptions.plist" +AC_PASSWORD="personal" # Keychain item name for notarytool credentials created via `notarytool store-credentials` + +PRODUCT_NAME="PReek" +MARKETING_VERSION=$(xcodebuild -showBuildSettings -scheme "$SCHEME_NAME" -project "$PROJECT_PATH" -destination "platform=macOS,arch=arm64" 2>&1 | grep MARKETING_VERSION | awk '{print $3}') + +# Create unique build directory +EXPORT_UUID=$(uuidgen) +BUILD_PATH="/tmp/$PRODUCT_NAME-build-$EXPORT_UUID" +ARCHIVE_PATH="$BUILD_PATH/$PRODUCT_NAME.xcarchive" +DMG_PATH="$BUILD_PATH/$PRODUCT_NAME-$MARKETING_VERSION.dmg" +LOGS_PATH="$BUILD_PATH/logs" + +mkdir -p "$BUILD_PATH" +mkdir -p "$LOGS_PATH" + +# Open the export folder +open "$BUILD_PATH" + +echo "=== Starting Build Process ===" +echo "Detected version: $MARKETING_VERSION" +echo "Build directory: $BUILD_PATH" +echo "Archive path: $ARCHIVE_PATH" +echo "Logs directory: $LOGS_PATH" +echo "" + +# Step 1: Create Archive +echo "=== Creating Archive ===" +xcodebuild archive \ + -scheme "$SCHEME_NAME" \ + -project "$PROJECT_PATH" \ + -destination "platform=macOS,arch=arm64" \ + -archivePath "$ARCHIVE_PATH" \ + -configuration Release \ + CODE_SIGN_STYLE=Automatic \ + -allowProvisioningUpdates \ + > "$LOGS_PATH/01-archive.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "Archive creation failed. Check log: $LOGS_PATH/01-archive.log" + exit 1 +fi + +echo "Archive created successfully" +echo "" + +# Step 2: Export Archive +echo "=== Exporting Archive ===" +xcodebuild -exportArchive \ + -archivePath "$ARCHIVE_PATH" \ + -exportOptionsPlist "$EXPORT_OPTIONS_PLIST" \ + -exportPath "$BUILD_PATH" \ + -allowProvisioningUpdates \ + > "$LOGS_PATH/02-export.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "Export of application archive failed. Check log: $LOGS_PATH/02-export.log" + exit 1 +fi + +echo "Export completed successfully" +echo "" + +# Step 3: Setup Node environment +echo "=== Setting up Node Environment ===" +fnm use v22 > "$LOGS_PATH/03-fnm.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "Failed to set Node version with fnm. Check log: $LOGS_PATH/03-fnm.log" + exit 1 +fi + +echo "Node environment ready" +echo "" + +# Step 4: Create DMG +echo "=== Creating DMG ===" + +pushd "$BUILD_PATH" > /dev/null + +npm install --global create-dmg > "$LOGS_PATH/04-npm-install.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "npm install failed. Check log: $LOGS_PATH/04-npm-install.log" + exit 1 +fi + +create-dmg --no-version-in-filename "$PRODUCT_NAME.app" > "$LOGS_PATH/05-create-dmg.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "Creating DMG failed. Check log: $LOGS_PATH/05-create-dmg.log" + exit 1 +fi + +# Rename DMG to expected name incl. version +mv "$PRODUCT_NAME.dmg" "$DMG_PATH" + +popd > /dev/null + +echo "DMG created successfully: $DMG_PATH" +echo "" + +# Step 5: Submit for Notarization +echo "=== Submitting for Notarization ===" +xcrun notarytool submit \ + -p "$AC_PASSWORD" \ + --verbose \ + "$DMG_PATH" \ + --wait \ + --timeout 2h \ + --output-format plist > "$BUILD_PATH/NotarizationResponse.plist" 2> "$LOGS_PATH/06-notarization.log" + +if [ $? -eq 0 ]; then + message=$(/usr/libexec/PlistBuddy -c "Print :message" "$BUILD_PATH/NotarizationResponse.plist") + status=$(/usr/libexec/PlistBuddy -c "Print :status" "$BUILD_PATH/NotarizationResponse.plist") + echo "Notarization response: $message - $status" +else + echo "Failed to submit DMG for notarization. Check log: $LOGS_PATH/06-notarization.log" + exit 1 +fi + +echo "$message: $status" +echo "" + +# Step 6: Staple Notarization Ticket +echo "=== Stapling Notarization Ticket ===" +xcrun stapler staple "$DMG_PATH" > "$LOGS_PATH/07-stapler.log" 2>&1 + +if [ $? -ne 0 ]; then + echo "Failed stapling ticket to DMG. Check log: $LOGS_PATH/07-stapler.log" + exit 1 +fi + +echo "Stapling completed successfully" +echo "" + +# Success! +echo "=== Build Process Complete ===" +echo "Final DMG location: $DMG_PATH" +echo "Logs location: $LOGS_PATH"