Last active
May 10, 2025 07:35
-
-
Save ggand0/0f6c266a999cf9b03f9ca560352c2bb0 to your computer and use it in GitHub Desktop.
Automates bundling, signing, packaging, and uploading a macOS .app (built with Rust) to App Store Connect using Transporter.
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
| #!/bin/bash | |
| set -euo pipefail | |
| # Constants — change as needed | |
| APP_NAME="<YOUR APP NAME>" | |
| BINARY_NAME="<YOUR BINARY NAME>" | |
| BUNDLE_ID="<com.yourorgname.appname>" | |
| VERSION_SHORT="0.1.0" | |
| TEAM_ID="<TEAM ID>" | |
| DEV_NAME="3rd Party Mac Developer Application: <YOUR NAME> ($TEAM_ID)" | |
| INSTALLER_NAME="3rd Party Mac Developer Installer: <YOUR NAME> ($TEAM_ID)" | |
| PROV_PROFILE="viewskater_provision_profile.provisionprofile" | |
| ENTITLEMENTS="entitlements.plist" | |
| EMAIL="<YOUR EMAIL>" | |
| APP_PASSWORD="<APP SPECIFIC PASSWORD>" | |
| APPLE_ID="<YOUR_APPLE_ID>" | |
| # Directories | |
| BUILD_DIR="target/release/bundle/osx" | |
| APP_PATH="$BUILD_DIR/$APP_NAME.app" | |
| PKG_PATH="$BUILD_DIR/$APP_NAME.pkg" | |
| ITMSP_DIR="$BUILD_DIR/$APP_NAME.itmsp" | |
| INFO_PLIST_LOCAL="Info.plist" | |
| METADATA_XML="$ITMSP_DIR/metadata.xml" | |
| # Step 1: Bundle app | |
| cargo bundle --release | |
| # Step 2: Generate build number (timestamp) | |
| BUILD_NUMBER=$(date +"%Y%m%d.%H%M%S") | |
| # Step 3: Update Info.plist with build number | |
| cp "$INFO_PLIST_LOCAL" "$APP_PATH/Contents/Info.plist" | |
| plutil -replace CFBundleVersion -string "$BUILD_NUMBER" "$APP_PATH/Contents/Info.plist" | |
| plutil -replace CFBundleShortVersionString -string "$VERSION_SHORT" "$APP_PATH/Contents/Info.plist" | |
| # Step 4: Embed provisioning profile | |
| cp "$PROV_PROFILE" "$APP_PATH/Contents/embedded.provisionprofile" | |
| # Step 5: Remove quarantine attribute | |
| xattr -cr "$APP_PATH" | |
| # Step 6: Code sign | |
| codesign --deep --force --options runtime \ | |
| --entitlements "$ENTITLEMENTS" \ | |
| --sign "$DEV_NAME" \ | |
| "$APP_PATH" | |
| # Step 7: Create .pkg | |
| productbuild --component "$APP_PATH" /Applications \ | |
| --sign "$INSTALLER_NAME" \ | |
| "$PKG_PATH" | |
| # Step 8: Prepare .itmsp dir | |
| mkdir -p "$ITMSP_DIR" | |
| cp "$PKG_PATH" "$ITMSP_DIR" | |
| # Step 9: Calculate size and md5 | |
| SIZE=$(stat -f%z "$PKG_PATH") | |
| MD5=$(md5 -q "$PKG_PATH") | |
| # Step 10: Update metadata.xml | |
| cat > "$METADATA_XML" <<EOF | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <package xmlns="http://apple.com/itunes/importer" version="software5.10"> | |
| <software_assets apple_id="$APPLE_ID" app_platform="osx"> | |
| <asset type="product-archive"> | |
| <data_file> | |
| <file_name>$APP_NAME.pkg</file_name> | |
| <size>$SIZE</size> | |
| <checksum type="md5">$MD5</checksum> | |
| </data_file> | |
| </asset> | |
| </software_assets> | |
| </package> | |
| EOF | |
| # Step 11: Upload to TestFlight | |
| /Applications/Transporter.app/Contents/itms/bin/iTMSTransporter \ | |
| -m upload \ | |
| -f "$ITMSP_DIR" \ | |
| -u "$EMAIL" \ | |
| -p "$APP_PASSWORD" | |
| echo "✅ Upload complete! Build number: $BUILD_NUMBER" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For full context and step-by-step explanation, see the blog post: https://ggando.com/blog/rust-appstore/