18 Building
Emily edited this page 2026-11-11 10:36:59 +01:00

Building

Requirements

Target Requirements
All Flutter 3.47+ / Dart 3.13+
Android JDK 17, Android SDK 36, release keystore
iOS / macOS macOS with Xcode 27+
Windows Windows with Visual Studio 2022 and the Desktop C++ workload
Linux GTK 3 development packages
Web Flutter web support; any static host

The project was developed and released with Flutter 3.47.9 / Dart 3.13.7.

Get the source

git clone https://git.emilyh.de/Emily/UniversalGamingApp.git
cd UniversalGamingApp
flutter pub get

Run

flutter run -d macos
flutter run -d chrome
flutter run -d android

For an Android emulator, the host machine is reachable at http://10.0.2.2:6767. For the iOS simulator, use http://127.0.0.1:6767 for a local backend.

Build commands

# Android APK (universal, installable)
flutter build apk --release

# Android app bundle for Google Play
flutter build appbundle --release

# iOS IPA (requires macOS, Xcode and an Apple signing identity)
flutter build ipa --release

# macOS app
flutter build macos --release

# Windows (run on Windows)
flutter build windows --release

# Linux (run on Linux), then package the single-file AppImage
tools/package_appimage.sh
flutter build linux --release

# Web static build
flutter build web --release

The web output is build/web/. The Android outputs are:

  • build/app/outputs/flutter-apk/app-release.apk
  • build/app/outputs/bundle/release/app-release.aab

Versioning

The app version lives in pubspec.yaml:

version: 2.12.2+35

2.12.2 is the display version; 32 is the build number. A release also updates:

  • lib/config/app_config.dart fallback version.
  • web/latest.json update metadata.
  • windows/runner/Runner.rc version fields.
  • deploy/docker-compose.yml, deploy/.env.example and deploy/publish-images.sh.
  • README.md, INSTALL.md and WEB_HOSTING.md version references.

Android signing

Release signing is read from android/key.properties, which is ignored by Git:

storeFile=/absolute/path/to/release.jks
storePassword=...
keyAlias=...
keyPassword=...

If the file is absent, the project falls back to debug signing so local release builds still work. Never commit the keystore, key.properties or passwords.

For release builds:

export JAVA_HOME="$HOME/jdk-17/Contents/Home"
export ANDROID_HOME="$HOME/android-sdk"
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/36.0.0:$PATH"
flutter build apk --release

Verify the APK:

aapt dump badging build/app/outputs/flutter-apk/app-release.apk | head -1
apksigner verify --print-certs build/app/outputs/flutter-apk/app-release.apk

iOS

An unsigned IPA can be produced without an Apple signing identity:

flutter build ios --release --no-codesign

Package build/ios/iphoneos/Runner.app into a Payload/ directory and zip it as an .ipa. The release artifact is unsigned and must be re-signed by the user.

For Universal Links, password-manager credentials and App Store distribution, build with a real Apple Developer identity and the correct associated-domain entitlements.

macOS

flutter build macos --release

The app is ad-hoc signed for local distribution. If you re-sign it manually:

codesign --force --deep --sign - \
  "build/macos/Build/Products/Release/Universal Gaming.app"

Create a DMG with the app and an /Applications symlink.

macOS builds disable the App Sandbox so Discord Rich Presence can reach the local IPC socket. The build is not intended for the Mac App Store.

Discord Rich Presence

Desktop builds accept a Discord Application ID at compile time:

flutter build macos --release \
  --dart-define=DISCORD_CLIENT_ID=123456789012345678

Without the flag the app compiles normally and the Discord setting explains that the build is not configured. See Features.

Self-hosted account server

Bake in a backend URL:

flutter build apk --release \
  --dart-define=UNIVERSAL_GAMING_API_URL=https://accounts.example.com

Or leave it unset and configure the server at runtime from the Account screen.

Web with Docker

deploy/Dockerfile builds the Flutter web app and serves it with Nginx on port 6969:

docker build -f deploy/Dockerfile -t universal-gaming-web:local .
docker run --rm -p 6969:6969 universal-gaming-web:local

The build stage is pinned to Flutter 3.47.9 and linux/amd64 for reproducible builds on Apple Silicon. The Dockerfile verifies the Flutter archive SHA-256 before extracting it.

Release checklist

  1. Run flutter analyze.
  2. Run flutter test --concurrency=1.
  3. Bump the version in every file listed under Versioning.
  4. Build all available artifacts.
  5. Generate SHA256SUMS.txt.
  6. Create a Gitea release and upload the artifacts.
  7. Deploy the web build.
  8. Verify the live version.json, latest.json and /healthz (backend).