#!/usr/bin/env bash # # release.sh — archive IceGlass (macOS menu bar app) and upload to # App Store Connect. # # Usage: Scripts/release.sh # # No third-party tooling: pure xcodebuild + the App Store Connect API key. # Credentials live in .env.release (gitignored); see .env.release.example. # # What it does: # 1. Regenerates the Xcode project with XcodeGen. # 2. Stamps CFBundleVersion with the git commit count (monotonic build no.) # via Scripts/update_build_number.sh during the build. # 3. xcodebuild archive -> .xcarchive (generic/platform=macOS) # 4. xcodebuild -exportArchive with destination=upload -> App Store Connect. # # NOTE: this project also ships an iOS companion (IceGlass-iOS, its own # bundle ID and — eventually — its own App Store Connect app record). This # script only releases the macOS app. When the iOS companion is ready to # publish, copy this file to release-ios.sh, swap PROJECT/SCHEME/BUNDLE_ID # for the iOS target, destination to "generic/platform=iOS", and point # -exportOptionsPlist at an ExportOptions-iOS.plist (see the appstore-publish # skill's template) — plus a sibling Scripts/metadata/ set for its own listing. # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$ROOT" PROJECT="IceGlass.xcodeproj" SCHEME="IceGlass" BUILD_DIR="$ROOT/build" # ---- credentials ------------------------------------------------------------ ENV_FILE="$ROOT/.env.release" if [ -f "$ENV_FILE" ]; then set -a; . "$ENV_FILE"; set +a fi : "${APPLE_TEAM_ID:?Set APPLE_TEAM_ID (copy .env.release.example -> .env.release)}" : "${ASC_KEY_ID:?Set ASC_KEY_ID in .env.release}" : "${ASC_ISSUER_ID:?Set ASC_ISSUER_ID in .env.release}" : "${ASC_KEY_PATH:?Set ASC_KEY_PATH in .env.release}" [ -f "$ASC_KEY_PATH" ] || { echo "❌ API key not found at: $ASC_KEY_PATH"; exit 1; } AUTH=( -authenticationKeyPath "$ASC_KEY_PATH" -authenticationKeyID "$ASC_KEY_ID" -authenticationKeyIssuerID "$ASC_ISSUER_ID" -allowProvisioningUpdates ) # ---- regenerate project ----------------------------------------------------- if command -v xcodegen >/dev/null 2>&1; then echo "🧩 Generating $PROJECT ..." xcodegen generate elif [ ! -d "$PROJECT" ]; then echo "❌ $PROJECT missing and xcodegen not installed."; exit 1 fi # ---- versioning ------------------------------------------------------------- # CFBundleVersion is stamped during the build by Scripts/update_build_number.sh # (raw commit count). The marketing version lives in project.yml's # MARKETING_VERSION setting for the IceGlass target (Info.plist references it # via $(MARKETING_VERSION), so there's no literal to PlistBuddy-read). BUILD_NUMBER="$(git rev-list HEAD --count)" MARKETING_VERSION="$(grep -m1 'MARKETING_VERSION:' project.yml | sed -E 's/.*"([^"]+)".*/\1/')" echo "📦 Version $MARKETING_VERSION — build $BUILD_NUMBER" mkdir -p "$BUILD_DIR" ARCHIVE_PATH="$BUILD_DIR/$SCHEME.xcarchive" EXPORT_PATH="$BUILD_DIR/$SCHEME-export" rm -rf "$ARCHIVE_PATH" "$EXPORT_PATH" echo "" echo "🛠 Archiving $SCHEME (macOS) ..." xcodebuild archive \ -project "$PROJECT" \ -scheme "$SCHEME" \ -configuration Release \ -destination "generic/platform=macOS" \ -archivePath "$ARCHIVE_PATH" \ CODE_SIGN_STYLE=Automatic \ DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \ "${AUTH[@]}" echo "🚀 Exporting + uploading to App Store Connect ..." xcodebuild -exportArchive \ -archivePath "$ARCHIVE_PATH" \ -exportPath "$EXPORT_PATH" \ -exportOptionsPlist "$SCRIPT_DIR/ExportOptions-macOS.plist" \ "${AUTH[@]}" echo "✅ IceGlass uploaded (build $BUILD_NUMBER)." echo "" echo "🎉 Done. The build appears in App Store Connect > TestFlight after processing (~5–15 min)." echo "" echo "➡️ Push metadata, then stage/submit for review with the canonical scripts" echo " (apps sit as siblings of indie-skills under ~/Documents/indie; --bundle" echo " and --version are required flags — there are no per-app defaults):" echo "" echo " set -a; source .env.release; set +a; swift ../indie-skills/skills/appstore-publish/scripts/asc-metadata.swift --bundle dev.rzen.indie.IceGlass --version $MARKETING_VERSION --dry-run" echo " set -a; source .env.release; set +a; swift ../indie-skills/skills/appstore-publish/scripts/asc-metadata.swift --bundle dev.rzen.indie.IceGlass --version $MARKETING_VERSION" echo " set -a; source .env.release; set +a; swift ../indie-skills/skills/appstore-publish/scripts/asc-submit.swift --bundle dev.rzen.indie.IceGlass --version $MARKETING_VERSION # stage only" echo " set -a; source .env.release; set +a; swift ../indie-skills/skills/appstore-publish/scripts/asc-submit.swift --bundle dev.rzen.indie.IceGlass --version $MARKETING_VERSION --submit # stage + submit"