Tanvrit Compute

Release signing

How to sign and publish Tanvrit Compute release builds. The scaffolding is in place; the only thing missing is the actual keystore + provisioning profile + Apple Team ID, which are provisioned once per account.

Android (Google Play)

One-time setup

  1. Generate a release keystore (keep this file off the repo — store in
  2. 1Password / secrets manager / GitHub Actions encrypted secrets):

`` keytool -genkeypair -v \ -keystore tanvrit-compute-release.jks \ -keyalg RSA -keysize 4096 -validity 10950 \ -alias tanvrit-compute ``

10,950 days ≈ 30 years; Play Store will still accept it past 25 years.

  1. Upload the certificate fingerprint to Play Console → App integrity →
  2. App signing. Pick Play App Signing and upload this keystore as the upload key. Google manages the release signing key on their side from then on.

Per-release env vars

The build reads these at assembly time. Set them in the GitHub Actions workflow (encrypted secrets) or export them locally before building:

ANDROID_KEYSTORE_PATH=/secure/path/tanvrit-compute-release.jks
ANDROID_KEYSTORE_PASSWORD=…
ANDROID_KEY_ALIAS=tanvrit-compute
ANDROID_KEY_PASSWORD=…

Alternatively drop them into ~/.gradle/gradle.properties (NOT the repo's gradle.properties) under these keys:

android.keystore.path=…
android.keystore.password=…
android.key.alias=…
android.key.password=…

Build + upload

./gradlew :composeApp:bundleRelease
# Output: composeApp/build/outputs/bundle/release/composeApp-release.aab

# Upload via Play Console or the fastlane / upload-google-play action.

When no keystore is configured the release build falls back to the debug signer — useful for internal testing but rejected by Play Store.

iOS (App Store Connect / TestFlight)

One-time setup

  1. Join the Apple Developer Program
  2. (<https://developer.apple.com/programs/>).

  3. Find your 10-character Team ID at <https://developer.apple.com/account>
  4. (Membership → Team ID).

  5. Register the app in App Store Connect with bundle ID
  6. com.tanvrit.compute.portal (matches iosApp/iosApp/Info.plist).

  7. Configure automatic signing in Xcode: open
  8. iosApp/iosApp.xcworkspace, select the iosApp target → Signing & Capabilities → set Team to your org; Xcode will provision the certificate + profile automatically.

ExportOptions.plist

Replace APPLE_TEAM_ID in iosApp/ExportOptions.plist with the Team ID from step 2 above. Commit the change.

Entitlements

iosApp/iosApp.entitlements declares:

  • Keychain access group (for session token storage).
  • Associated domains (applinks:compute.tanvrit.com) for Universal
  • Links. To actually enable Universal Links, also host https://compute.tanvrit.com/.well-known/apple-app-site-association with your app's appID — see Apple's docs for the format. (Not hosted yet; add when needed.)

Build + upload

# 1. Archive the Release configuration
xcodebuild -workspace iosApp/iosApp.xcworkspace \
    -scheme iosApp -configuration Release \
    -archivePath build/ComputePortal.xcarchive archive

# 2. Export a signed .ipa using the options plist above
xcodebuild -exportArchive \
    -archivePath build/ComputePortal.xcarchive \
    -exportOptionsPlist iosApp/ExportOptions.plist \
    -exportPath build/ipa

# 3. Upload to App Store Connect
xcrun altool --upload-app --type ios -f build/ipa/iosApp.ipa \
    --apiKey $APP_STORE_CONNECT_API_KEY_ID \
    --apiIssuer $APP_STORE_CONNECT_ISSUER_ID

App Store Connect API keys are provisioned at <https://appstoreconnect.apple.com/access/api>. They replace the older username + app-specific-password flow and don't expire.

Desktop (no signing needed today)

The Compose Desktop distribution ships unsigned DMG / MSI / DEB to GitHub Releases. Users on macOS see the standard Gatekeeper warning until we enroll in the Apple Developer program and sign via codesign + notarize with xcrun notarytool. That's a follow-up.