Release 1.0.0 !51
6 files changed, +95 −15
Layout: unified · split
App/README.org +14
| @@ -15,3 +15,17 @@ subsystem =sh.krz.moonrise=. | ||
| 15 | 15 | Backend: both configurations use https://moonrise-server.audit-labs.workers.dev |
| 16 | 16 | (=MOONRISE_API_URL= in =project.yml=). For a local Worker, set it to |
| 17 | 17 | =http://localhost:8787= and regenerate. |
| 18 | ||
| 19 | * Release | |
| 20 | ||
| 21 | #+begin_src sh | |
| 22 | scripts/release-ios.sh | |
| 23 | #+end_src | |
| 24 | ||
| 25 | Run from a clean =main=. It regenerates the project, archives the iPhone | |
| 26 | app with its widgets and the Watch app, and uploads it to App Store | |
| 27 | Connect, signed through the Apple ID in Xcode. The version is | |
| 28 | =MARKETING_VERSION= in =project.yml=; the build number is | |
| 29 | =git rev-list --count HEAD=, so each build maps to a commit. | |
| 30 | =MOONRISE_PUBLISH=0= exports the =.ipa= to =.build/ios-release= without | |
| 31 | uploading. The visionOS app is a separate product and is not uploaded. | |
App/Sources/InAppBrowser.swift −1
| @@ -9,7 +9,6 @@ enum InAppBrowser { | ||
| 9 | 9 | static let action = OpenURLAction { url in |
| 10 | 10 | guard url.scheme == "https" || url.scheme == "http", let top = topViewController() else { return .systemAction } |
| 11 | 11 | let safari = SFSafariViewController(url: url) |
| 12 | safari.preferredControlTintColor = UIColor(red: 0.88, green: 0.24, blue: 0.19, alpha: 1) | |
| 13 | 12 | safari.dismissButtonStyle = .done |
| 14 | 13 | top.present(safari, animated: true) |
| 15 | 14 | return .handled |
App/Watch/Widgets-Info.plist +2 −2
| @@ -17,9 +17,9 @@ | ||
| 17 | 17 | <key>CFBundlePackageType</key> |
| 18 | 18 | <string>XPC!</string> |
| 19 | 19 | <key>CFBundleShortVersionString</key> |
| 20 | <string>1.0</string> | |
| 20 | <string>$(MARKETING_VERSION)</string> | |
| 21 | 21 | <key>CFBundleVersion</key> |
| 22 | <string>1</string> | |
| 22 | <string>$(CURRENT_PROJECT_VERSION)</string> | |
| 23 | 23 | <key>NSExtension</key> |
| 24 | 24 | <dict> |
| 25 | 25 | <key>NSExtensionPointIdentifier</key> |
App/Widgets/Info.plist +2 −2
| @@ -17,9 +17,9 @@ | ||
| 17 | 17 | <key>CFBundlePackageType</key> |
| 18 | 18 | <string>XPC!</string> |
| 19 | 19 | <key>CFBundleShortVersionString</key> |
| 20 | <string>1.0</string> | |
| 20 | <string>$(MARKETING_VERSION)</string> | |
| 21 | 21 | <key>CFBundleVersion</key> |
| 22 | <string>1</string> | |
| 22 | <string>$(CURRENT_PROJECT_VERSION)</string> | |
| 23 | 23 | <key>NSExtension</key> |
| 24 | 24 | <dict> |
| 25 | 25 | <key>NSExtensionPointIdentifier</key> |
App/project.yml +14 −10
| @@ -54,8 +54,8 @@ targets: | ||
| 54 | 54 | CODE_SIGN_STYLE: Automatic |
| 55 | 55 | SWIFT_VERSION: "6.0" |
| 56 | 56 | TARGETED_DEVICE_FAMILY: "1,2" |
| 57 | MARKETING_VERSION: "1.0" | |
| 58 | CURRENT_PROJECT_VERSION: "1" | |
| 57 | MARKETING_VERSION: "1.0.0" | |
| 58 | CURRENT_PROJECT_VERSION: "52" | |
| 59 | 59 | GENERATE_INFOPLIST_FILE: YES |
| 60 | 60 | INFOPLIST_KEY_CFBundleDisplayName: Moonrise |
| 61 | 61 | INFOPLIST_KEY_NSSupportsLiveActivities: YES |
| @@ -83,6 +83,8 @@ targets: | ||
| 83 | 83 | path: Widgets/Info.plist |
| 84 | 84 | properties: |
| 85 | 85 | CFBundleDisplayName: Moonrise |
| 86 | CFBundleShortVersionString: $(MARKETING_VERSION) | |
| 87 | CFBundleVersion: $(CURRENT_PROJECT_VERSION) | |
| 86 | 88 | NSWidgetWantsLocation: true |
| 87 | 89 | NSExtension: |
| 88 | 90 | NSExtensionPointIdentifier: com.apple.widgetkit-extension |
| @@ -93,8 +95,8 @@ targets: | ||
| 93 | 95 | CODE_SIGN_STYLE: Automatic |
| 94 | 96 | SWIFT_VERSION: "6.0" |
| 95 | 97 | TARGETED_DEVICE_FAMILY: "1,2" |
| 96 | MARKETING_VERSION: "1.0" | |
| 97 | CURRENT_PROJECT_VERSION: "1" | |
| 98 | MARKETING_VERSION: "1.0.0" | |
| 99 | CURRENT_PROJECT_VERSION: "52" | |
| 98 | 100 | MoonriseWatch: |
| 99 | 101 | type: application |
| 100 | 102 | platform: watchOS |
| @@ -111,8 +113,8 @@ targets: | ||
| 111 | 113 | DEVELOPMENT_TEAM: ZCNAX3VL9D |
| 112 | 114 | CODE_SIGN_STYLE: Automatic |
| 113 | 115 | SWIFT_VERSION: "6.0" |
| 114 | MARKETING_VERSION: "1.0" | |
| 115 | CURRENT_PROJECT_VERSION: "1" | |
| 116 | MARKETING_VERSION: "1.0.0" | |
| 117 | CURRENT_PROJECT_VERSION: "52" | |
| 116 | 118 | GENERATE_INFOPLIST_FILE: YES |
| 117 | 119 | INFOPLIST_KEY_CFBundleDisplayName: Moonrise |
| 118 | 120 | INFOPLIST_KEY_WKCompanionAppBundleIdentifier: sh.krz.moonrise |
| @@ -135,6 +137,8 @@ targets: | ||
| 135 | 137 | path: Watch/Widgets-Info.plist |
| 136 | 138 | properties: |
| 137 | 139 | CFBundleDisplayName: Moonrise |
| 140 | CFBundleShortVersionString: $(MARKETING_VERSION) | |
| 141 | CFBundleVersion: $(CURRENT_PROJECT_VERSION) | |
| 138 | 142 | NSWidgetWantsLocation: true |
| 139 | 143 | NSExtension: |
| 140 | 144 | NSExtensionPointIdentifier: com.apple.widgetkit-extension |
| @@ -144,8 +148,8 @@ targets: | ||
| 144 | 148 | DEVELOPMENT_TEAM: ZCNAX3VL9D |
| 145 | 149 | CODE_SIGN_STYLE: Automatic |
| 146 | 150 | SWIFT_VERSION: "6.0" |
| 147 | MARKETING_VERSION: "1.0" | |
| 148 | CURRENT_PROJECT_VERSION: "1" | |
| 151 | MARKETING_VERSION: "1.0.0" | |
| 152 | CURRENT_PROJECT_VERSION: "52" | |
| 149 | 153 | MoonriseVision: |
| 150 | 154 | type: application |
| 151 | 155 | platform: visionOS |
| @@ -169,8 +173,8 @@ targets: | ||
| 169 | 173 | DEVELOPMENT_TEAM: ZCNAX3VL9D |
| 170 | 174 | CODE_SIGN_STYLE: Automatic |
| 171 | 175 | SWIFT_VERSION: "6.0" |
| 172 | MARKETING_VERSION: "1.0" | |
| 173 | CURRENT_PROJECT_VERSION: "1" | |
| 176 | MARKETING_VERSION: "1.0.0" | |
| 177 | CURRENT_PROJECT_VERSION: "52" | |
| 174 | 178 | GENERATE_INFOPLIST_FILE: YES |
| 175 | 179 | INFOPLIST_KEY_CFBundleDisplayName: Moonrise |
| 176 | 180 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation: YES |
scripts/release-ios.sh added +63
| @@ -0,0 +1,63 @@ | ||
| 1 | #!/bin/sh | |
| 2 | # Archives the iOS app (with its widgets and the watch app) and uploads it to App Store Connect, | |
| 3 | # signed automatically with the team's distribution certificate through the Apple ID signed in | |
| 4 | # to Xcode. The version is MARKETING_VERSION in App/project.yml; the build number is the commit | |
| 5 | # count on main, so every upload can be traced to a commit. The upload then shows in TestFlight | |
| 6 | # and can be picked for an App Store submission. | |
| 7 | # Usage: scripts/release-ios.sh | |
| 8 | # MOONRISE_PUBLISH 0 archives and exports the .ipa to .build/ios-release without uploading | |
| 9 | set -eu | |
| 10 | ||
| 11 | cd "$(dirname "$0")/.." | |
| 12 | publish="${MOONRISE_PUBLISH:-1}" | |
| 13 | team=ZCNAX3VL9D | |
| 14 | ||
| 15 | if [ "$publish" != 0 ]; then | |
| 16 | [ -z "$(git status --porcelain)" ] || { echo "The working tree has changes." >&2; exit 1; } | |
| 17 | [ "$(git branch --show-current)" = main ] || { echo "Release from main." >&2; exit 1; } | |
| 18 | fi | |
| 19 | ||
| 20 | version="$(sed -n 's/.*MARKETING_VERSION: "\(.*\)"/\1/p' App/project.yml | sort -u)" | |
| 21 | [ "$(printf '%s\n' "$version" | wc -l | tr -d ' ')" = 1 ] || { echo "The targets' MARKETING_VERSION differ: $version" >&2; exit 1; } | |
| 22 | build="$(git rev-list --count HEAD)" | |
| 23 | ||
| 24 | command -v xcodegen >/dev/null || { echo "Install XcodeGen: brew install xcodegen" >&2; exit 1; } | |
| 25 | (cd App && xcodegen generate --quiet) | |
| 26 | ||
| 27 | out=.build/ios-release | |
| 28 | rm -rf "${out:?}" | |
| 29 | mkdir -p "$out" | |
| 30 | archive="$out/moonrise.xcarchive" | |
| 31 | xcodebuild archive -project App/Moonrise.xcodeproj -scheme Moonrise -configuration Release \ | |
| 32 | -destination 'generic/platform=iOS' -archivePath "$archive" -allowProvisioningUpdates -quiet \ | |
| 33 | MARKETING_VERSION="$version" CURRENT_PROJECT_VERSION="$build" | |
| 34 | ||
| 35 | if [ "$publish" = 0 ]; then destination=export; else destination=upload; fi | |
| 36 | cat > "$out/ExportOptions.plist" <<PLIST | |
| 37 | <?xml version="1.0" encoding="UTF-8"?> | |
| 38 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 39 | <plist version="1.0"> | |
| 40 | <dict> | |
| 41 | <key>method</key> | |
| 42 | <string>app-store-connect</string> | |
| 43 | <key>destination</key> | |
| 44 | <string>$destination</string> | |
| 45 | <key>teamID</key> | |
| 46 | <string>$team</string> | |
| 47 | <key>signingStyle</key> | |
| 48 | <string>automatic</string> | |
| 49 | <key>manageAppVersionAndBuildNumber</key> | |
| 50 | <false/> | |
| 51 | <key>uploadSymbols</key> | |
| 52 | <true/> | |
| 53 | </dict> | |
| 54 | </plist> | |
| 55 | PLIST | |
| 56 | xcodebuild -exportArchive -archivePath "$archive" -exportOptionsPlist "$out/ExportOptions.plist" \ | |
| 57 | -exportPath "$out/export" -allowProvisioningUpdates -quiet | |
| 58 | ||
| 59 | if [ "$publish" = 0 ]; then | |
| 60 | echo "Exported $(ls "$out"/export/*.ipa): $version ($build), not uploaded" | |
| 61 | else | |
| 62 | echo "Uploaded Moonrise $version ($build) to App Store Connect; it shows in TestFlight once processed" | |
| 63 | fi | |